diff --git a/lib/src/core/utils/error_handler.dart b/lib/src/core/utils/error_handler.dart index edd6e59..8e35243 100644 --- a/lib/src/core/utils/error_handler.dart +++ b/lib/src/core/utils/error_handler.dart @@ -42,6 +42,7 @@ class ErrorHandler { } static void showErrorSnackBar(BuildContext context, Object error) { + if (!context.mounted) return; final scaffoldMessenger = ScaffoldMessenger.of(context); scaffoldMessenger.hideCurrentSnackBar(); diff --git a/lib/src/features/authentication/presentation/screens/profile_screen.dart b/lib/src/features/authentication/presentation/screens/profile_screen.dart index e872545..627b381 100644 --- a/lib/src/features/authentication/presentation/screens/profile_screen.dart +++ b/lib/src/features/authentication/presentation/screens/profile_screen.dart @@ -286,19 +286,19 @@ class _ProfileScreenState extends ConsumerState { final l10n = AppLocalizations.of(context)!; showDialog( context: context, - builder: (context) => AlertDialog( + builder: (dialogContext) => AlertDialog( title: Text(title, style: const TextStyle(color: AppTheme.errorColor)), content: Text(content), actions: [ TextButton( - onPressed: () => Navigator.pop(context), + onPressed: () => Navigator.pop(dialogContext), child: Text(l10n.commonCancel), ), ElevatedButton( style: ElevatedButton.styleFrom(backgroundColor: AppTheme.errorColor), onPressed: () { - Navigator.pop(context); + Navigator.pop(dialogContext); onConfirm(); }, child: Text(l10n.commonConfirm), diff --git a/lib/src/features/dashboard/presentation/screens/hub_screen.dart b/lib/src/features/dashboard/presentation/screens/hub_screen.dart index 75c678d..6407cf7 100644 --- a/lib/src/features/dashboard/presentation/screens/hub_screen.dart +++ b/lib/src/features/dashboard/presentation/screens/hub_screen.dart @@ -253,13 +253,13 @@ class _HubScreenState extends ConsumerState { showDialog( context: context, - builder: (context) => AlertDialog( + builder: (dialogContext) => AlertDialog( title: Text(l10n.multiplayerTitle), content: Text(l10n.multiplayerDescription), actions: [ TextButton( onPressed: () { - Navigator.pop(context); + Navigator.pop(dialogContext); _showJoinCodeDialog(); }, child: Text(l10n.multiplayerJoinButton), @@ -268,14 +268,14 @@ class _HubScreenState extends ConsumerState { style: ElevatedButton.styleFrom( backgroundColor: AppTheme.primaryColor), onPressed: () async { - Navigator.pop(context); + Navigator.pop(dialogContext); try { final party = await ref.read(partyRepositoryProvider).createParty(); if (mounted) context.go('/lobby/${party.id}'); } catch (e) { if (mounted) { - if (mounted) ErrorHandler.showErrorSnackBar(context, e); + ErrorHandler.showErrorSnackBar(context, e); } } }, @@ -293,7 +293,7 @@ class _HubScreenState extends ConsumerState { final controller = TextEditingController(); showDialog( context: context, - builder: (context) => AlertDialog( + builder: (dialogContext) => AlertDialog( title: Text(l10n.multiplayerEnterCodeTitle), content: TextField( controller: controller, @@ -305,21 +305,21 @@ class _HubScreenState extends ConsumerState { ), actions: [ TextButton( - onPressed: () => Navigator.pop(context), + onPressed: () => Navigator.pop(dialogContext), child: Text(l10n.multiplayerCancelAction), ), ElevatedButton( onPressed: () async { final code = controller.text.trim().toUpperCase(); if (code.isNotEmpty) { - Navigator.pop(context); + Navigator.pop(dialogContext); try { final party = await ref.read(partyRepositoryProvider).joinParty(code); if (mounted) context.go('/lobby/${party.id}'); } catch (e) { if (mounted) { - if (mounted) ErrorHandler.showErrorSnackBar(context, e); + ErrorHandler.showErrorSnackBar(context, e); } } } diff --git a/lib/src/features/multiplayer/data/repositories/party_repository.dart b/lib/src/features/multiplayer/data/repositories/party_repository.dart index 9e8f95d..af37fb3 100644 --- a/lib/src/features/multiplayer/data/repositories/party_repository.dart +++ b/lib/src/features/multiplayer/data/repositories/party_repository.dart @@ -83,7 +83,11 @@ class PartyRepository { }); }, onCancel: () async { - await unsubscribe?.call(); + try { + await unsubscribe?.call(); + } catch (e) { + log('Safe ignore: Unsubscribe error (likely already disconnected): $e'); + } log('🔌 Unsubscribed from party $partyId'); }, ); @@ -120,7 +124,11 @@ class PartyRepository { }); }, onCancel: () async { - await unsubscribe?.call(); + try { + await unsubscribe?.call(); + } catch (e) { + log('Safe ignore: Unsubscribe error (likely already disconnected): $e'); + } log('🔌 Unsubscribed from party members $partyId'); }, ); diff --git a/lib/src/features/workout_runner/presentation/screens/battle_screen.dart b/lib/src/features/workout_runner/presentation/screens/battle_screen.dart index 2cd2f95..3a310d4 100644 --- a/lib/src/features/workout_runner/presentation/screens/battle_screen.dart +++ b/lib/src/features/workout_runner/presentation/screens/battle_screen.dart @@ -141,11 +141,11 @@ class _BattleScreenState extends ConsumerState { final controller = ref.read(battleControllerProvider.notifier); final battleState = ref.read(battleControllerProvider); - + if (battleState.isResting) { controller.tickRest(); final newState = ref.read(battleControllerProvider); - + if (newState.isResting) { _runRestTimer(); } else { @@ -254,7 +254,7 @@ class _BattleScreenState extends ConsumerState { showDialog( context: context, barrierDismissible: false, - builder: (context) => AlertDialog( + builder: (dialogContext) => AlertDialog( title: Text(l10n.battleRaidComplete), content: Column( mainAxisSize: MainAxisSize.min, @@ -267,7 +267,7 @@ class _BattleScreenState extends ConsumerState { const SizedBox(height: 16), Text( '+$xpEarned XP', - style: Theme.of(context).textTheme.headlineMedium?.copyWith( + style: Theme.of(dialogContext).textTheme.headlineMedium?.copyWith( color: AppTheme.primaryColor, ), ), @@ -276,7 +276,7 @@ class _BattleScreenState extends ConsumerState { actions: [ ElevatedButton( onPressed: () { - Navigator.of(context).pop(); + Navigator.of(dialogContext).pop(); context.go('/hub'); }, child: Text(l10n.battleBackToHub), @@ -1079,7 +1079,8 @@ class _BattleScreenState extends ConsumerState { children: [ _InfoBox( label: l10n.battleWeight, - value: '${currentSet.targetWeightTotal} kg', + value: + '${currentSet.targetWeightTotal} ${l10n.unitKg}', ), _InfoBox( label: l10n.battleReps,