Merge pull request #24 from flixcoo/feature/23-implement-deletion-of-game-sessions

feature/23-implement-deletion-of-game-sessions
This commit is contained in:
2025-06-08 01:32:14 +02:00
committed by GitHub
8 changed files with 101 additions and 21 deletions

2
.gitignore vendored
View File

@@ -1,5 +1,3 @@
increment_build_number.sh
# Do not remove or rename entries in this file, only add new ones # Do not remove or rename entries in this file, only add new ones
# See https://github.com/flutter/flutter/issues/128635 for more context. # See https://github.com/flutter/flutter/issues/128635 for more context.

View File

@@ -0,0 +1,2 @@
build_number=$(awk -F'+' '/version:/ {print $2}' pubspec.yaml); build_number=${build_number:-0};
sed -i '' -E "s/(version: [0-9]+\.[0-9]+\.[0-9]\+)[0-9]*/\1$((build_number + 1))/" pubspec.yaml

View File

@@ -215,7 +215,7 @@
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
BuildIndependentTargetsInParallel = YES; BuildIndependentTargetsInParallel = YES;
LastUpgradeCheck = 1620; LastUpgradeCheck = 1510;
ORGANIZATIONNAME = ""; ORGANIZATIONNAME = "";
TargetAttributes = { TargetAttributes = {
331C8080294A63A400263BE5 = { 331C8080294A63A400263BE5 = {

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1620" LastUpgradeVersion = "1510"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View File

@@ -169,4 +169,17 @@ class LocalStorageService {
return false; return false;
} }
} }
static Future<bool> deleteAllGames() async {
try {
Globals.gameList.clear();
await saveGameSessions();
logger.i('Alle Runden wurden erfolgreich gelöscht.');
return true;
} catch (e) {
logger.e('Fehler beim Löschen aller Runden: $e',
error: 'Löschen fehlgeschlagen');
return false;
}
}
} }

View File

@@ -289,7 +289,9 @@ class _CreateGameState extends State<CreateGame> {
caboPenalty: Globals.caboPenalty, caboPenalty: Globals.caboPenalty,
isPointsLimitEnabled: selectedMode!, isPointsLimitEnabled: selectedMode!,
); );
setState(() {
Globals.addGameSession(gameSession); Globals.addGameSession(gameSession);
});
LocalStorageService.saveGameSessions(); LocalStorageService.saveGameSessions();
if (context.mounted) { if (context.mounted) {
Navigator.pushReplacement( Navigator.pushReplacement(

View File

@@ -45,19 +45,16 @@ class _MainMenuViewState extends State<MainMenuView> {
), ),
); );
}, },
icon: const Icon( icon: const Icon(CupertinoIcons.settings, size: 30)),
CupertinoIcons.settings,
size: 30,
)),
middle: const Text('Cabo Counter'), middle: const Text('Cabo Counter'),
trailing: IconButton( trailing: IconButton(
onPressed: () { onPressed: () => {
Navigator.push( Navigator.push(
context, context,
CupertinoPageRoute( CupertinoPageRoute(
builder: (context) => const CreateGame(), builder: (context) => const CreateGame(),
), ),
); )
}, },
icon: const Icon(CupertinoIcons.add)), icon: const Icon(CupertinoIcons.add)),
), ),
@@ -95,7 +92,30 @@ class _MainMenuViewState extends State<MainMenuView> {
itemCount: Globals.gameList.length, itemCount: Globals.gameList.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final session = Globals.gameList[index]; final session = Globals.gameList[index];
return Padding( return Dismissible(
key: Key(session.gameTitle),
background: Container(
color: CupertinoColors.destructiveRed,
alignment: Alignment.centerLeft,
padding: const EdgeInsets.only(left: 20.0),
child: const Icon(
CupertinoIcons.delete,
color: CupertinoColors.white,
),
),
direction: DismissDirection.startToEnd,
confirmDismiss: (direction) async {
final String gameTitle =
Globals.gameList[index].gameTitle;
return await _showDeleteGamePopup(gameTitle);
},
onDismissed: (direction) {
_deleteSpecificGame(index);
},
dismissThresholds: const {
DismissDirection.startToEnd: 0.6
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0), padding: const EdgeInsets.symmetric(vertical: 10.0),
child: CupertinoListTile( child: CupertinoListTile(
title: Text(session.gameTitle), title: Text(session.gameTitle),
@@ -131,15 +151,60 @@ class _MainMenuViewState extends State<MainMenuView> {
); );
setState(() {}); setState(() {});
}, },
)); ),
}), ),
);
},
),
), ),
), ),
); );
} }
/// Translates the game mode boolean into the corresponding String.
/// If [pointLimit] is true, it returns '101 Punkte', otherwise it returns 'Unbegrenzt'.
String _translateGameMode(bool pointLimit) { String _translateGameMode(bool pointLimit) {
if (pointLimit) return '101 Punkte'; if (pointLimit) return '101 Punkte';
return 'Unbegrenzt'; return 'Unbegrenzt';
} }
/// Shows a confirmation dialog to delete all game sessions.
/// Returns true if the user confirms the deletion, false otherwise.
///
Future<bool> _showDeleteGamePopup(String gameTitle) async {
bool? shouldDelete = await showCupertinoDialog<bool>(
context: context,
builder: (context) {
return CupertinoAlertDialog(
title: const Text('Spiel löschen?'),
content: Text(
'Bist du sicher, dass du die Runde "$gameTitle" löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.'),
actions: [
CupertinoDialogAction(
onPressed: () {
Navigator.pop(context, false);
},
child: const Text('Abbrechen'),
),
CupertinoDialogAction(
onPressed: () {
Navigator.pop(context, true);
},
child: const Text('Löschen'),
),
],
);
},
) ??
false;
return shouldDelete;
}
/// Deletes a specific game session by its index.
/// This function takes an [index] as parameter and removes the game session at
/// that index from the global game list,
void _deleteSpecificGame(int index) {
Globals.gameList.removeAt(index);
LocalStorageService.saveGameSessions();
}
} }

View File

@@ -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.1.6-alpha+145 version: 0.1.6+145
environment: environment:
sdk: ^3.5.4 sdk: ^3.5.4