From 38e43f54d884d1c1dd227034aaaea9c0281b8e21 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Thu, 3 Jul 2025 11:52:40 +0200 Subject: [PATCH 01/17] Added uuid to gameSession class & json scheme --- assets/schema.json | 3 +++ lib/data/game_session.dart | 11 +++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/assets/schema.json b/assets/schema.json index 17d7faa..a9a07e5 100644 --- a/assets/schema.json +++ b/assets/schema.json @@ -5,6 +5,9 @@ "items": { "type": "object", "properties": { + "id": { + "type": "string" + }, "createdAt": { "type": "string" }, diff --git a/lib/data/game_session.dart b/lib/data/game_session.dart index a741ae8..ada34dc 100644 --- a/lib/data/game_session.dart +++ b/lib/data/game_session.dart @@ -1,5 +1,6 @@ import 'package:cabo_counter/data/round.dart'; import 'package:flutter/cupertino.dart'; +import 'package:uuid/uuid.dart'; /// This class represents a game session for Cabo game. /// [createdAt] is the timestamp of when the game session was created. @@ -12,6 +13,7 @@ import 'package:flutter/cupertino.dart'; /// [isGameFinished] is a boolean indicating if the game has ended yet. /// [winner] is the name of the player who won the game. class GameSession extends ChangeNotifier { + late String id; final DateTime createdAt; final String gameTitle; final List players; @@ -33,17 +35,21 @@ class GameSession extends ChangeNotifier { required this.isPointsLimitEnabled, }) { playerScores = List.filled(players.length, 0); + var uuid = const Uuid(); + id = uuid.v1(); + print('GameSession created with ID: $id'); } @override toString() { - return ('GameSession: [createdAt: $createdAt, gameTitle: $gameTitle, ' + return ('GameSession: [id: $id, createdAt: $createdAt, gameTitle: $gameTitle, ' 'isPointsLimitEnabled: $isPointsLimitEnabled, pointLimit: $pointLimit, caboPenalty: $caboPenalty,' ' players: $players, playerScores: $playerScores, roundList: $roundList, winner: $winner]'); } /// Converts the GameSession object to a JSON map. Map toJson() => { + 'id': id, 'createdAt': createdAt.toIso8601String(), 'gameTitle': gameTitle, 'players': players, @@ -59,7 +65,8 @@ class GameSession extends ChangeNotifier { /// Creates a GameSession object from a JSON map. GameSession.fromJson(Map json) - : createdAt = DateTime.parse(json['createdAt']), + : id = json['id'] ?? const Uuid().v1(), + createdAt = DateTime.parse(json['createdAt']), gameTitle = json['gameTitle'], players = List.from(json['players']), pointLimit = json['pointLimit'], From 9eb3cac0981d9253d2dbceeda201996138a7d72e Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Thu, 3 Jul 2025 11:52:50 +0200 Subject: [PATCH 02/17] Addewd temp print --- lib/services/local_storage_service.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/services/local_storage_service.dart b/lib/services/local_storage_service.dart index 6039a7b..71dd332 100644 --- a/lib/services/local_storage_service.dart +++ b/lib/services/local_storage_service.dart @@ -86,6 +86,11 @@ class LocalStorageService { GameSession.fromJson(jsonItem as Map)) .toList(); + for (GameSession session in gameManager.gameList) { + print( + '[local_storage_service.dart] Geladene Session: ${session.gameTitle} - ${session.id}'); + } + print( '[local_storage_service.dart] Die Spieldaten wurden erfolgreich geladen und verarbeitet'); return true; From a756c493970d62c1563c50c9cd31c2657894b34f Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Thu, 3 Jul 2025 11:53:30 +0200 Subject: [PATCH 03/17] Added function getGameSessionIndexById() and renamed removeGameSessionByIndex() --- lib/data/game_manager.dart | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/data/game_manager.dart b/lib/data/game_manager.dart index 94b6287..f00d73c 100644 --- a/lib/data/game_manager.dart +++ b/lib/data/game_manager.dart @@ -30,12 +30,19 @@ class GameManager extends ChangeNotifier { /// Takes a [index] as input. It then removes the session at the specified index from the `gameList`, /// sorts the list in descending order based on the creation date, and notifies listeners of the change. /// It also saves the updated game sessions to local storage. - void removeGameSession(int index) { + void removeGameSessionByIndex(int index) { gameList[index].removeListener(notifyListeners); gameList.removeAt(index); notifyListeners(); LocalStorageService.saveGameSessions(); } + + /// Removes a game session by its ID. + /// Takes a String [id] as input. It finds the index of the game session with the matching ID + /// in the `gameList`, and then calls `removeGameSessionByIndex` with that index. + int getGameSessionIndexById(String id) { + return gameList.indexWhere((session) => session.id.toString() == id); + } } final gameManager = GameManager(); From f7842404113dc1d535acd343777550512834e765 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Thu, 3 Jul 2025 11:53:46 +0200 Subject: [PATCH 04/17] Refactoring --- lib/views/main_menu_view.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/views/main_menu_view.dart b/lib/views/main_menu_view.dart index f41a0ef..6597a68 100644 --- a/lib/views/main_menu_view.dart +++ b/lib/views/main_menu_view.dart @@ -131,7 +131,8 @@ class _MainMenuViewState extends State { gameTitle); }, onDismissed: (direction) { - gameManager.removeGameSession(index); + gameManager + .removeGameSessionByIndex(index); }, dismissThresholds: const { DismissDirection.startToEnd: 0.6 From f9fac719b0da671ffeefb3b6a24a10d20aad4be9 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Thu, 3 Jul 2025 11:58:25 +0200 Subject: [PATCH 05/17] Changed function and altered return type --- lib/data/game_manager.dart | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/data/game_manager.dart b/lib/data/game_manager.dart index f00d73c..f29270c 100644 --- a/lib/data/game_manager.dart +++ b/lib/data/game_manager.dart @@ -40,8 +40,12 @@ class GameManager extends ChangeNotifier { /// Removes a game session by its ID. /// Takes a String [id] as input. It finds the index of the game session with the matching ID /// in the `gameList`, and then calls `removeGameSessionByIndex` with that index. - int getGameSessionIndexById(String id) { - return gameList.indexWhere((session) => session.id.toString() == id); + bool removeGameSessionById(String id) { + final int index = + gameList.indexWhere((session) => session.id.toString() == id); + if (index == -1) return false; + removeGameSessionByIndex(index); + return true; } } From 2c1d65c4034761f8710d38d23c99dd5179790064 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Thu, 3 Jul 2025 13:05:28 +0200 Subject: [PATCH 06/17] Changed state handling --- lib/views/main_menu_view.dart | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/views/main_menu_view.dart b/lib/views/main_menu_view.dart index 6597a68..3a9441f 100644 --- a/lib/views/main_menu_view.dart +++ b/lib/views/main_menu_view.dart @@ -169,18 +169,19 @@ class _MainMenuViewState extends State { CupertinoIcons.person_2_fill), ], ), - onTap: () async { - //ignore: unused_local_variable - final val = await Navigator.push( + onTap: () { + final session = + gameManager.gameList[index]; + Navigator.push( context, CupertinoPageRoute( builder: (context) => ActiveGameView( - gameSession: gameManager - .gameList[index]), + gameSession: session), ), - ); - setState(() {}); + ).then((_) { + setState(() {}); + }); }, ), ), From d34c6fff53c480bd5f402804a6083d9271fd155a Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Thu, 3 Jul 2025 13:06:12 +0200 Subject: [PATCH 07/17] Added function gameExistsInGameList --- lib/data/game_manager.dart | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/data/game_manager.dart b/lib/data/game_manager.dart index f29270c..1ccc9dc 100644 --- a/lib/data/game_manager.dart +++ b/lib/data/game_manager.dart @@ -15,14 +15,9 @@ class GameManager extends ChangeNotifier { notifyListeners(); // Propagate session changes }); gameList.add(session); - print( - '[game_manager.dart] Added game session: ${session.gameTitle} at ${session.createdAt}'); gameList.sort((a, b) => b.createdAt.compareTo(a.createdAt)); - print( - '[game_manager.dart] Sorted game sessions by creation date. Total sessions: ${gameList.length}'); notifyListeners(); await LocalStorageService.saveGameSessions(); - print('[game_manager.dart] Saved game sessions to local storage.'); return gameList.indexOf(session); } @@ -40,12 +35,17 @@ class GameManager extends ChangeNotifier { /// Removes a game session by its ID. /// Takes a String [id] as input. It finds the index of the game session with the matching ID /// in the `gameList`, and then calls `removeGameSessionByIndex` with that index. - bool removeGameSessionById(String id) { + void removeGameSessionById(String id) { final int index = gameList.indexWhere((session) => session.id.toString() == id); - if (index == -1) return false; + if (index == -1) return; removeGameSessionByIndex(index); - return true; + } + + bool gameExistsInGameList(String id) { + return gameList.any((session) => session.id.toString() == id) == -1 + ? false + : true; } } From e45fc8abc886644229019cbca319d7f52edbb971 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Thu, 3 Jul 2025 13:06:40 +0200 Subject: [PATCH 08/17] Input changed to copy instead of reference --- lib/views/create_game_view.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/views/create_game_view.dart b/lib/views/create_game_view.dart index 6c52890..fd59529 100644 --- a/lib/views/create_game_view.dart +++ b/lib/views/create_game_view.dart @@ -320,12 +320,13 @@ class _CreateGameViewState extends State { isPointsLimitEnabled: _isPointsLimitEnabled!, ); final index = await gameManager.addGameSession(gameSession); + final session = gameManager.gameList[index]; if (context.mounted) { Navigator.pushReplacement( context, CupertinoPageRoute( - builder: (context) => ActiveGameView( - gameSession: gameManager.gameList[index]))); + builder: (context) => + ActiveGameView(gameSession: session))); } }, ), From 5389ce1d442fda7107fa6690948dc0a2a27fbd81 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Thu, 3 Jul 2025 13:07:01 +0200 Subject: [PATCH 09/17] Implemented deletion button --- lib/main.dart | 1 + lib/views/active_game_view.dart | 123 ++++++++++++++++++++++++-------- pubspec.yaml | 3 +- 3 files changed, 96 insertions(+), 31 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 27c3835..2a2a91e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -65,6 +65,7 @@ class _AppState extends State with WidgetsBindingObserver { return supportedLocales.first; }, theme: CupertinoThemeData( + applyThemeToAll: true, brightness: Brightness.dark, primaryColor: CustomTheme.primaryColor, scaffoldBackgroundColor: CustomTheme.backgroundColor, diff --git a/lib/views/active_game_view.dart b/lib/views/active_game_view.dart index d4ff7bd..b5eafc3 100644 --- a/lib/views/active_game_view.dart +++ b/lib/views/active_game_view.dart @@ -1,3 +1,4 @@ +import 'package:cabo_counter/data/game_manager.dart'; import 'package:cabo_counter/data/game_session.dart'; import 'package:cabo_counter/l10n/app_localizations.dart'; import 'package:cabo_counter/utility/custom_theme.dart'; @@ -17,15 +18,24 @@ class ActiveGameView extends StatefulWidget { } class _ActiveGameViewState extends State { + late final GameSession gameSession; + bool _deleted = false; + + @override + void initState() { + super.initState(); + gameSession = widget.gameSession; + } + @override Widget build(BuildContext context) { return ListenableBuilder( - listenable: widget.gameSession, + listenable: gameSession, builder: (context, _) { List sortedPlayerIndices = _getSortedPlayerIndices(); return CupertinoPageScaffold( navigationBar: CupertinoNavigationBar( - middle: Text(widget.gameSession.gameTitle), + middle: Text(gameSession.gameTitle), ), child: SafeArea( child: SingleChildScrollView( @@ -42,7 +52,7 @@ class _ActiveGameViewState extends State { ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), - itemCount: widget.gameSession.players.length, + itemCount: gameSession.players.length, itemBuilder: (BuildContext context, int index) { int playerIndex = sortedPlayerIndices[index]; return CupertinoListTile( @@ -51,7 +61,7 @@ class _ActiveGameViewState extends State { _getPlacementPrefix(index), const SizedBox(width: 5), Text( - widget.gameSession.players[playerIndex], + gameSession.players[playerIndex], style: const TextStyle( fontWeight: FontWeight.bold), ), @@ -60,8 +70,7 @@ class _ActiveGameViewState extends State { trailing: Row( children: [ const SizedBox(width: 5), - Text( - '${widget.gameSession.playerScores[playerIndex]} ' + Text('${gameSession.playerScores[playerIndex]} ' '${AppLocalizations.of(context).points}') ], ), @@ -78,7 +87,7 @@ class _ActiveGameViewState extends State { ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), - itemCount: widget.gameSession.roundNumber, + itemCount: gameSession.roundNumber, itemBuilder: (BuildContext context, int index) { return Padding( padding: const EdgeInsets.all(1), @@ -88,14 +97,13 @@ class _ActiveGameViewState extends State { title: Text( '${AppLocalizations.of(context).round} ${index + 1}', ), - trailing: index + 1 != - widget.gameSession.roundNumber || - widget.gameSession.isGameFinished == - true - ? (const Text('\u{2705}', - style: TextStyle(fontSize: 22))) - : const Text('\u{23F3}', - style: TextStyle(fontSize: 22)), + trailing: + index + 1 != gameSession.roundNumber || + gameSession.isGameFinished == true + ? (const Text('\u{2705}', + style: TextStyle(fontSize: 22))) + : const Text('\u{23F3}', + style: TextStyle(fontSize: 22)), onTap: () async { // ignore: unused_local_variable final val = await Navigator.of(context, @@ -104,7 +112,7 @@ class _ActiveGameViewState extends State { CupertinoPageRoute( fullscreenDialog: true, builder: (context) => RoundView( - gameSession: widget.gameSession, + gameSession: gameSession, roundNumber: index + 1), ), ); @@ -129,17 +137,21 @@ class _ActiveGameViewState extends State { ), onTap: () => Navigator.push( context, - MaterialPageRoute( + CupertinoPageRoute( builder: (_) => GraphView( - gameSession: widget.gameSession, + gameSession: gameSession, )))), CupertinoListTile( - title: - Text(AppLocalizations.of(context).delete_game, - style: const TextStyle( - color: Colors.white30, - )), - onTap: () {}, + title: Text( + AppLocalizations.of(context).delete_game, + ), + onTap: () { + _showDeleteGameDialog().then((value) { + if (value) { + _removeGameSession(gameSession); + } + }); + }, ), CupertinoListTile( title: Text( @@ -151,12 +163,11 @@ class _ActiveGameViewState extends State { context, CupertinoPageRoute( builder: (_) => CreateGameView( - gameTitle: - widget.gameSession.gameTitle, + gameTitle: gameSession.gameTitle, isPointsLimitEnabled: widget .gameSession .isPointsLimitEnabled, - players: widget.gameSession.players, + players: gameSession.players, ))); }, ), @@ -180,11 +191,11 @@ class _ActiveGameViewState extends State { /// ascending order. List _getSortedPlayerIndices() { List playerIndices = - List.generate(widget.gameSession.players.length, (index) => index); + List.generate(gameSession.players.length, (index) => index); // Sort the indices based on the summed points playerIndices.sort((a, b) { - int scoreA = widget.gameSession.playerScores[a]; - int scoreB = widget.gameSession.playerScores[b]; + int scoreA = gameSession.playerScores[a]; + int scoreB = gameSession.playerScores[b]; return scoreA.compareTo(scoreB); }); return playerIndices; @@ -217,4 +228,56 @@ class _ActiveGameViewState extends State { ); } } + + Future _showDeleteGameDialog() async { + return await showCupertinoDialog( + context: context, + builder: (BuildContext context) { + return CupertinoAlertDialog( + title: Text(AppLocalizations.of(context).delete_game), + content: Text( + 'Möchtes du das Spiel "${gameSession.gameTitle}" wirklich löschen?'), + actions: [ + CupertinoDialogAction( + child: Text(AppLocalizations.of(context).cancel), + onPressed: () => Navigator.pop(context, false), + ), + CupertinoDialogAction( + child: Text(AppLocalizations.of(context).delete), + onPressed: () { + Navigator.pop(context, true); + }, + ), + ], + ); + }, + ) ?? + false; + } + + Future _removeGameSession(GameSession gameSession) async { + if (gameManager.gameExistsInGameList(gameSession.id)) { + Navigator.pop(context); + + WidgetsBinding.instance.addPostFrameCallback((_) { + gameManager.removeGameSessionById(gameSession.id); + }); + } else { + showCupertinoDialog( + context: context, + builder: (BuildContext context) { + return CupertinoAlertDialog( + title: const Text('ID Fehler'), + content: const Text( + 'Das Spiel hat bisher noch keine ID zugewiesen bekommen. Falls du das Spiel löschen möchtest, mache das bitte über das Hauptmenü. Alle neu erstellten Spiele haben eine ID.'), + actions: [ + CupertinoDialogAction( + child: Text(AppLocalizations.of(context).ok), + onPressed: () => Navigator.pop(context), + ), + ], + ); + }); + } + } } diff --git a/pubspec.yaml b/pubspec.yaml index a7c91ae..a52beee 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: cabo_counter description: "Mobile app for the card game Cabo" publish_to: 'none' -version: 0.3.5+269 +version: 0.3.5+312 environment: sdk: ^3.5.4 @@ -26,6 +26,7 @@ dependencies: sdk: flutter intl: any syncfusion_flutter_charts: ^30.1.37 + uuid: ^4.5.1 dev_dependencies: flutter_test: From 6f0cd817149882377e18bc048a16ab291cb0b9a8 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Thu, 3 Jul 2025 13:08:56 +0200 Subject: [PATCH 10/17] Removed variable --- lib/views/active_game_view.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/views/active_game_view.dart b/lib/views/active_game_view.dart index b5eafc3..c44ef26 100644 --- a/lib/views/active_game_view.dart +++ b/lib/views/active_game_view.dart @@ -19,7 +19,6 @@ class ActiveGameView extends StatefulWidget { class _ActiveGameViewState extends State { late final GameSession gameSession; - bool _deleted = false; @override void initState() { From 3aab4721979e9edb4f5e9fe7dd914ff4e5b12a50 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Thu, 3 Jul 2025 13:09:09 +0200 Subject: [PATCH 11/17] Shortened return --- lib/data/game_manager.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/data/game_manager.dart b/lib/data/game_manager.dart index 1ccc9dc..24c55da 100644 --- a/lib/data/game_manager.dart +++ b/lib/data/game_manager.dart @@ -43,9 +43,7 @@ class GameManager extends ChangeNotifier { } bool gameExistsInGameList(String id) { - return gameList.any((session) => session.id.toString() == id) == -1 - ? false - : true; + return gameList.any((session) => session.id.toString() == id); } } From 9e9693ae42e5b8869170f71b3486cff8b994c196 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Thu, 3 Jul 2025 17:26:27 +0200 Subject: [PATCH 12/17] Updated localizations --- lib/l10n/app_de.arb | 9 ++++++--- lib/l10n/app_en.arb | 6 ++++-- lib/l10n/app_localizations.dart | 30 +++++++++++++++++++++--------- lib/l10n/app_localizations_de.dart | 17 ++++++++++++----- lib/l10n/app_localizations_en.dart | 15 +++++++++++---- pubspec.yaml | 2 +- 6 files changed, 55 insertions(+), 24 deletions(-) diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 51147d0..c10a52a 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -22,7 +22,7 @@ "empty_text_1": "Ganz schön leer hier...", "empty_text_2": "Füge über den Button oben rechts eine neue Runde hinzu", "delete_game_title": "Spiel löschen?", - "delete_game_message": "Bist du sicher, dass du die Runde {gameTitle} löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.", + "delete_game_message": "Bist du sicher, dass du das Spiel {gameTitle} löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.", "@delete_game_message": { "placeholders": { "gameTitle": { @@ -68,6 +68,9 @@ "delete_game": "Spiel löschen", "new_game_same_settings": "Neues Spiel mit gleichen Einstellungen", "export_game": "Spiel exportieren", + "id_error_title": "ID Fehler", + "id_error_message": "Das Spiel hat bisher noch keine ID zugewiesen bekommen. Falls du das Spiel löschen möchtest, mache das bitte über das Hauptmenü. Alle neu erstellten Spiele haben eine ID.", + "game_process": "Spielverlauf", @@ -80,7 +83,6 @@ "game_data": "Spieldaten", "import_data": "Daten importieren", "export_data": "Daten exportieren", - "error": "Fehler", "import_success_title": "Import erfolgreich", "import_success_message":"Die Spieldaten wurden erfolgreich importiert.", @@ -91,7 +93,8 @@ "import_generic_error_title": "Import fehlgeschlagen", "import_generic_error_message": "Der Import ist fehlgeschlagen.", - "error_export": "Datei konnte nicht exportiert werden", + "export_error_title": "Fehler", + "export_error_message": "Datei konnte nicht exportiert werden", "error_found": "Fehler gefunden?", "create_issue": "Issue erstellen", "app_version": "App-Version", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index a6b1a8f..73d1c96 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -80,7 +80,8 @@ "game_data": "Game Data", "import_data": "Import Data", "export_data": "Export Data", - "error": "Error", + "id_error_title": "ID Error", + "id_error_message": "The game has not yet been assigned an ID. If you want to delete the game, please do so via the main menu. All newly created games have an ID.", "import_success_title": "Import successful", "import_success_message":"The game data has been successfully imported.", @@ -91,7 +92,8 @@ "import_generic_error_title": "Import failed", "import_generic_error_message": "The import has failed.", - "error_export": "Could not export file", + "export_error_title": "Fehler", + "export_error_message": "Could not export file", "error_found": "Found a bug?", "create_issue": "Create Issue", "app_version": "App Version", diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index a4e1edb..2659d08 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -215,7 +215,7 @@ abstract class AppLocalizations { /// No description provided for @delete_game_message. /// /// In de, this message translates to: - /// **'Bist du sicher, dass du die Runde {gameTitle} löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.'** + /// **'Bist du sicher, dass du das Spiel {gameTitle} löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.'** String delete_game_message(String gameTitle); /// No description provided for @overview. @@ -386,6 +386,18 @@ abstract class AppLocalizations { /// **'Spiel exportieren'** String get export_game; + /// No description provided for @id_error_title. + /// + /// In de, this message translates to: + /// **'ID Fehler'** + String get id_error_title; + + /// No description provided for @id_error_message. + /// + /// In de, this message translates to: + /// **'Das Spiel hat bisher noch keine ID zugewiesen bekommen. Falls du das Spiel löschen möchtest, mache das bitte über das Hauptmenü. Alle neu erstellten Spiele haben eine ID.'** + String get id_error_message; + /// No description provided for @game_process. /// /// In de, this message translates to: @@ -446,12 +458,6 @@ abstract class AppLocalizations { /// **'Daten exportieren'** String get export_data; - /// No description provided for @error. - /// - /// In de, this message translates to: - /// **'Fehler'** - String get error; - /// No description provided for @import_success_title. /// /// In de, this message translates to: @@ -500,11 +506,17 @@ abstract class AppLocalizations { /// **'Der Import ist fehlgeschlagen.'** String get import_generic_error_message; - /// No description provided for @error_export. + /// No description provided for @export_error_title. + /// + /// In de, this message translates to: + /// **'Fehler'** + String get export_error_title; + + /// No description provided for @export_error_message. /// /// In de, this message translates to: /// **'Datei konnte nicht exportiert werden'** - String get error_export; + String get export_error_message; /// No description provided for @error_found. /// diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index b06d454..6d5f1a0 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -68,7 +68,7 @@ class AppLocalizationsDe extends AppLocalizations { @override String delete_game_message(String gameTitle) { - return 'Bist du sicher, dass du die Runde $gameTitle löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.'; + return 'Bist du sicher, dass du das Spiel $gameTitle löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.'; } @override @@ -161,6 +161,13 @@ class AppLocalizationsDe extends AppLocalizations { @override String get export_game => 'Spiel exportieren'; + @override + String get id_error_title => 'ID Fehler'; + + @override + String get id_error_message => + 'Das Spiel hat bisher noch keine ID zugewiesen bekommen. Falls du das Spiel löschen möchtest, mache das bitte über das Hauptmenü. Alle neu erstellten Spiele haben eine ID.'; + @override String get game_process => 'Spielverlauf'; @@ -191,9 +198,6 @@ class AppLocalizationsDe extends AppLocalizations { @override String get export_data => 'Daten exportieren'; - @override - String get error => 'Fehler'; - @override String get import_success_title => 'Import erfolgreich'; @@ -222,7 +226,10 @@ class AppLocalizationsDe extends AppLocalizations { String get import_generic_error_message => 'Der Import ist fehlgeschlagen.'; @override - String get error_export => 'Datei konnte nicht exportiert werden'; + String get export_error_title => 'Fehler'; + + @override + String get export_error_message => 'Datei konnte nicht exportiert werden'; @override String get error_found => 'Fehler gefunden?'; diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 2dfc72d..63553ff 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -158,6 +158,13 @@ class AppLocalizationsEn extends AppLocalizations { @override String get export_game => 'Export Game'; + @override + String get id_error_title => 'ID Error'; + + @override + String get id_error_message => + 'The game has not yet been assigned an ID. If you want to delete the game, please do so via the main menu. All newly created games have an ID.'; + @override String get game_process => 'Spielverlauf'; @@ -188,9 +195,6 @@ class AppLocalizationsEn extends AppLocalizations { @override String get export_data => 'Export Data'; - @override - String get error => 'Error'; - @override String get import_success_title => 'Import successful'; @@ -219,7 +223,10 @@ class AppLocalizationsEn extends AppLocalizations { String get import_generic_error_message => 'The import has failed.'; @override - String get error_export => 'Could not export file'; + String get export_error_title => 'Fehler'; + + @override + String get export_error_message => 'Could not export file'; @override String get error_found => 'Found a bug?'; diff --git a/pubspec.yaml b/pubspec.yaml index a52beee..88e2991 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: cabo_counter description: "Mobile app for the card game Cabo" publish_to: 'none' -version: 0.3.5+312 +version: 0.3.5+317 environment: sdk: ^3.5.4 From 5c1ed94d446da1570c22063b586c6c5ed5a93251 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Thu, 3 Jul 2025 17:26:39 +0200 Subject: [PATCH 13/17] Implemented localizations --- lib/views/active_game_view.dart | 11 ++++++----- lib/views/settings_view.dart | 6 +++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/views/active_game_view.dart b/lib/views/active_game_view.dart index c44ef26..3f9c613 100644 --- a/lib/views/active_game_view.dart +++ b/lib/views/active_game_view.dart @@ -233,9 +233,11 @@ class _ActiveGameViewState extends State { context: context, builder: (BuildContext context) { return CupertinoAlertDialog( - title: Text(AppLocalizations.of(context).delete_game), + title: Text(AppLocalizations.of(context).delete_game_title), content: Text( - 'Möchtes du das Spiel "${gameSession.gameTitle}" wirklich löschen?'), + AppLocalizations.of(context) + .delete_game_message(gameSession.gameTitle), + ), actions: [ CupertinoDialogAction( child: Text(AppLocalizations.of(context).cancel), @@ -266,9 +268,8 @@ class _ActiveGameViewState extends State { context: context, builder: (BuildContext context) { return CupertinoAlertDialog( - title: const Text('ID Fehler'), - content: const Text( - 'Das Spiel hat bisher noch keine ID zugewiesen bekommen. Falls du das Spiel löschen möchtest, mache das bitte über das Hauptmenü. Alle neu erstellten Spiele haben eine ID.'), + title: Text(AppLocalizations.of(context).id_error_title), + content: Text(AppLocalizations.of(context).id_error_message), actions: [ CupertinoDialogAction( child: Text(AppLocalizations.of(context).ok), diff --git a/lib/views/settings_view.dart b/lib/views/settings_view.dart index b36347d..b9ae02c 100644 --- a/lib/views/settings_view.dart +++ b/lib/views/settings_view.dart @@ -145,10 +145,10 @@ class _SettingsViewState extends State { showCupertinoDialog( context: context, builder: (context) => CupertinoAlertDialog( - title: - Text(AppLocalizations.of(context).error), + title: Text(AppLocalizations.of(context) + .export_error_title), content: Text(AppLocalizations.of(context) - .error_export), + .export_error_message), actions: [ CupertinoDialogAction( child: From 7d6c3e5f14b5593eb91696a264147e0d003e0af0 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Thu, 3 Jul 2025 17:32:52 +0200 Subject: [PATCH 14/17] Added quotation marks to String --- lib/l10n/app_de.arb | 2 +- lib/l10n/app_en.arb | 2 +- lib/l10n/app_localizations.dart | 2 +- lib/l10n/app_localizations_de.dart | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index c10a52a..7fa3710 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -22,7 +22,7 @@ "empty_text_1": "Ganz schön leer hier...", "empty_text_2": "Füge über den Button oben rechts eine neue Runde hinzu", "delete_game_title": "Spiel löschen?", - "delete_game_message": "Bist du sicher, dass du das Spiel {gameTitle} löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.", + "delete_game_message": "Bist du sicher, dass du das Spiel \"{gameTitle}\" löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.", "@delete_game_message": { "placeholders": { "gameTitle": { diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 73d1c96..ce99202 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -22,7 +22,7 @@ "empty_text_1": "Pretty empty here...", "empty_text_2": "Add a new round using the button in the top right corner.", "delete_game_title": "Delete game?", - "delete_game_message": "Are you sure you want to delete the game {gameTitle}? This action cannot be undone.", + "delete_game_message": "Are you sure you want to delete the game \"{gameTitle}\"? This action cannot be undone.", "@delete_game_message": { "placeholders": { "gameTitle": { diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 2659d08..eb858f5 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -215,7 +215,7 @@ abstract class AppLocalizations { /// No description provided for @delete_game_message. /// /// In de, this message translates to: - /// **'Bist du sicher, dass du das Spiel {gameTitle} löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.'** + /// **'Bist du sicher, dass du das Spiel \"{gameTitle}\" löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.'** String delete_game_message(String gameTitle); /// No description provided for @overview. diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index 6d5f1a0..f72adbb 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -68,7 +68,7 @@ class AppLocalizationsDe extends AppLocalizations { @override String delete_game_message(String gameTitle) { - return 'Bist du sicher, dass du das Spiel $gameTitle löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.'; + return 'Bist du sicher, dass du das Spiel \"$gameTitle\" löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.'; } @override From 4f2f2c8d3c5d2cfc45b815cc3af03f00e2cae06f Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Thu, 3 Jul 2025 17:33:19 +0200 Subject: [PATCH 15/17] Updated delete popup style --- lib/views/active_game_view.dart | 6 +++++- lib/views/main_menu_view.dart | 6 +++++- pubspec.yaml | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/views/active_game_view.dart b/lib/views/active_game_view.dart index 3f9c613..1b5e546 100644 --- a/lib/views/active_game_view.dart +++ b/lib/views/active_game_view.dart @@ -244,7 +244,11 @@ class _ActiveGameViewState extends State { onPressed: () => Navigator.pop(context, false), ), CupertinoDialogAction( - child: Text(AppLocalizations.of(context).delete), + child: Text( + AppLocalizations.of(context).delete, + style: const TextStyle( + fontWeight: FontWeight.bold, color: Colors.red), + ), onPressed: () { Navigator.pop(context, true); }, diff --git a/lib/views/main_menu_view.dart b/lib/views/main_menu_view.dart index 3a9441f..3281c6f 100644 --- a/lib/views/main_menu_view.dart +++ b/lib/views/main_menu_view.dart @@ -226,7 +226,11 @@ class _MainMenuViewState extends State { onPressed: () { Navigator.pop(context, true); }, - child: Text(AppLocalizations.of(context).delete), + child: Text( + AppLocalizations.of(context).delete, + style: const TextStyle( + fontWeight: FontWeight.bold, color: Colors.red), + ), ), ], ); diff --git a/pubspec.yaml b/pubspec.yaml index 88e2991..56b89bc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: cabo_counter description: "Mobile app for the card game Cabo" publish_to: 'none' -version: 0.3.5+317 +version: 0.3.6+318 environment: sdk: ^3.5.4 From 1c2803eb85dcd93d2dad90eaf11dcef12e3e2b79 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Thu, 3 Jul 2025 17:34:12 +0200 Subject: [PATCH 16/17] Deleted print --- lib/data/game_session.dart | 1 - lib/l10n/app_localizations_en.dart | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/data/game_session.dart b/lib/data/game_session.dart index ada34dc..36c4c4e 100644 --- a/lib/data/game_session.dart +++ b/lib/data/game_session.dart @@ -37,7 +37,6 @@ class GameSession extends ChangeNotifier { playerScores = List.filled(players.length, 0); var uuid = const Uuid(); id = uuid.v1(); - print('GameSession created with ID: $id'); } @override diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 63553ff..27d675b 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -68,7 +68,7 @@ class AppLocalizationsEn extends AppLocalizations { @override String delete_game_message(String gameTitle) { - return 'Are you sure you want to delete the game $gameTitle? This action cannot be undone.'; + return 'Are you sure you want to delete the game \"$gameTitle\"? This action cannot be undone.'; } @override From 69b213ffe3f2cc436faa6b8a123bb26e93849bd2 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Thu, 3 Jul 2025 17:38:05 +0200 Subject: [PATCH 17/17] Updated translation --- lib/l10n/app_en.arb | 2 +- lib/l10n/app_localizations_en.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index ce99202..f8dbb2f 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -92,7 +92,7 @@ "import_generic_error_title": "Import failed", "import_generic_error_message": "The import has failed.", - "export_error_title": "Fehler", + "export_error_title": "Export failed", "export_error_message": "Could not export file", "error_found": "Found a bug?", "create_issue": "Create Issue", diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 27d675b..657f2ce 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -223,7 +223,7 @@ class AppLocalizationsEn extends AppLocalizations { String get import_generic_error_message => 'The import has failed.'; @override - String get export_error_title => 'Fehler'; + String get export_error_title => 'Export failed'; @override String get export_error_message => 'Could not export file';