Merge pull request #76 from flixcoo/feature/62-implement-delete-game-button-in-activegameview
Implement delete game button in activegameview
This commit is contained in:
@@ -5,6 +5,9 @@
|
|||||||
"items": {
|
"items": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"createdAt": {
|
"createdAt": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -15,14 +15,9 @@ class GameManager extends ChangeNotifier {
|
|||||||
notifyListeners(); // Propagate session changes
|
notifyListeners(); // Propagate session changes
|
||||||
});
|
});
|
||||||
gameList.add(session);
|
gameList.add(session);
|
||||||
print(
|
|
||||||
'[game_manager.dart] Added game session: ${session.gameTitle} at ${session.createdAt}');
|
|
||||||
gameList.sort((a, b) => b.createdAt.compareTo(a.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();
|
notifyListeners();
|
||||||
await LocalStorageService.saveGameSessions();
|
await LocalStorageService.saveGameSessions();
|
||||||
print('[game_manager.dart] Saved game sessions to local storage.');
|
|
||||||
return gameList.indexOf(session);
|
return gameList.indexOf(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,12 +25,26 @@ class GameManager extends ChangeNotifier {
|
|||||||
/// Takes a [index] as input. It then removes the session at the specified index from the `gameList`,
|
/// 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.
|
/// 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.
|
/// It also saves the updated game sessions to local storage.
|
||||||
void removeGameSession(int index) {
|
void removeGameSessionByIndex(int index) {
|
||||||
gameList[index].removeListener(notifyListeners);
|
gameList[index].removeListener(notifyListeners);
|
||||||
gameList.removeAt(index);
|
gameList.removeAt(index);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
LocalStorageService.saveGameSessions();
|
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.
|
||||||
|
void removeGameSessionById(String id) {
|
||||||
|
final int index =
|
||||||
|
gameList.indexWhere((session) => session.id.toString() == id);
|
||||||
|
if (index == -1) return;
|
||||||
|
removeGameSessionByIndex(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool gameExistsInGameList(String id) {
|
||||||
|
return gameList.any((session) => session.id.toString() == id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final gameManager = GameManager();
|
final gameManager = GameManager();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:cabo_counter/data/round.dart';
|
import 'package:cabo_counter/data/round.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
/// This class represents a game session for Cabo game.
|
/// This class represents a game session for Cabo game.
|
||||||
/// [createdAt] is the timestamp of when the game session was created.
|
/// [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.
|
/// [isGameFinished] is a boolean indicating if the game has ended yet.
|
||||||
/// [winner] is the name of the player who won the game.
|
/// [winner] is the name of the player who won the game.
|
||||||
class GameSession extends ChangeNotifier {
|
class GameSession extends ChangeNotifier {
|
||||||
|
late String id;
|
||||||
final DateTime createdAt;
|
final DateTime createdAt;
|
||||||
final String gameTitle;
|
final String gameTitle;
|
||||||
final List<String> players;
|
final List<String> players;
|
||||||
@@ -33,17 +35,20 @@ class GameSession extends ChangeNotifier {
|
|||||||
required this.isPointsLimitEnabled,
|
required this.isPointsLimitEnabled,
|
||||||
}) {
|
}) {
|
||||||
playerScores = List.filled(players.length, 0);
|
playerScores = List.filled(players.length, 0);
|
||||||
|
var uuid = const Uuid();
|
||||||
|
id = uuid.v1();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
toString() {
|
toString() {
|
||||||
return ('GameSession: [createdAt: $createdAt, gameTitle: $gameTitle, '
|
return ('GameSession: [id: $id, createdAt: $createdAt, gameTitle: $gameTitle, '
|
||||||
'isPointsLimitEnabled: $isPointsLimitEnabled, pointLimit: $pointLimit, caboPenalty: $caboPenalty,'
|
'isPointsLimitEnabled: $isPointsLimitEnabled, pointLimit: $pointLimit, caboPenalty: $caboPenalty,'
|
||||||
' players: $players, playerScores: $playerScores, roundList: $roundList, winner: $winner]');
|
' players: $players, playerScores: $playerScores, roundList: $roundList, winner: $winner]');
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts the GameSession object to a JSON map.
|
/// Converts the GameSession object to a JSON map.
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
|
'id': id,
|
||||||
'createdAt': createdAt.toIso8601String(),
|
'createdAt': createdAt.toIso8601String(),
|
||||||
'gameTitle': gameTitle,
|
'gameTitle': gameTitle,
|
||||||
'players': players,
|
'players': players,
|
||||||
@@ -59,7 +64,8 @@ class GameSession extends ChangeNotifier {
|
|||||||
|
|
||||||
/// Creates a GameSession object from a JSON map.
|
/// Creates a GameSession object from a JSON map.
|
||||||
GameSession.fromJson(Map<String, dynamic> json)
|
GameSession.fromJson(Map<String, dynamic> json)
|
||||||
: createdAt = DateTime.parse(json['createdAt']),
|
: id = json['id'] ?? const Uuid().v1(),
|
||||||
|
createdAt = DateTime.parse(json['createdAt']),
|
||||||
gameTitle = json['gameTitle'],
|
gameTitle = json['gameTitle'],
|
||||||
players = List<String>.from(json['players']),
|
players = List<String>.from(json['players']),
|
||||||
pointLimit = json['pointLimit'],
|
pointLimit = json['pointLimit'],
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
"empty_text_1": "Ganz schön leer hier...",
|
"empty_text_1": "Ganz schön leer hier...",
|
||||||
"empty_text_2": "Füge über den Button oben rechts eine neue Runde hinzu",
|
"empty_text_2": "Füge über den Button oben rechts eine neue Runde hinzu",
|
||||||
"delete_game_title": "Spiel löschen?",
|
"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": {
|
"@delete_game_message": {
|
||||||
"placeholders": {
|
"placeholders": {
|
||||||
"gameTitle": {
|
"gameTitle": {
|
||||||
@@ -68,6 +68,9 @@
|
|||||||
"delete_game": "Spiel löschen",
|
"delete_game": "Spiel löschen",
|
||||||
"new_game_same_settings": "Neues Spiel mit gleichen Einstellungen",
|
"new_game_same_settings": "Neues Spiel mit gleichen Einstellungen",
|
||||||
"export_game": "Spiel exportieren",
|
"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",
|
"game_process": "Spielverlauf",
|
||||||
|
|
||||||
@@ -80,7 +83,6 @@
|
|||||||
"game_data": "Spieldaten",
|
"game_data": "Spieldaten",
|
||||||
"import_data": "Daten importieren",
|
"import_data": "Daten importieren",
|
||||||
"export_data": "Daten exportieren",
|
"export_data": "Daten exportieren",
|
||||||
"error": "Fehler",
|
|
||||||
|
|
||||||
"import_success_title": "Import erfolgreich",
|
"import_success_title": "Import erfolgreich",
|
||||||
"import_success_message":"Die Spieldaten wurden erfolgreich importiert.",
|
"import_success_message":"Die Spieldaten wurden erfolgreich importiert.",
|
||||||
@@ -91,7 +93,8 @@
|
|||||||
"import_generic_error_title": "Import fehlgeschlagen",
|
"import_generic_error_title": "Import fehlgeschlagen",
|
||||||
"import_generic_error_message": "Der Import ist 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?",
|
"error_found": "Fehler gefunden?",
|
||||||
"create_issue": "Issue erstellen",
|
"create_issue": "Issue erstellen",
|
||||||
"app_version": "App-Version",
|
"app_version": "App-Version",
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
"empty_text_1": "Pretty empty here...",
|
"empty_text_1": "Pretty empty here...",
|
||||||
"empty_text_2": "Add a new round using the button in the top right corner.",
|
"empty_text_2": "Add a new round using the button in the top right corner.",
|
||||||
"delete_game_title": "Delete game?",
|
"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": {
|
"@delete_game_message": {
|
||||||
"placeholders": {
|
"placeholders": {
|
||||||
"gameTitle": {
|
"gameTitle": {
|
||||||
@@ -80,7 +80,8 @@
|
|||||||
"game_data": "Game Data",
|
"game_data": "Game Data",
|
||||||
"import_data": "Import Data",
|
"import_data": "Import Data",
|
||||||
"export_data": "Export 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_title": "Import successful",
|
||||||
"import_success_message":"The game data has been successfully imported.",
|
"import_success_message":"The game data has been successfully imported.",
|
||||||
@@ -91,7 +92,8 @@
|
|||||||
"import_generic_error_title": "Import failed",
|
"import_generic_error_title": "Import failed",
|
||||||
"import_generic_error_message": "The import has failed.",
|
"import_generic_error_message": "The import has failed.",
|
||||||
|
|
||||||
"error_export": "Could not export file",
|
"export_error_title": "Export failed",
|
||||||
|
"export_error_message": "Could not export file",
|
||||||
"error_found": "Found a bug?",
|
"error_found": "Found a bug?",
|
||||||
"create_issue": "Create Issue",
|
"create_issue": "Create Issue",
|
||||||
"app_version": "App Version",
|
"app_version": "App Version",
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ abstract class AppLocalizations {
|
|||||||
/// No description provided for @delete_game_message.
|
/// No description provided for @delete_game_message.
|
||||||
///
|
///
|
||||||
/// In de, this message translates to:
|
/// 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);
|
String delete_game_message(String gameTitle);
|
||||||
|
|
||||||
/// No description provided for @overview.
|
/// No description provided for @overview.
|
||||||
@@ -386,6 +386,18 @@ abstract class AppLocalizations {
|
|||||||
/// **'Spiel exportieren'**
|
/// **'Spiel exportieren'**
|
||||||
String get export_game;
|
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.
|
/// No description provided for @game_process.
|
||||||
///
|
///
|
||||||
/// In de, this message translates to:
|
/// In de, this message translates to:
|
||||||
@@ -446,12 +458,6 @@ abstract class AppLocalizations {
|
|||||||
/// **'Daten exportieren'**
|
/// **'Daten exportieren'**
|
||||||
String get export_data;
|
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.
|
/// No description provided for @import_success_title.
|
||||||
///
|
///
|
||||||
/// In de, this message translates to:
|
/// In de, this message translates to:
|
||||||
@@ -500,11 +506,17 @@ abstract class AppLocalizations {
|
|||||||
/// **'Der Import ist fehlgeschlagen.'**
|
/// **'Der Import ist fehlgeschlagen.'**
|
||||||
String get import_generic_error_message;
|
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:
|
/// In de, this message translates to:
|
||||||
/// **'Datei konnte nicht exportiert werden'**
|
/// **'Datei konnte nicht exportiert werden'**
|
||||||
String get error_export;
|
String get export_error_message;
|
||||||
|
|
||||||
/// No description provided for @error_found.
|
/// No description provided for @error_found.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String delete_game_message(String gameTitle) {
|
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
|
@override
|
||||||
@@ -161,6 +161,13 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get export_game => 'Spiel exportieren';
|
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
|
@override
|
||||||
String get game_process => 'Spielverlauf';
|
String get game_process => 'Spielverlauf';
|
||||||
|
|
||||||
@@ -191,9 +198,6 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get export_data => 'Daten exportieren';
|
String get export_data => 'Daten exportieren';
|
||||||
|
|
||||||
@override
|
|
||||||
String get error => 'Fehler';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get import_success_title => 'Import erfolgreich';
|
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.';
|
String get import_generic_error_message => 'Der Import ist fehlgeschlagen.';
|
||||||
|
|
||||||
@override
|
@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
|
@override
|
||||||
String get error_found => 'Fehler gefunden?';
|
String get error_found => 'Fehler gefunden?';
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String delete_game_message(String gameTitle) {
|
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
|
@override
|
||||||
@@ -158,6 +158,13 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get export_game => 'Export Game';
|
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
|
@override
|
||||||
String get game_process => 'Spielverlauf';
|
String get game_process => 'Spielverlauf';
|
||||||
|
|
||||||
@@ -188,9 +195,6 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get export_data => 'Export Data';
|
String get export_data => 'Export Data';
|
||||||
|
|
||||||
@override
|
|
||||||
String get error => 'Error';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get import_success_title => 'Import successful';
|
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.';
|
String get import_generic_error_message => 'The import has failed.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get error_export => 'Could not export file';
|
String get export_error_title => 'Export failed';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get export_error_message => 'Could not export file';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get error_found => 'Found a bug?';
|
String get error_found => 'Found a bug?';
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ class _AppState extends State<App> with WidgetsBindingObserver {
|
|||||||
return supportedLocales.first;
|
return supportedLocales.first;
|
||||||
},
|
},
|
||||||
theme: CupertinoThemeData(
|
theme: CupertinoThemeData(
|
||||||
|
applyThemeToAll: true,
|
||||||
brightness: Brightness.dark,
|
brightness: Brightness.dark,
|
||||||
primaryColor: CustomTheme.primaryColor,
|
primaryColor: CustomTheme.primaryColor,
|
||||||
scaffoldBackgroundColor: CustomTheme.backgroundColor,
|
scaffoldBackgroundColor: CustomTheme.backgroundColor,
|
||||||
|
|||||||
@@ -86,6 +86,11 @@ class LocalStorageService {
|
|||||||
GameSession.fromJson(jsonItem as Map<String, dynamic>))
|
GameSession.fromJson(jsonItem as Map<String, dynamic>))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
|
for (GameSession session in gameManager.gameList) {
|
||||||
|
print(
|
||||||
|
'[local_storage_service.dart] Geladene Session: ${session.gameTitle} - ${session.id}');
|
||||||
|
}
|
||||||
|
|
||||||
print(
|
print(
|
||||||
'[local_storage_service.dart] Die Spieldaten wurden erfolgreich geladen und verarbeitet');
|
'[local_storage_service.dart] Die Spieldaten wurden erfolgreich geladen und verarbeitet');
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:cabo_counter/data/game_manager.dart';
|
||||||
import 'package:cabo_counter/data/game_session.dart';
|
import 'package:cabo_counter/data/game_session.dart';
|
||||||
import 'package:cabo_counter/l10n/app_localizations.dart';
|
import 'package:cabo_counter/l10n/app_localizations.dart';
|
||||||
import 'package:cabo_counter/utility/custom_theme.dart';
|
import 'package:cabo_counter/utility/custom_theme.dart';
|
||||||
@@ -17,15 +18,23 @@ class ActiveGameView extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ActiveGameViewState extends State<ActiveGameView> {
|
class _ActiveGameViewState extends State<ActiveGameView> {
|
||||||
|
late final GameSession gameSession;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
gameSession = widget.gameSession;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ListenableBuilder(
|
return ListenableBuilder(
|
||||||
listenable: widget.gameSession,
|
listenable: gameSession,
|
||||||
builder: (context, _) {
|
builder: (context, _) {
|
||||||
List<int> sortedPlayerIndices = _getSortedPlayerIndices();
|
List<int> sortedPlayerIndices = _getSortedPlayerIndices();
|
||||||
return CupertinoPageScaffold(
|
return CupertinoPageScaffold(
|
||||||
navigationBar: CupertinoNavigationBar(
|
navigationBar: CupertinoNavigationBar(
|
||||||
middle: Text(widget.gameSession.gameTitle),
|
middle: Text(gameSession.gameTitle),
|
||||||
),
|
),
|
||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
@@ -42,7 +51,7 @@ class _ActiveGameViewState extends State<ActiveGameView> {
|
|||||||
ListView.builder(
|
ListView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
itemCount: widget.gameSession.players.length,
|
itemCount: gameSession.players.length,
|
||||||
itemBuilder: (BuildContext context, int index) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
int playerIndex = sortedPlayerIndices[index];
|
int playerIndex = sortedPlayerIndices[index];
|
||||||
return CupertinoListTile(
|
return CupertinoListTile(
|
||||||
@@ -51,7 +60,7 @@ class _ActiveGameViewState extends State<ActiveGameView> {
|
|||||||
_getPlacementPrefix(index),
|
_getPlacementPrefix(index),
|
||||||
const SizedBox(width: 5),
|
const SizedBox(width: 5),
|
||||||
Text(
|
Text(
|
||||||
widget.gameSession.players[playerIndex],
|
gameSession.players[playerIndex],
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontWeight: FontWeight.bold),
|
fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
@@ -60,8 +69,7 @@ class _ActiveGameViewState extends State<ActiveGameView> {
|
|||||||
trailing: Row(
|
trailing: Row(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(width: 5),
|
const SizedBox(width: 5),
|
||||||
Text(
|
Text('${gameSession.playerScores[playerIndex]} '
|
||||||
'${widget.gameSession.playerScores[playerIndex]} '
|
|
||||||
'${AppLocalizations.of(context).points}')
|
'${AppLocalizations.of(context).points}')
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -78,7 +86,7 @@ class _ActiveGameViewState extends State<ActiveGameView> {
|
|||||||
ListView.builder(
|
ListView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
itemCount: widget.gameSession.roundNumber,
|
itemCount: gameSession.roundNumber,
|
||||||
itemBuilder: (BuildContext context, int index) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.all(1),
|
padding: const EdgeInsets.all(1),
|
||||||
@@ -88,14 +96,13 @@ class _ActiveGameViewState extends State<ActiveGameView> {
|
|||||||
title: Text(
|
title: Text(
|
||||||
'${AppLocalizations.of(context).round} ${index + 1}',
|
'${AppLocalizations.of(context).round} ${index + 1}',
|
||||||
),
|
),
|
||||||
trailing: index + 1 !=
|
trailing:
|
||||||
widget.gameSession.roundNumber ||
|
index + 1 != gameSession.roundNumber ||
|
||||||
widget.gameSession.isGameFinished ==
|
gameSession.isGameFinished == true
|
||||||
true
|
? (const Text('\u{2705}',
|
||||||
? (const Text('\u{2705}',
|
style: TextStyle(fontSize: 22)))
|
||||||
style: TextStyle(fontSize: 22)))
|
: const Text('\u{23F3}',
|
||||||
: const Text('\u{23F3}',
|
style: TextStyle(fontSize: 22)),
|
||||||
style: TextStyle(fontSize: 22)),
|
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
// ignore: unused_local_variable
|
// ignore: unused_local_variable
|
||||||
final val = await Navigator.of(context,
|
final val = await Navigator.of(context,
|
||||||
@@ -104,7 +111,7 @@ class _ActiveGameViewState extends State<ActiveGameView> {
|
|||||||
CupertinoPageRoute(
|
CupertinoPageRoute(
|
||||||
fullscreenDialog: true,
|
fullscreenDialog: true,
|
||||||
builder: (context) => RoundView(
|
builder: (context) => RoundView(
|
||||||
gameSession: widget.gameSession,
|
gameSession: gameSession,
|
||||||
roundNumber: index + 1),
|
roundNumber: index + 1),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -129,17 +136,21 @@ class _ActiveGameViewState extends State<ActiveGameView> {
|
|||||||
),
|
),
|
||||||
onTap: () => Navigator.push(
|
onTap: () => Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
CupertinoPageRoute(
|
||||||
builder: (_) => GraphView(
|
builder: (_) => GraphView(
|
||||||
gameSession: widget.gameSession,
|
gameSession: gameSession,
|
||||||
)))),
|
)))),
|
||||||
CupertinoListTile(
|
CupertinoListTile(
|
||||||
title:
|
title: Text(
|
||||||
Text(AppLocalizations.of(context).delete_game,
|
AppLocalizations.of(context).delete_game,
|
||||||
style: const TextStyle(
|
),
|
||||||
color: Colors.white30,
|
onTap: () {
|
||||||
)),
|
_showDeleteGameDialog().then((value) {
|
||||||
onTap: () {},
|
if (value) {
|
||||||
|
_removeGameSession(gameSession);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
),
|
),
|
||||||
CupertinoListTile(
|
CupertinoListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
@@ -151,12 +162,11 @@ class _ActiveGameViewState extends State<ActiveGameView> {
|
|||||||
context,
|
context,
|
||||||
CupertinoPageRoute(
|
CupertinoPageRoute(
|
||||||
builder: (_) => CreateGameView(
|
builder: (_) => CreateGameView(
|
||||||
gameTitle:
|
gameTitle: gameSession.gameTitle,
|
||||||
widget.gameSession.gameTitle,
|
|
||||||
isPointsLimitEnabled: widget
|
isPointsLimitEnabled: widget
|
||||||
.gameSession
|
.gameSession
|
||||||
.isPointsLimitEnabled,
|
.isPointsLimitEnabled,
|
||||||
players: widget.gameSession.players,
|
players: gameSession.players,
|
||||||
)));
|
)));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -180,11 +190,11 @@ class _ActiveGameViewState extends State<ActiveGameView> {
|
|||||||
/// ascending order.
|
/// ascending order.
|
||||||
List<int> _getSortedPlayerIndices() {
|
List<int> _getSortedPlayerIndices() {
|
||||||
List<int> playerIndices =
|
List<int> playerIndices =
|
||||||
List<int>.generate(widget.gameSession.players.length, (index) => index);
|
List<int>.generate(gameSession.players.length, (index) => index);
|
||||||
// Sort the indices based on the summed points
|
// Sort the indices based on the summed points
|
||||||
playerIndices.sort((a, b) {
|
playerIndices.sort((a, b) {
|
||||||
int scoreA = widget.gameSession.playerScores[a];
|
int scoreA = gameSession.playerScores[a];
|
||||||
int scoreB = widget.gameSession.playerScores[b];
|
int scoreB = gameSession.playerScores[b];
|
||||||
return scoreA.compareTo(scoreB);
|
return scoreA.compareTo(scoreB);
|
||||||
});
|
});
|
||||||
return playerIndices;
|
return playerIndices;
|
||||||
@@ -217,4 +227,61 @@ class _ActiveGameViewState extends State<ActiveGameView> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> _showDeleteGameDialog() async {
|
||||||
|
return await showCupertinoDialog<bool>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return CupertinoAlertDialog(
|
||||||
|
title: Text(AppLocalizations.of(context).delete_game_title),
|
||||||
|
content: Text(
|
||||||
|
AppLocalizations.of(context)
|
||||||
|
.delete_game_message(gameSession.gameTitle),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
CupertinoDialogAction(
|
||||||
|
child: Text(AppLocalizations.of(context).cancel),
|
||||||
|
onPressed: () => Navigator.pop(context, false),
|
||||||
|
),
|
||||||
|
CupertinoDialogAction(
|
||||||
|
child: Text(
|
||||||
|
AppLocalizations.of(context).delete,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold, color: Colors.red),
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context, true);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
) ??
|
||||||
|
false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _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: Text(AppLocalizations.of(context).id_error_title),
|
||||||
|
content: Text(AppLocalizations.of(context).id_error_message),
|
||||||
|
actions: [
|
||||||
|
CupertinoDialogAction(
|
||||||
|
child: Text(AppLocalizations.of(context).ok),
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -320,12 +320,13 @@ class _CreateGameViewState extends State<CreateGameView> {
|
|||||||
isPointsLimitEnabled: _isPointsLimitEnabled!,
|
isPointsLimitEnabled: _isPointsLimitEnabled!,
|
||||||
);
|
);
|
||||||
final index = await gameManager.addGameSession(gameSession);
|
final index = await gameManager.addGameSession(gameSession);
|
||||||
|
final session = gameManager.gameList[index];
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
Navigator.pushReplacement(
|
Navigator.pushReplacement(
|
||||||
context,
|
context,
|
||||||
CupertinoPageRoute(
|
CupertinoPageRoute(
|
||||||
builder: (context) => ActiveGameView(
|
builder: (context) =>
|
||||||
gameSession: gameManager.gameList[index])));
|
ActiveGameView(gameSession: session)));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -131,7 +131,8 @@ class _MainMenuViewState extends State<MainMenuView> {
|
|||||||
gameTitle);
|
gameTitle);
|
||||||
},
|
},
|
||||||
onDismissed: (direction) {
|
onDismissed: (direction) {
|
||||||
gameManager.removeGameSession(index);
|
gameManager
|
||||||
|
.removeGameSessionByIndex(index);
|
||||||
},
|
},
|
||||||
dismissThresholds: const {
|
dismissThresholds: const {
|
||||||
DismissDirection.startToEnd: 0.6
|
DismissDirection.startToEnd: 0.6
|
||||||
@@ -168,18 +169,19 @@ class _MainMenuViewState extends State<MainMenuView> {
|
|||||||
CupertinoIcons.person_2_fill),
|
CupertinoIcons.person_2_fill),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
onTap: () async {
|
onTap: () {
|
||||||
//ignore: unused_local_variable
|
final session =
|
||||||
final val = await Navigator.push(
|
gameManager.gameList[index];
|
||||||
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
CupertinoPageRoute(
|
CupertinoPageRoute(
|
||||||
builder: (context) =>
|
builder: (context) =>
|
||||||
ActiveGameView(
|
ActiveGameView(
|
||||||
gameSession: gameManager
|
gameSession: session),
|
||||||
.gameList[index]),
|
|
||||||
),
|
),
|
||||||
);
|
).then((_) {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -224,7 +226,11 @@ class _MainMenuViewState extends State<MainMenuView> {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(context, true);
|
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),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -145,10 +145,10 @@ class _SettingsViewState extends State<SettingsView> {
|
|||||||
showCupertinoDialog(
|
showCupertinoDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => CupertinoAlertDialog(
|
builder: (context) => CupertinoAlertDialog(
|
||||||
title:
|
title: Text(AppLocalizations.of(context)
|
||||||
Text(AppLocalizations.of(context).error),
|
.export_error_title),
|
||||||
content: Text(AppLocalizations.of(context)
|
content: Text(AppLocalizations.of(context)
|
||||||
.error_export),
|
.export_error_message),
|
||||||
actions: [
|
actions: [
|
||||||
CupertinoDialogAction(
|
CupertinoDialogAction(
|
||||||
child:
|
child:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ name: cabo_counter
|
|||||||
description: "Mobile app for the card game Cabo"
|
description: "Mobile app for the card game Cabo"
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
|
|
||||||
version: 0.3.5+269
|
version: 0.3.6+318
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.5.4
|
sdk: ^3.5.4
|
||||||
@@ -26,6 +26,7 @@ dependencies:
|
|||||||
sdk: flutter
|
sdk: flutter
|
||||||
intl: any
|
intl: any
|
||||||
syncfusion_flutter_charts: ^30.1.37
|
syncfusion_flutter_charts: ^30.1.37
|
||||||
|
uuid: ^4.5.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
Reference in New Issue
Block a user