Implemented save & load method

This commit is contained in:
Felix Kirchner
2025-04-30 17:17:01 +02:00
parent 8fed846eac
commit 11f87bc198
5 changed files with 140 additions and 93 deletions

View File

@@ -52,8 +52,8 @@
</TestAction> </TestAction>
<LaunchAction <LaunchAction
buildConfiguration = "Release" buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
launchStyle = "0" launchStyle = "0"
useCustomWorkingDirectory = "NO" useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO" ignoresPersistentStateOnLaunch = "NO"

View File

@@ -1,10 +1,45 @@
import 'package:cabo_counter/data/game_session.dart'; import 'package:cabo_counter/utility/apptheme.dart';
import 'package:cabo_counter/utility/globals.dart'; import 'package:cabo_counter/utility/local_storage_service.dart';
import 'package:cabo_counter/utility/theme.dart';
import 'package:cabo_counter/views/main_menu_view.dart'; import 'package:cabo_counter/views/main_menu_view.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
void main() { void main() {
/// FIXME Just for Debugging
/// Fills the game list with some test data.
/*Globals.addGameSession(GameSession(
gameTitle: 'Spiel am 27.02.2025',
players: ['Clara', 'Tobias', 'Yannik', 'Lena', 'Lekaia'],
gameHasPointLimit: true));
Globals.addGameSession(GameSession(
gameTitle: 'Freundschaftsrunde',
players: ['Felix', 'Jonas', 'Nils'],
gameHasPointLimit: false));
Globals.addGameSession(GameSession(
gameTitle: 'Familienabend',
players: ['Mama', 'Papa', 'Lisa'],
gameHasPointLimit: true,
));
Globals.addGameSession(GameSession(
gameTitle: 'Turnier 1. Runde',
players: ['Tim', 'Max', 'Sophie', 'Lena'],
gameHasPointLimit: false));
Globals.addGameSession(GameSession(
gameTitle: '2 Namen max length',
players: ['Heinrich', 'Johannes'],
gameHasPointLimit: true));
Globals.addGameSession(GameSession(
gameTitle: '3 Namen max length',
players: ['Benjamin', 'Stefanie', 'Wolfgang'],
gameHasPointLimit: false));
Globals.addGameSession(GameSession(
gameTitle: '4 Namen max length',
players: ['Leonhard', 'Mathilde', 'Bernhard', 'Gerlinde'],
gameHasPointLimit: true));
Globals.addGameSession(GameSession(
gameTitle: '5 Namen max length',
players: ['Hartmuth', 'Elisabet', 'Rosalind', 'Theresia', 'Karoline'],
gameHasPointLimit: false));
*/
runApp(const App()); runApp(const App());
} }
@@ -13,13 +48,15 @@ class App extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
LocalStorageService.loadGameSessions();
return CupertinoApp( return CupertinoApp(
theme: CupertinoThemeData( theme: CupertinoThemeData(
brightness: Brightness.dark, brightness: Brightness.dark,
primaryColor: Theme.primaryColor, primaryColor: AppTheme.primaryColor,
scaffoldBackgroundColor: Theme.backgroundColor, scaffoldBackgroundColor: AppTheme.backgroundColor,
textTheme: CupertinoTextThemeData( textTheme: CupertinoTextThemeData(
primaryColor: Theme.primaryColor, primaryColor: AppTheme.primaryColor,
), ),
), ),
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
@@ -28,41 +65,7 @@ class App extends StatelessWidget {
); );
} }
/// FIXME Just for Debugging dispose() {
/// Fills the game list with some test data. LocalStorageService.saveGameSessions();
void fillGameList() {
Globals.addGameSession(GameSession(
gameTitle: 'Spiel am 27.02.2025',
players: ['Clara', 'Tobias', 'Yannik', 'Lena', 'Lekaia'],
gameHasPointLimit: true));
Globals.addGameSession(GameSession(
gameTitle: 'Freundschaftsrunde',
players: ['Felix', 'Jonas', 'Nils'],
gameHasPointLimit: false));
Globals.addGameSession(GameSession(
gameTitle: 'Familienabend',
players: ['Mama', 'Papa', 'Lisa'],
gameHasPointLimit: true,
));
Globals.addGameSession(GameSession(
gameTitle: 'Turnier 1. Runde',
players: ['Tim', 'Max', 'Sophie', 'Lena'],
gameHasPointLimit: false));
Globals.addGameSession(GameSession(
gameTitle: '2 Namen max length',
players: ['Heinrich', 'Johannes'],
gameHasPointLimit: true));
Globals.addGameSession(GameSession(
gameTitle: '3 Namen max length',
players: ['Benjamin', 'Stefanie', 'Wolfgang'],
gameHasPointLimit: false));
Globals.addGameSession(GameSession(
gameTitle: '4 Namen max length',
players: ['Leonhard', 'Mathilde', 'Bernhard', 'Gerlinde'],
gameHasPointLimit: true));
Globals.addGameSession(GameSession(
gameTitle: '5 Namen max length',
players: ['Hartmuth', 'Elisabet', 'Rosalind', 'Theresia', 'Karoline'],
gameHasPointLimit: false));
} }
} }

View File

@@ -1,4 +1,6 @@
import 'package:cabo_counter/utility/apptheme.dart';
import 'package:cabo_counter/utility/globals.dart'; import 'package:cabo_counter/utility/globals.dart';
import 'package:cabo_counter/utility/local_storage_service.dart';
import 'package:cabo_counter/views/active_game_view.dart'; import 'package:cabo_counter/views/active_game_view.dart';
import 'package:cabo_counter/views/create_game_view.dart'; import 'package:cabo_counter/views/create_game_view.dart';
import 'package:cabo_counter/views/information_view.dart'; import 'package:cabo_counter/views/information_view.dart';
@@ -14,9 +16,19 @@ class MainMenuView extends StatefulWidget {
} }
class _MainMenuViewState extends State<MainMenuView> { class _MainMenuViewState extends State<MainMenuView> {
@override
initState() {
super.initState();
LocalStorageService.loadGameSessions().then((_) {
setState(() {});
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
LocalStorageService.loadGameSessions();
return CupertinoPageScaffold( return CupertinoPageScaffold(
resizeToAvoidBottomInset: false,
navigationBar: CupertinoNavigationBar( navigationBar: CupertinoNavigationBar(
leading: IconButton( leading: IconButton(
onPressed: () { onPressed: () {
@@ -45,49 +57,74 @@ class _MainMenuViewState extends State<MainMenuView> {
), ),
child: CupertinoPageScaffold( child: CupertinoPageScaffold(
child: SafeArea( child: SafeArea(
child: ListView.builder( child: Globals.gameList.isEmpty
itemCount: Globals.gameList.length, ? Column(
itemBuilder: (context, index) { mainAxisAlignment:
final session = Globals.gameList[index]; MainAxisAlignment.center, // Oben ausrichten
return Padding( children: [
padding: const EdgeInsets.symmetric(vertical: 10.0), const SizedBox(height: 30), // Abstand von oben
child: CupertinoListTile( Center(
title: Text(session.gameTitle), child: GestureDetector(
subtitle: session.isGameFinished == true onTap: () => setState(() {}),
? Text( child: Icon(
'\u{1F947} ${session.winner}', CupertinoIcons.plus,
style: const TextStyle(fontSize: 14), size: 60,
) color: AppTheme.primaryColor,
: Text( ),
'Modus: ${_translateGameMode(session.gameHasPointLimit)}', )),
style: const TextStyle(fontSize: 14), const SizedBox(height: 10), // Abstand von oben
), const Padding(
trailing: Row( padding: EdgeInsets.symmetric(horizontal: 70),
children: [ child: Text(
Text('${session.roundNumber}'), 'Ganz schön leer hier...\nFüge über den Button oben rechts eine neue Runde hinzu.',
const SizedBox(width: 3), textAlign: TextAlign.center,
const Icon( style: TextStyle(fontSize: 16),
CupertinoIcons.arrow_2_circlepath_circle_fill), ),
const SizedBox(width: 15),
Text('${session.players.length}'),
const SizedBox(width: 3),
const Icon(CupertinoIcons.person_2_fill),
],
), ),
onTap: () async { ],
//ignore: unused_local_variable )
final val = await Navigator.push( : ListView.builder(
context, itemCount: Globals.gameList.length,
CupertinoPageRoute( itemBuilder: (context, index) {
builder: (context) => ActiveGameView( final session = Globals.gameList[index];
gameSession: Globals.gameList[index]), return Padding(
), padding: const EdgeInsets.symmetric(vertical: 10.0),
); child: CupertinoListTile(
setState(() {}); title: Text(session.gameTitle),
}, subtitle: session.isGameFinished == true
)); ? Text(
}, '\u{1F947} ${session.winner}',
), style: const TextStyle(fontSize: 14),
)
: Text(
'Modus: ${_translateGameMode(session.gameHasPointLimit)}',
style: const TextStyle(fontSize: 14),
),
trailing: Row(
children: [
Text('${session.roundNumber}'),
const SizedBox(width: 3),
const Icon(CupertinoIcons
.arrow_2_circlepath_circle_fill),
const SizedBox(width: 15),
Text('${session.players.length}'),
const SizedBox(width: 3),
const Icon(CupertinoIcons.person_2_fill),
],
),
onTap: () async {
//ignore: unused_local_variable
final val = await Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => ActiveGameView(
gameSession: Globals.gameList[index]),
),
);
setState(() {});
},
));
}),
), ),
), ),
); );

View File

@@ -1,5 +1,6 @@
import 'package:cabo_counter/data/game_session.dart'; import 'package:cabo_counter/data/game_session.dart';
import 'package:cabo_counter/utility/theme.dart'; import 'package:cabo_counter/utility/apptheme.dart';
import 'package:cabo_counter/utility/local_storage_service.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
@@ -71,7 +72,10 @@ class _RoundViewState extends State<RoundView> {
previousPageTitle: 'Übersicht', previousPageTitle: 'Übersicht',
leading: CupertinoButton( leading: CupertinoButton(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
onPressed: () => Navigator.pop(context, widget.gameSession), onPressed: () => {
LocalStorageService.saveGameSessions(),
Navigator.pop(context, widget.gameSession)
},
child: const Text('Abbrechen'), child: const Text('Abbrechen'),
), ),
), ),
@@ -86,7 +90,7 @@ class _RoundViewState extends State<RoundView> {
children: [ children: [
const SizedBox(height: 40), const SizedBox(height: 40),
Text('Runde ${widget.roundNumber}', Text('Runde ${widget.roundNumber}',
style: Theme.roundTitle), style: AppTheme.roundTitle),
const SizedBox(height: 10), const SizedBox(height: 10),
const Text( const Text(
'Wer hat CABO gesagt?', 'Wer hat CABO gesagt?',
@@ -101,8 +105,8 @@ class _RoundViewState extends State<RoundView> {
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: CupertinoSegmentedControl<int>( child: CupertinoSegmentedControl<int>(
unselectedColor: Theme.backgroundTintColor, unselectedColor: AppTheme.backgroundTintColor,
selectedColor: Theme.primaryColor, selectedColor: AppTheme.primaryColor,
groupValue: _caboPlayerIndex, groupValue: _caboPlayerIndex,
children: Map.fromEntries(widget.gameSession.players children: Map.fromEntries(widget.gameSession.players
.asMap() .asMap()
@@ -267,7 +271,7 @@ class _RoundViewState extends State<RoundView> {
return Container( return Container(
height: 80, height: 80,
padding: const EdgeInsets.only(bottom: 20), padding: const EdgeInsets.only(bottom: 20),
color: Theme.backgroundTintColor, color: AppTheme.backgroundTintColor,
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
@@ -275,6 +279,7 @@ class _RoundViewState extends State<RoundView> {
onPressed: _areRoundInputsValid() onPressed: _areRoundInputsValid()
? () { ? () {
_finishRound(); _finishRound();
LocalStorageService.saveGameSessions();
Navigator.pop(context, widget.gameSession); Navigator.pop(context, widget.gameSession);
} }
: null, : null,
@@ -284,6 +289,7 @@ class _RoundViewState extends State<RoundView> {
onPressed: _areRoundInputsValid() onPressed: _areRoundInputsValid()
? () { ? () {
_finishRound(); _finishRound();
LocalStorageService.saveGameSessions();
if (widget.gameSession.isGameFinished == true) { if (widget.gameSession.isGameFinished == true) {
Navigator.pop(context, widget.gameSession); Navigator.pop(context, widget.gameSession);
} else { } else {

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.3+65 version: 0.1.3+101
environment: environment:
sdk: ^3.5.4 sdk: ^3.5.4
@@ -15,6 +15,7 @@ dependencies:
url_launcher: any url_launcher: any
package_info_plus: any package_info_plus: any
flutter_keyboard_visibility: ^6.0.0 flutter_keyboard_visibility: ^6.0.0
path_provider: ^2.1.1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: