From 799c849570685334cdcb82279b694c96e7b2bf7f Mon Sep 17 00:00:00 2001 From: Mathis Kirchner Date: Fri, 9 Jan 2026 21:55:58 +0100 Subject: [PATCH] wrap every view that uses a snackbar in ScaffoldMessenger --- .../group_view/create_group_view.dart | 114 ++++---- .../create_match/create_match_view.dart | 254 +++++++++--------- .../views/main_menu/settings_view.dart | 196 +++++++------- 3 files changed, 285 insertions(+), 279 deletions(-) diff --git a/lib/presentation/views/main_menu/group_view/create_group_view.dart b/lib/presentation/views/main_menu/group_view/create_group_view.dart index f92df0f..8192c6b 100644 --- a/lib/presentation/views/main_menu/group_view/create_group_view.dart +++ b/lib/presentation/views/main_menu/group_view/create_group_view.dart @@ -44,66 +44,68 @@ class _CreateGroupViewState extends State { @override Widget build(BuildContext context) { final loc = AppLocalizations.of(context); - return Scaffold( - backgroundColor: CustomTheme.backgroundColor, - appBar: AppBar(title: Text(loc.create_new_group)), - body: SafeArea( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - margin: CustomTheme.standardMargin, - child: TextInputField( - controller: _groupNameController, - hintText: loc.group_name, + return ScaffoldMessenger( + child: Scaffold( + backgroundColor: CustomTheme.backgroundColor, + appBar: AppBar(title: Text(loc.create_new_group)), + body: SafeArea( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + margin: CustomTheme.standardMargin, + child: TextInputField( + controller: _groupNameController, + hintText: loc.group_name, + ), ), - ), - Expanded( - child: PlayerSelection( - onChanged: (value) { - setState(() { - selectedPlayers = [...value]; - }); - }, + Expanded( + child: PlayerSelection( + onChanged: (value) { + setState(() { + selectedPlayers = [...value]; + }); + }, + ), ), - ), - CustomWidthButton( - text: loc.create_group, - sizeRelativeToWidth: 0.95, - buttonType: ButtonType.primary, - onPressed: - (_groupNameController.text.isEmpty || - (selectedPlayers.length < 2)) - ? null - : () async { - bool success = await db.groupDao.addGroup( - group: Group( - name: _groupNameController.text.trim(), - members: selectedPlayers, - ), - ); - if (!context.mounted) return; - if (success) { - Navigator.pop(context); - } else { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - backgroundColor: CustomTheme.boxColor, - content: Center( - child: Text( - AppLocalizations.of( - context, - ).error_creating_group, - style: const TextStyle(color: Colors.white), - ), - ), + CustomWidthButton( + text: loc.create_group, + sizeRelativeToWidth: 0.95, + buttonType: ButtonType.primary, + onPressed: + (_groupNameController.text.isEmpty || + (selectedPlayers.length < 2)) + ? null + : () async { + bool success = await db.groupDao.addGroup( + group: Group( + name: _groupNameController.text.trim(), + members: selectedPlayers, ), ); - } - }, - ), - const SizedBox(height: 20), - ], + if (!context.mounted) return; + if (success) { + Navigator.pop(context); + } else { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + backgroundColor: CustomTheme.boxColor, + content: Center( + child: Text( + AppLocalizations.of( + context, + ).error_creating_group, + style: const TextStyle(color: Colors.white), + ), + ), + ), + ); + } + }, + ), + const SizedBox(height: 20), + ], + ), ), ), ); diff --git a/lib/presentation/views/main_menu/match_view/create_match/create_match_view.dart b/lib/presentation/views/main_menu/match_view/create_match/create_match_view.dart index dc6690b..518fd24 100644 --- a/lib/presentation/views/main_menu/match_view/create_match/create_match_view.dart +++ b/lib/presentation/views/main_menu/match_view/create_match/create_match_view.dart @@ -119,140 +119,142 @@ class _CreateMatchViewState extends State { @override Widget build(BuildContext context) { final loc = AppLocalizations.of(context); - return Scaffold( - backgroundColor: CustomTheme.backgroundColor, - appBar: AppBar(title: Text(loc.create_new_match)), - body: SafeArea( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - margin: CustomTheme.tileMargin, - child: TextInputField( - controller: _matchNameController, - hintText: hintText ?? '', + return ScaffoldMessenger( + child: Scaffold( + backgroundColor: CustomTheme.backgroundColor, + appBar: AppBar(title: Text(loc.create_new_match)), + body: SafeArea( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + margin: CustomTheme.tileMargin, + child: TextInputField( + controller: _matchNameController, + hintText: hintText ?? '', + ), ), - ), - ChooseTile( - title: loc.game, - trailingText: selectedGameIndex == -1 - ? loc.none - : games[selectedGameIndex].$1, - onPressed: () async { - selectedGameIndex = await Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => ChooseGameView( - games: games, - initialGameIndex: selectedGameIndex, + ChooseTile( + title: loc.game, + trailingText: selectedGameIndex == -1 + ? loc.none + : games[selectedGameIndex].$1, + onPressed: () async { + selectedGameIndex = await Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => ChooseGameView( + games: games, + initialGameIndex: selectedGameIndex, + ), ), - ), - ); - setState(() { - if (selectedGameIndex != -1) { - hintText = games[selectedGameIndex].$1; - selectedRuleset = games[selectedGameIndex].$3; - selectedRulesetIndex = _rulesets.indexWhere( - (r) => r.$1 == selectedRuleset, - ); - } else { - hintText = loc.match_name; - selectedRuleset = null; - } - }); - }, - ), - ChooseTile( - title: loc.ruleset, - trailingText: selectedRuleset == null - ? loc.none - : translateRulesetToString(selectedRuleset!, context), - onPressed: () async { - selectedRuleset = await Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => ChooseRulesetView( - rulesets: _rulesets, - initialRulesetIndex: selectedRulesetIndex, - ), - ), - ); - if (!mounted) return; - selectedRulesetIndex = _rulesets.indexWhere( - (r) => r.$1 == selectedRuleset, - ); - selectedGameIndex = -1; - setState(() {}); - }, - ), - ChooseTile( - title: loc.group, - trailingText: selectedGroup == null - ? loc.none_group - : selectedGroup!.name, - onPressed: () async { - selectedGroup = await Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => ChooseGroupView( - groups: groupsList, - initialGroupId: selectedGroupId, - ), - ), - ); - selectedGroupId = selectedGroup?.id ?? ''; - if (selectedGroup != null) { - filteredPlayerList = playerList - .where( - (p) => !selectedGroup!.members.any((m) => m.id == p.id), - ) - .toList(); - } else { - filteredPlayerList = List.from(playerList); - } - setState(() {}); - }, - ), - Expanded( - child: PlayerSelection( - key: ValueKey(selectedGroup?.id ?? 'no_group'), - initialSelectedPlayers: selectedPlayers ?? [], - availablePlayers: filteredPlayerList, - onChanged: (value) { + ); setState(() { - selectedPlayers = value; + if (selectedGameIndex != -1) { + hintText = games[selectedGameIndex].$1; + selectedRuleset = games[selectedGameIndex].$3; + selectedRulesetIndex = _rulesets.indexWhere( + (r) => r.$1 == selectedRuleset, + ); + } else { + hintText = loc.match_name; + selectedRuleset = null; + } }); }, ), - ), - CustomWidthButton( - text: loc.create_match, - sizeRelativeToWidth: 0.95, - buttonType: ButtonType.primary, - onPressed: _enableCreateGameButton() - ? () async { - Match match = Match( - name: _matchNameController.text.isEmpty - ? (hintText ?? '') - : _matchNameController.text.trim(), - createdAt: DateTime.now(), - group: selectedGroup, - players: selectedPlayers, - ); - await db.matchDao.addMatch(match: match); - if (context.mounted) { - Navigator.pushReplacement( - context, - CupertinoPageRoute( - fullscreenDialog: true, - builder: (context) => MatchResultView( - match: match, - onWinnerChanged: widget.onWinnerChanged, - ), - ), + ChooseTile( + title: loc.ruleset, + trailingText: selectedRuleset == null + ? loc.none + : translateRulesetToString(selectedRuleset!, context), + onPressed: () async { + selectedRuleset = await Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => ChooseRulesetView( + rulesets: _rulesets, + initialRulesetIndex: selectedRulesetIndex, + ), + ), + ); + if (!mounted) return; + selectedRulesetIndex = _rulesets.indexWhere( + (r) => r.$1 == selectedRuleset, + ); + selectedGameIndex = -1; + setState(() {}); + }, + ), + ChooseTile( + title: loc.group, + trailingText: selectedGroup == null + ? loc.none_group + : selectedGroup!.name, + onPressed: () async { + selectedGroup = await Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => ChooseGroupView( + groups: groupsList, + initialGroupId: selectedGroupId, + ), + ), + ); + selectedGroupId = selectedGroup?.id ?? ''; + if (selectedGroup != null) { + filteredPlayerList = playerList + .where( + (p) => !selectedGroup!.members.any((m) => m.id == p.id), + ) + .toList(); + } else { + filteredPlayerList = List.from(playerList); + } + setState(() {}); + }, + ), + Expanded( + child: PlayerSelection( + key: ValueKey(selectedGroup?.id ?? 'no_group'), + initialSelectedPlayers: selectedPlayers ?? [], + availablePlayers: filteredPlayerList, + onChanged: (value) { + setState(() { + selectedPlayers = value; + }); + }, + ), + ), + CustomWidthButton( + text: loc.create_match, + sizeRelativeToWidth: 0.95, + buttonType: ButtonType.primary, + onPressed: _enableCreateGameButton() + ? () async { + Match match = Match( + name: _matchNameController.text.isEmpty + ? (hintText ?? '') + : _matchNameController.text.trim(), + createdAt: DateTime.now(), + group: selectedGroup, + players: selectedPlayers, ); + await db.matchDao.addMatch(match: match); + if (context.mounted) { + Navigator.pushReplacement( + context, + CupertinoPageRoute( + fullscreenDialog: true, + builder: (context) => MatchResultView( + match: match, + onWinnerChanged: widget.onWinnerChanged, + ), + ), + ); + } } - } - : null, - ), - ], + : null, + ), + ], + ), ), ), ); diff --git a/lib/presentation/views/main_menu/settings_view.dart b/lib/presentation/views/main_menu/settings_view.dart index 374c463..c5fcfa2 100644 --- a/lib/presentation/views/main_menu/settings_view.dart +++ b/lib/presentation/views/main_menu/settings_view.dart @@ -21,105 +21,107 @@ class _SettingsViewState extends State { @override Widget build(BuildContext context) { final loc = AppLocalizations.of(context); - return Scaffold( - appBar: AppBar(backgroundColor: CustomTheme.backgroundColor), - backgroundColor: CustomTheme.backgroundColor, - body: LayoutBuilder( - builder: (BuildContext context, BoxConstraints constraints) => - SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.fromLTRB(24, 0, 24, 10), - child: Text( - textAlign: TextAlign.start, - loc.menu, - style: const TextStyle( - fontSize: 28, - fontWeight: FontWeight.bold, - ), - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 24, - vertical: 10, - ), - child: Text( - textAlign: TextAlign.start, - loc.settings, - style: const TextStyle( - fontSize: 22, - fontWeight: FontWeight.bold, - ), - ), - ), - SettingsListTile( - title: loc.export_data, - icon: Icons.upload_rounded, - suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16), - onPressed: () async { - final String json = - await DataTransferService.getAppDataAsJson(context); - final result = await DataTransferService.exportData( - json, - 'game_tracker-data', - ); - if (!context.mounted) return; - showExportSnackBar(context: context, result: result); - }, - ), - SettingsListTile( - title: loc.import_data, - icon: Icons.download_rounded, - suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16), - onPressed: () async { - final result = await DataTransferService.importData( - context, - ); - if (!context.mounted) return; - showImportSnackBar(context: context, result: result); - }, - ), - SettingsListTile( - title: loc.delete_all_data, - icon: Icons.delete_rounded, - suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16), - onPressed: () { - showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text(loc.delete_all_data), - content: Text(loc.this_cannot_be_undone), - actions: [ - TextButton( - onPressed: () => Navigator.of(context).pop(false), - child: Text(loc.cancel), - ), - TextButton( - onPressed: () => Navigator.of(context).pop(true), - child: Text(loc.delete), - ), - ], + return ScaffoldMessenger( + child: Scaffold( + appBar: AppBar(backgroundColor: CustomTheme.backgroundColor), + backgroundColor: CustomTheme.backgroundColor, + body: LayoutBuilder( + builder: (BuildContext context, BoxConstraints constraints) => + SingleChildScrollView( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(24, 0, 24, 10), + child: Text( + textAlign: TextAlign.start, + loc.menu, + style: const TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, ), - ).then((confirmed) { - if (confirmed == true && context.mounted) { - DataTransferService.deleteAllData(context); - showSnackbar( - context: context, - message: AppLocalizations.of( - context, - ).data_successfully_deleted, - ); - } - }); - }, - ), - ], + ), + ), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 24, + vertical: 10, + ), + child: Text( + textAlign: TextAlign.start, + loc.settings, + style: const TextStyle( + fontSize: 22, + fontWeight: FontWeight.bold, + ), + ), + ), + SettingsListTile( + title: loc.export_data, + icon: Icons.upload_rounded, + suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16), + onPressed: () async { + final String json = + await DataTransferService.getAppDataAsJson(context); + final result = await DataTransferService.exportData( + json, + 'game_tracker-data', + ); + if (!context.mounted) return; + showExportSnackBar(context: context, result: result); + }, + ), + SettingsListTile( + title: loc.import_data, + icon: Icons.download_rounded, + suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16), + onPressed: () async { + final result = await DataTransferService.importData( + context, + ); + if (!context.mounted) return; + showImportSnackBar(context: context, result: result); + }, + ), + SettingsListTile( + title: loc.delete_all_data, + icon: Icons.delete_rounded, + suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16), + onPressed: () { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text(loc.delete_all_data), + content: Text(loc.this_cannot_be_undone), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(false), + child: Text(loc.cancel), + ), + TextButton( + onPressed: () => Navigator.of(context).pop(true), + child: Text(loc.delete), + ), + ], + ), + ).then((confirmed) { + if (confirmed == true && context.mounted) { + DataTransferService.deleteAllData(context); + showSnackbar( + context: context, + message: AppLocalizations.of( + context, + ).data_successfully_deleted, + ); + } + }); + }, + ), + ], + ), ), - ), + ), ), ); }