From 34207997f62db9560a9a1570b2278601f836edc8 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Wed, 9 Jul 2025 14:15:36 +0200 Subject: [PATCH 01/19] Tried new design for im- and export-button --- lib/views/settings_view.dart | 39 ++++++++++++++++++++++++++++++++++-- pubspec.yaml | 2 +- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/lib/views/settings_view.dart b/lib/views/settings_view.dart index 2e86122..8185d8a 100644 --- a/lib/views/settings_view.dart +++ b/lib/views/settings_view.dart @@ -107,7 +107,7 @@ class _SettingsViewState extends State { style: CustomTheme.rowTitle, ), ), - Padding( + /*Padding( padding: const EdgeInsets.only(top: 30), child: Center( heightFactor: 1, @@ -163,7 +163,42 @@ class _SettingsViewState extends State { ), ], )), - ) + ),*/ + Padding( + padding: const EdgeInsets.fromLTRB(10, 15, 10, 0), + child: CupertinoFormSection.insetGrouped( + backgroundColor: CustomTheme.backgroundColor, + margin: EdgeInsets.zero, + children: [ + CupertinoFormRow( + prefix: Row( + children: [ + Icon( + CupertinoIcons.square_arrow_up, + color: CustomTheme.primaryColor, + ), + const SizedBox(width: 10), + const Text('Spieldaten exportieren'), + ], + ), + padding: const EdgeInsets.symmetric( + vertical: 10, horizontal: 15), + child: const CupertinoListTileChevron()), + CupertinoFormRow( + prefix: Row( + children: [ + Icon( + CupertinoIcons.square_arrow_down, + color: CustomTheme.primaryColor, + ), + const SizedBox(width: 10), + const Text('Spieldaten importieren'), + ], + ), + padding: const EdgeInsets.symmetric( + vertical: 10, horizontal: 15), + child: const CupertinoListTileChevron()) + ])), ], ), Positioned( diff --git a/pubspec.yaml b/pubspec.yaml index 562b189..9b8aaa4 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.9+331 +version: 0.3.9+333 environment: sdk: ^3.5.4 From 1bae1be93b7d6e5957f4c6502210537ea596baea Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Wed, 9 Jul 2025 14:17:54 +0200 Subject: [PATCH 02/19] Moved views to presentation folder --- lib/main.dart | 2 +- lib/{ => presentation}/views/active_game_view.dart | 6 +++--- lib/{ => presentation}/views/create_game_view.dart | 4 ++-- lib/{ => presentation}/views/graph_view.dart | 0 lib/{ => presentation}/views/information_view.dart | 0 lib/{ => presentation}/views/main_menu_view.dart | 6 +++--- lib/{ => presentation}/views/mode_selection_view.dart | 0 lib/{ => presentation}/views/round_view.dart | 0 lib/{ => presentation}/views/settings_view.dart | 0 lib/{ => presentation}/views/tab_view.dart | 4 ++-- 10 files changed, 11 insertions(+), 11 deletions(-) rename lib/{ => presentation}/views/active_game_view.dart (98%) rename lib/{ => presentation}/views/create_game_view.dart (98%) rename lib/{ => presentation}/views/graph_view.dart (100%) rename lib/{ => presentation}/views/information_view.dart (100%) rename lib/{ => presentation}/views/main_menu_view.dart (98%) rename lib/{ => presentation}/views/mode_selection_view.dart (100%) rename lib/{ => presentation}/views/round_view.dart (100%) rename lib/{ => presentation}/views/settings_view.dart (100%) rename lib/{ => presentation}/views/tab_view.dart (90%) diff --git a/lib/main.dart b/lib/main.dart index cd3d05f..06e2d2b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,8 +1,8 @@ import 'package:cabo_counter/l10n/app_localizations.dart'; +import 'package:cabo_counter/presentation/views/tab_view.dart'; import 'package:cabo_counter/services/config_service.dart'; import 'package:cabo_counter/services/local_storage_service.dart'; import 'package:cabo_counter/utility/custom_theme.dart'; -import 'package:cabo_counter/views/tab_view.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/services.dart'; diff --git a/lib/views/active_game_view.dart b/lib/presentation/views/active_game_view.dart similarity index 98% rename from lib/views/active_game_view.dart rename to lib/presentation/views/active_game_view.dart index 5945a3e..ddc0299 100644 --- a/lib/views/active_game_view.dart +++ b/lib/presentation/views/active_game_view.dart @@ -1,11 +1,11 @@ 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/presentation/views/create_game_view.dart'; +import 'package:cabo_counter/presentation/views/graph_view.dart'; +import 'package:cabo_counter/presentation/views/round_view.dart'; import 'package:cabo_counter/services/local_storage_service.dart'; import 'package:cabo_counter/utility/custom_theme.dart'; -import 'package:cabo_counter/views/create_game_view.dart'; -import 'package:cabo_counter/views/graph_view.dart'; -import 'package:cabo_counter/views/round_view.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; diff --git a/lib/views/create_game_view.dart b/lib/presentation/views/create_game_view.dart similarity index 98% rename from lib/views/create_game_view.dart rename to lib/presentation/views/create_game_view.dart index f6099f4..2c04e74 100644 --- a/lib/views/create_game_view.dart +++ b/lib/presentation/views/create_game_view.dart @@ -1,10 +1,10 @@ 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/presentation/views/active_game_view.dart'; +import 'package:cabo_counter/presentation/views/mode_selection_view.dart'; import 'package:cabo_counter/services/config_service.dart'; import 'package:cabo_counter/utility/custom_theme.dart'; -import 'package:cabo_counter/views/active_game_view.dart'; -import 'package:cabo_counter/views/mode_selection_view.dart'; import 'package:flutter/cupertino.dart'; enum CreateStatus { diff --git a/lib/views/graph_view.dart b/lib/presentation/views/graph_view.dart similarity index 100% rename from lib/views/graph_view.dart rename to lib/presentation/views/graph_view.dart diff --git a/lib/views/information_view.dart b/lib/presentation/views/information_view.dart similarity index 100% rename from lib/views/information_view.dart rename to lib/presentation/views/information_view.dart diff --git a/lib/views/main_menu_view.dart b/lib/presentation/views/main_menu_view.dart similarity index 98% rename from lib/views/main_menu_view.dart rename to lib/presentation/views/main_menu_view.dart index e087cfc..230c4de 100644 --- a/lib/views/main_menu_view.dart +++ b/lib/presentation/views/main_menu_view.dart @@ -1,11 +1,11 @@ import 'package:cabo_counter/data/game_manager.dart'; import 'package:cabo_counter/l10n/app_localizations.dart'; +import 'package:cabo_counter/presentation/views/active_game_view.dart'; +import 'package:cabo_counter/presentation/views/create_game_view.dart'; +import 'package:cabo_counter/presentation/views/settings_view.dart'; import 'package:cabo_counter/services/config_service.dart'; import 'package:cabo_counter/services/local_storage_service.dart'; import 'package:cabo_counter/utility/custom_theme.dart'; -import 'package:cabo_counter/views/active_game_view.dart'; -import 'package:cabo_counter/views/create_game_view.dart'; -import 'package:cabo_counter/views/settings_view.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; diff --git a/lib/views/mode_selection_view.dart b/lib/presentation/views/mode_selection_view.dart similarity index 100% rename from lib/views/mode_selection_view.dart rename to lib/presentation/views/mode_selection_view.dart diff --git a/lib/views/round_view.dart b/lib/presentation/views/round_view.dart similarity index 100% rename from lib/views/round_view.dart rename to lib/presentation/views/round_view.dart diff --git a/lib/views/settings_view.dart b/lib/presentation/views/settings_view.dart similarity index 100% rename from lib/views/settings_view.dart rename to lib/presentation/views/settings_view.dart diff --git a/lib/views/tab_view.dart b/lib/presentation/views/tab_view.dart similarity index 90% rename from lib/views/tab_view.dart rename to lib/presentation/views/tab_view.dart index 4abd411..efa4311 100644 --- a/lib/views/tab_view.dart +++ b/lib/presentation/views/tab_view.dart @@ -1,7 +1,7 @@ import 'package:cabo_counter/l10n/app_localizations.dart'; +import 'package:cabo_counter/presentation/views/information_view.dart'; +import 'package:cabo_counter/presentation/views/main_menu_view.dart'; import 'package:cabo_counter/utility/custom_theme.dart'; -import 'package:cabo_counter/views/information_view.dart'; -import 'package:cabo_counter/views/main_menu_view.dart'; import 'package:flutter/cupertino.dart'; class TabView extends StatefulWidget { From ed8aced8a870426bdb50d5528c38912f33f450bb Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Wed, 9 Jul 2025 14:18:28 +0200 Subject: [PATCH 03/19] Moved widgets to presentation folder --- lib/presentation/views/settings_view.dart | 2 +- lib/{ => presentation}/widgets/stepper.dart | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename lib/{ => presentation}/widgets/stepper.dart (100%) diff --git a/lib/presentation/views/settings_view.dart b/lib/presentation/views/settings_view.dart index 8185d8a..7875890 100644 --- a/lib/presentation/views/settings_view.dart +++ b/lib/presentation/views/settings_view.dart @@ -1,9 +1,9 @@ import 'package:cabo_counter/l10n/app_localizations.dart'; +import 'package:cabo_counter/presentation/widgets/stepper.dart'; import 'package:cabo_counter/services/config_service.dart'; import 'package:cabo_counter/services/local_storage_service.dart'; import 'package:cabo_counter/utility/custom_theme.dart'; import 'package:cabo_counter/utility/globals.dart'; -import 'package:cabo_counter/widgets/stepper.dart'; import 'package:flutter/cupertino.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:url_launcher/url_launcher.dart'; diff --git a/lib/widgets/stepper.dart b/lib/presentation/widgets/stepper.dart similarity index 100% rename from lib/widgets/stepper.dart rename to lib/presentation/widgets/stepper.dart From 0c774366594d944e2250fd35ae3585fd1a04ec29 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Wed, 9 Jul 2025 15:20:05 +0200 Subject: [PATCH 04/19] Implemented CustomRowForm Widget --- lib/presentation/widgets/custom_form_row.dart | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 lib/presentation/widgets/custom_form_row.dart diff --git a/lib/presentation/widgets/custom_form_row.dart b/lib/presentation/widgets/custom_form_row.dart new file mode 100644 index 0000000..61d0fdb --- /dev/null +++ b/lib/presentation/widgets/custom_form_row.dart @@ -0,0 +1,49 @@ +import 'package:cabo_counter/utility/custom_theme.dart'; +import 'package:flutter/cupertino.dart'; + +class CustomFormRow extends StatefulWidget { + final String prefixText; + final IconData prefixIcon; + final Widget? suffixWidget; + final void Function()? onTap; + const CustomFormRow({ + super.key, + required this.prefixText, + required this.prefixIcon, + required this.onTap, + this.suffixWidget, + }); + + @override + State createState() => _CustomFormRowState(); +} + +class _CustomFormRowState extends State { + late Widget suffixWidget; + @override + void initState() { + super.initState(); + suffixWidget = widget.suffixWidget ?? const SizedBox.shrink(); + } + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: widget.onTap, + child: CupertinoFormRow( + prefix: Row( + children: [ + Icon( + widget.prefixIcon, + color: CustomTheme.primaryColor, + ), + const SizedBox(width: 10), + Text(widget.prefixText), + ], + ), + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 15), + child: suffixWidget, + ), + ); + } +} From 7fa95f4bcaf7c27438955dd413b37cc366de4c09 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Wed, 9 Jul 2025 15:20:28 +0200 Subject: [PATCH 05/19] Used new custom form row --- lib/presentation/views/settings_view.dart | 106 +++++----------------- pubspec.yaml | 2 +- 2 files changed, 22 insertions(+), 86 deletions(-) diff --git a/lib/presentation/views/settings_view.dart b/lib/presentation/views/settings_view.dart index 7875890..4c44e1b 100644 --- a/lib/presentation/views/settings_view.dart +++ b/lib/presentation/views/settings_view.dart @@ -1,10 +1,12 @@ import 'package:cabo_counter/l10n/app_localizations.dart'; +import 'package:cabo_counter/presentation/widgets/custom_form_row.dart'; import 'package:cabo_counter/presentation/widgets/stepper.dart'; import 'package:cabo_counter/services/config_service.dart'; import 'package:cabo_counter/services/local_storage_service.dart'; import 'package:cabo_counter/utility/custom_theme.dart'; import 'package:cabo_counter/utility/globals.dart'; import 'package:flutter/cupertino.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -107,97 +109,31 @@ class _SettingsViewState extends State { style: CustomTheme.rowTitle, ), ), - /*Padding( - padding: const EdgeInsets.only(top: 30), - child: Center( - heightFactor: 1, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - CupertinoButton( - color: CustomTheme.primaryColor, - sizeStyle: CupertinoButtonSize.medium, - child: Text( - AppLocalizations.of(context).import_data, - style: - TextStyle(color: CustomTheme.backgroundColor), - ), - onPressed: () async { - final success = - await LocalStorageService.importJsonFile(); - showFeedbackDialog(success); - }), - const SizedBox( - width: 20, - ), - CupertinoButton( - color: CustomTheme.primaryColor, - sizeStyle: CupertinoButtonSize.medium, - child: Text( - AppLocalizations.of(context).export_data, - style: - TextStyle(color: CustomTheme.backgroundColor), - ), - onPressed: () async { - final success = - await LocalStorageService.exportGameData(); - if (!success && context.mounted) { - showCupertinoDialog( - context: context, - builder: (context) => CupertinoAlertDialog( - title: Text(AppLocalizations.of(context) - .export_error_title), - content: Text(AppLocalizations.of(context) - .export_error_message), - actions: [ - CupertinoDialogAction( - child: - Text(AppLocalizations.of(context).ok), - onPressed: () => Navigator.pop(context), - ), - ], - ), - ); - } - }, - ), - ], - )), - ),*/ Padding( padding: const EdgeInsets.fromLTRB(10, 15, 10, 0), child: CupertinoFormSection.insetGrouped( backgroundColor: CustomTheme.backgroundColor, margin: EdgeInsets.zero, children: [ - CupertinoFormRow( - prefix: Row( - children: [ - Icon( - CupertinoIcons.square_arrow_up, - color: CustomTheme.primaryColor, - ), - const SizedBox(width: 10), - const Text('Spieldaten exportieren'), - ], - ), - padding: const EdgeInsets.symmetric( - vertical: 10, horizontal: 15), - child: const CupertinoListTileChevron()), - CupertinoFormRow( - prefix: Row( - children: [ - Icon( - CupertinoIcons.square_arrow_down, - color: CustomTheme.primaryColor, - ), - const SizedBox(width: 10), - const Text('Spieldaten importieren'), - ], - ), - padding: const EdgeInsets.symmetric( - vertical: 10, horizontal: 15), - child: const CupertinoListTileChevron()) + CustomFormRow( + prefixText: 'Spieldaten importieren', + prefixIcon: CupertinoIcons.square_arrow_down, + onTap: () {}, + suffixWidget: CupertinoListTileChevron(), + ), + CustomFormRow( + prefixText: 'Spieldaten exportieren', + prefixIcon: CupertinoIcons.square_arrow_up, + onTap: () {}, + suffixWidget: const CupertinoListTileChevron(), + ), + CustomFormRow( + prefixText: AppLocalizations.of(context).create_issue, + prefixIcon: FontAwesomeIcons.github, + onTap: () => launchUrl(Uri.parse( + 'https://github.com/flixcoo/Cabo-Counter/issues')), + suffixWidget: const CupertinoListTileChevron(), + ), ])), ], ), diff --git a/pubspec.yaml b/pubspec.yaml index 9b8aaa4..2bae78c 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.9+333 +version: 0.3.9+337 environment: sdk: ^3.5.4 From 2d34ebf35b71d52b9f1702e70668da5cc6aba869 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Wed, 9 Jul 2025 15:21:46 +0200 Subject: [PATCH 06/19] Removed double information --- lib/presentation/views/settings_view.dart | 60 +++++++++-------------- 1 file changed, 22 insertions(+), 38 deletions(-) diff --git a/lib/presentation/views/settings_view.dart b/lib/presentation/views/settings_view.dart index 4c44e1b..baaf24e 100644 --- a/lib/presentation/views/settings_view.dart +++ b/lib/presentation/views/settings_view.dart @@ -141,44 +141,28 @@ class _SettingsViewState extends State { bottom: 30, left: 0, right: 0, - child: Column( - children: [ - Center( - child: Text(AppLocalizations.of(context).error_found), - ), - Padding( - padding: const EdgeInsets.fromLTRB(0, 0, 0, 30), - child: Center( - child: CupertinoButton( - onPressed: () => launchUrl(Uri.parse( - 'https://github.com/flixcoo/Cabo-Counter/issues')), - child: Text(AppLocalizations.of(context).create_issue), - ), - ), - ), - FutureBuilder( - future: _getPackageInfo(), - builder: (context, snapshot) { - if (snapshot.hasData) { - return Text( - '${Globals.appDevPhase} ${snapshot.data!.version} ' - '(${AppLocalizations.of(context).build} ${snapshot.data!.buildNumber})', - textAlign: TextAlign.center, - ); - } else if (snapshot.hasError) { - return Text( - '${AppLocalizations.of(context).app_version} -.-.- (${AppLocalizations.of(context).build} -)', - textAlign: TextAlign.center, - ); - } - return Text( - AppLocalizations.of(context).load_version, - textAlign: TextAlign.center, - ); - }, - ) - ], - )), + child: Center( + child: FutureBuilder( + future: _getPackageInfo(), + builder: (context, snapshot) { + if (snapshot.hasData) { + return Text( + '${Globals.appDevPhase} ${snapshot.data!.version} ' + '(${AppLocalizations.of(context).build} ${snapshot.data!.buildNumber})', + textAlign: TextAlign.center, + ); + } else if (snapshot.hasError) { + return Text( + '${AppLocalizations.of(context).app_version} -.-.- (${AppLocalizations.of(context).build} -)', + textAlign: TextAlign.center, + ); + } + return Text( + AppLocalizations.of(context).load_version, + textAlign: TextAlign.center, + ); + }, + ))), ], )), ); From ee5ec4d0d99cdc3f5649c9273e3a153de560d459 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Wed, 9 Jul 2025 16:19:16 +0200 Subject: [PATCH 07/19] Refactored methods to private --- lib/services/local_storage_service.dart | 26 ++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/services/local_storage_service.dart b/lib/services/local_storage_service.dart index 12130a1..29ac58b 100644 --- a/lib/services/local_storage_service.dart +++ b/lib/services/local_storage_service.dart @@ -21,7 +21,7 @@ class LocalStorageService { static const String _fileName = 'game_data.json'; /// Writes the game session list to a JSON file and returns it as string. - static String getGameDataAsJsonFile() { + static String _getGameDataAsJsonFile() { final jsonFile = gameManager.gameList.map((session) => session.toJson()).toList(); return json.encode(jsonFile); @@ -39,7 +39,7 @@ class LocalStorageService { print('[local_storage_service.dart] Versuche, Daten zu speichern...'); try { final file = await _getFilePath(); - final jsonFile = getGameDataAsJsonFile(); + final jsonFile = _getGameDataAsJsonFile(); await file.writeAsString(jsonFile); print( '[local_storage_service.dart] Die Spieldaten wurden zwischengespeichert.'); @@ -70,7 +70,7 @@ class LocalStorageService { return false; } - if (!await validateJsonSchema(jsonString, true)) { + if (!await _validateJsonSchema(jsonString, true)) { print( '[local_storage_service.dart] Die Datei konnte nicht validiert werden'); gameManager.gameList = []; @@ -105,7 +105,7 @@ class LocalStorageService { /// Opens the file picker to export game data as a JSON file. /// This method will export the given [jsonString] as a JSON file. It opens /// the file picker with the choosen [fileName]. - static Future exportJsonData( + static Future _exportJsonData( String jsonString, String fileName, ) async { @@ -133,16 +133,16 @@ class LocalStorageService { /// Opens the file picker to export all game sessions as a JSON file. static Future exportGameData() async { - String jsonString = getGameDataAsJsonFile(); + String jsonString = _getGameDataAsJsonFile(); String fileName = 'cabo_counter-game_data'; - return exportJsonData(jsonString, fileName); + return _exportJsonData(jsonString, fileName); } /// Opens the file picker to save a single game session as a JSON file. static Future exportSingleGameSession(GameSession session) async { String jsonString = json.encode(session.toJson()); String fileName = 'cabo_counter-game_${session.id.substring(0, 7)}'; - return exportJsonData(jsonString, fileName); + return _exportJsonData(jsonString, fileName); } /// Opens the file picker to import a JSON file and loads the game data from it. @@ -162,7 +162,7 @@ class LocalStorageService { try { final jsonString = await _readFileContent(path.files.single); - if (await validateJsonSchema(jsonString, true)) { + if (await _validateJsonSchema(jsonString, true)) { // Checks if the JSON String is in the gameList format final jsonData = json.decode(jsonString) as List; @@ -172,12 +172,12 @@ class LocalStorageService { .toList(); for (GameSession s in importedList) { - importSession(s); + _importSession(s); } - } else if (await validateJsonSchema(jsonString, false)) { + } else if (await _validateJsonSchema(jsonString, false)) { // Checks if the JSON String is in the single game format final jsonData = json.decode(jsonString) as Map; - importSession(GameSession.fromJson(jsonData)); + _importSession(GameSession.fromJson(jsonData)); } else { return ImportStatus.validationError; } @@ -198,7 +198,7 @@ class LocalStorageService { } /// Imports a single game session into the gameList. - static Future importSession(GameSession session) async { + static Future _importSession(GameSession session) async { if (gameManager.gameExistsInGameList(session.id)) { print( '[local_storage_service.dart] Die Session mit der ID ${session.id} existiert bereits. Sie wird überschrieben.'); @@ -221,7 +221,7 @@ class LocalStorageService { /// This method checks if the provided [jsonString] is valid against the /// JSON schema. It takes a boolean [isGameList] to determine /// which schema to use (game list or single game). - static Future validateJsonSchema( + static Future _validateJsonSchema( String jsonString, bool isGameList) async { final String schemaString; From 249609276411d0399e57ca44a5c9c2e2ae1dde9f Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Wed, 9 Jul 2025 16:21:14 +0200 Subject: [PATCH 08/19] Changed label --- lib/l10n/app_de.arb | 6 +++--- lib/l10n/app_en.arb | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 9281ac1..632988c 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -82,9 +82,9 @@ "point_limit": "Punkte-Limit", "point_limit_subtitle": "... hier ist Schluss", "reset_to_default": "Auf Standard zurücksetzen", - "game_data": "Spieldaten", - "import_data": "Daten importieren", - "export_data": "Daten exportieren", + "app": "App", + "import_data": "Spieldaten importieren", + "export_data": "Spieldaten exportieren", "import_success_title": "Import erfolgreich", "import_success_message":"Die Spieldaten wurden erfolgreich importiert.", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 8b328ba..1948270 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -78,7 +78,7 @@ "point_limit": "Point Limit", "point_limit_subtitle": "... the game ends here.", "reset_to_default": "Reset to Default", - "game_data": "Game Data", + "app": "App", "import_data": "Import Data", "export_data": "Export Data", "id_error_title": "ID Error", From 847e3dcd19b834e86d25aa6378fa064fed0a6bb2 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Wed, 9 Jul 2025 16:21:32 +0200 Subject: [PATCH 09/19] Modified paddings and text color --- lib/presentation/widgets/stepper.dart | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/presentation/widgets/stepper.dart b/lib/presentation/widgets/stepper.dart index 879235e..8ca2635 100644 --- a/lib/presentation/widgets/stepper.dart +++ b/lib/presentation/widgets/stepper.dart @@ -1,3 +1,4 @@ +import 'package:cabo_counter/utility/custom_theme.dart'; import 'package:flutter/cupertino.dart'; // Für iOS-Style class Stepper extends StatefulWidget { @@ -34,18 +35,20 @@ class _StepperState extends State { Widget build(BuildContext context) { return Row( mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.end, children: [ CupertinoButton( - padding: const EdgeInsets.all(8), + padding: EdgeInsets.zero, onPressed: _decrement, child: const Icon(CupertinoIcons.minus), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 12.0), - child: Text('$_value', style: const TextStyle(fontSize: 18)), + child: Text('$_value', + style: TextStyle(fontSize: 18, color: CustomTheme.white)), ), CupertinoButton( - padding: const EdgeInsets.all(8), + padding: EdgeInsets.zero, onPressed: _increment, child: const Icon(CupertinoIcons.add), ), From 21920d2ac4807e6f40ce4842bb024e74e0741b5f Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Wed, 9 Jul 2025 17:14:20 +0200 Subject: [PATCH 10/19] Changed string --- lib/l10n/app_de.arb | 5 +++-- lib/l10n/app_en.arb | 13 +++++++------ lib/l10n/app_localizations.dart | 22 ++++++++++++++-------- lib/l10n/app_localizations_de.dart | 11 +++++++---- lib/l10n/app_localizations_en.dart | 7 +++++-- 5 files changed, 36 insertions(+), 22 deletions(-) diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 632988c..b83c646 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -82,9 +82,10 @@ "point_limit": "Punkte-Limit", "point_limit_subtitle": "... hier ist Schluss", "reset_to_default": "Auf Standard zurücksetzen", - "app": "App", + "data": "Daten", "import_data": "Spieldaten importieren", "export_data": "Spieldaten exportieren", + "app": "App", "import_success_title": "Import erfolgreich", "import_success_message":"Die Spieldaten wurden erfolgreich importiert.", @@ -101,7 +102,7 @@ "create_issue": "Issue erstellen", "app_version": "App-Version", "build": "Build", - "load_version": "Lade Version...", + "loading": "Lädt...", "about_text": "Hey :) Danke, dass du als eine:r der ersten User meiner ersten eigenen App dabei bist! Ich hab sehr viel Arbeit in dieses Projekt gesteckt und auch, wenn ich (hoffentlich) an vieles Gedacht hab, wird auf jeden Fall noch nicht alles 100% funktionieren. Solltest du also irgendwelche Fehler entdecken oder Feedback zum Design oder der Benutzerfreundlichkeit haben, teile Sie mir gern über die Testflight App oder auf den dir bekannten Wegen mit. Danke! " } \ No newline at end of file diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 1948270..1c111e2 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -71,6 +71,10 @@ "export_game": "Export Game", "game_process": "Spielverlauf", + "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.", + "end_game_title": "End the game?", + "end_game_message": "Do you want to end the game? The game gets marked as finished and cannot be continued.", "settings": "Settings", "cabo_penalty": "Cabo Penalty", @@ -78,13 +82,10 @@ "point_limit": "Point Limit", "point_limit_subtitle": "... the game ends here.", "reset_to_default": "Reset to Default", - "app": "App", + "data": "Data", "import_data": "Import Data", "export_data": "Export Data", - "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.", - "end_game_title": "End the game?", - "end_game_message": "Do you want to end the game? The game gets marked as finished and cannot be continued.", + "app": "App", "import_success_title": "Import successful", "import_success_message":"The game data has been successfully imported.", @@ -100,7 +101,7 @@ "error_found": "Found a bug?", "create_issue": "Create Issue", "app_version": "App Version", - "load_version": "Loading version...", + "loading": "Loading...", "build": "Build", "about_text": "Hey :) Thanks for being one of the first users of my app! I’ve put a lot of work into this project, and even though I tried to think of everything, it might not work perfectly just yet. So if you discover any bugs or have feedback on the design or usability, please let me know via the TestFlight app or by sending me a message or email. Thank you very much!" diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index c836194..84295df 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -458,24 +458,30 @@ abstract class AppLocalizations { /// **'Auf Standard zurücksetzen'** String get reset_to_default; - /// No description provided for @game_data. + /// No description provided for @data. /// /// In de, this message translates to: - /// **'Spieldaten'** - String get game_data; + /// **'Daten'** + String get data; /// No description provided for @import_data. /// /// In de, this message translates to: - /// **'Daten importieren'** + /// **'Spieldaten importieren'** String get import_data; /// No description provided for @export_data. /// /// In de, this message translates to: - /// **'Daten exportieren'** + /// **'Spieldaten exportieren'** String get export_data; + /// No description provided for @app. + /// + /// In de, this message translates to: + /// **'App'** + String get app; + /// No description provided for @import_success_title. /// /// In de, this message translates to: @@ -560,11 +566,11 @@ abstract class AppLocalizations { /// **'Build'** String get build; - /// No description provided for @load_version. + /// No description provided for @loading. /// /// In de, this message translates to: - /// **'Lade Version...'** - String get load_version; + /// **'Lädt...'** + String get loading; /// No description provided for @about_text. /// diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index 5b9d841..f4a2bbd 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -200,13 +200,16 @@ class AppLocalizationsDe extends AppLocalizations { String get reset_to_default => 'Auf Standard zurücksetzen'; @override - String get game_data => 'Spieldaten'; + String get data => 'Daten'; @override - String get import_data => 'Daten importieren'; + String get import_data => 'Spieldaten importieren'; @override - String get export_data => 'Daten exportieren'; + String get export_data => 'Spieldaten exportieren'; + + @override + String get app => 'App'; @override String get import_success_title => 'Import erfolgreich'; @@ -254,7 +257,7 @@ class AppLocalizationsDe extends AppLocalizations { String get build => 'Build'; @override - String get load_version => 'Lade Version...'; + String get loading => 'Lädt...'; @override String get about_text => diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index c98dddd..aac55f2 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -197,7 +197,7 @@ class AppLocalizationsEn extends AppLocalizations { String get reset_to_default => 'Reset to Default'; @override - String get game_data => 'Game Data'; + String get data => 'Data'; @override String get import_data => 'Import Data'; @@ -205,6 +205,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get export_data => 'Export Data'; + @override + String get app => 'App'; + @override String get import_success_title => 'Import successful'; @@ -251,7 +254,7 @@ class AppLocalizationsEn extends AppLocalizations { String get build => 'Build'; @override - String get load_version => 'Loading version...'; + String get loading => 'Loading...'; @override String get about_text => From 9bc80a8cd94e827576bc726d506b9319b5ba1220 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Wed, 9 Jul 2025 17:15:00 +0200 Subject: [PATCH 11/19] Updated CustomFormRow padding and pressed handler --- lib/presentation/widgets/custom_form_row.dart | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/presentation/widgets/custom_form_row.dart b/lib/presentation/widgets/custom_form_row.dart index 61d0fdb..f03b453 100644 --- a/lib/presentation/widgets/custom_form_row.dart +++ b/lib/presentation/widgets/custom_form_row.dart @@ -1,3 +1,4 @@ +import 'package:cabo_counter/presentation/widgets/stepper.dart'; import 'package:cabo_counter/utility/custom_theme.dart'; import 'package:flutter/cupertino.dart'; @@ -5,12 +6,12 @@ class CustomFormRow extends StatefulWidget { final String prefixText; final IconData prefixIcon; final Widget? suffixWidget; - final void Function()? onTap; + final void Function()? onPressed; const CustomFormRow({ super.key, required this.prefixText, required this.prefixIcon, - required this.onTap, + this.onPressed, this.suffixWidget, }); @@ -28,8 +29,9 @@ class _CustomFormRowState extends State { @override Widget build(BuildContext context) { - return GestureDetector( - onTap: widget.onTap, + return CupertinoButton( + padding: EdgeInsets.zero, + onPressed: widget.onPressed, child: CupertinoFormRow( prefix: Row( children: [ @@ -41,7 +43,9 @@ class _CustomFormRowState extends State { Text(widget.prefixText), ], ), - padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 15), + padding: suffixWidget is Stepper + ? const EdgeInsets.fromLTRB(15, 0, 0, 0) + : const EdgeInsets.symmetric(vertical: 10, horizontal: 15), child: suffixWidget, ), ); From 696ade5b9b1c60f52cda8aed76d21c708d0c6842 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Wed, 9 Jul 2025 17:15:30 +0200 Subject: [PATCH 12/19] Implemented various new forms of CustomFormRow into SettingsView --- lib/presentation/views/settings_view.dart | 234 +++++++++++++--------- pubspec.yaml | 2 +- 2 files changed, 139 insertions(+), 97 deletions(-) diff --git a/lib/presentation/views/settings_view.dart b/lib/presentation/views/settings_view.dart index baaf24e..34540a4 100644 --- a/lib/presentation/views/settings_view.dart +++ b/lib/presentation/views/settings_view.dart @@ -46,66 +46,89 @@ class _SettingsViewState extends State { ), ), Padding( - padding: const EdgeInsets.fromLTRB(15, 10, 10, 0), - child: CupertinoListTile( - padding: EdgeInsets.zero, - title: Text(AppLocalizations.of(context).cabo_penalty), - subtitle: Text( - AppLocalizations.of(context).cabo_penalty_subtitle), - trailing: Stepper( - key: _stepperKey1, - initialValue: ConfigService.caboPenalty, - minValue: 0, - maxValue: 50, - step: 1, - onChanged: (newCaboPenalty) { - setState(() { - ConfigService.setCaboPenalty(newCaboPenalty); - ConfigService.caboPenalty = newCaboPenalty; - }); - }, - ), - )), - Padding( - padding: const EdgeInsets.fromLTRB(15, 10, 10, 0), - child: CupertinoListTile( - padding: EdgeInsets.zero, - title: Text(AppLocalizations.of(context).point_limit), - subtitle: - Text(AppLocalizations.of(context).point_limit_subtitle), - trailing: Stepper( - key: _stepperKey2, - initialValue: ConfigService.pointLimit, - minValue: 30, - maxValue: 1000, - step: 10, - onChanged: (newPointLimit) { - setState(() { - ConfigService.setPointLimit(newPointLimit); - ConfigService.pointLimit = newPointLimit; - }); - }, - ), - )), - Padding( - padding: const EdgeInsets.fromLTRB(0, 10, 0, 0), - child: Center( - heightFactor: 0.9, - child: CupertinoButton( - padding: EdgeInsets.zero, - onPressed: () => setState(() { - ConfigService.resetConfig(); - _stepperKey1 = UniqueKey(); - _stepperKey2 = UniqueKey(); - }), - child: - Text(AppLocalizations.of(context).reset_to_default), - ), - )), + padding: const EdgeInsets.fromLTRB(10, 15, 10, 10), + child: CupertinoFormSection.insetGrouped( + backgroundColor: CustomTheme.backgroundColor, + margin: EdgeInsets.zero, + children: [ + CustomFormRow( + key: _stepperKey1, + prefixText: 'Cabo-Strafe', + prefixIcon: CupertinoIcons.minus_square, + suffixWidget: Stepper( + initialValue: ConfigService.caboPenalty, + minValue: 0, + maxValue: 50, + step: 1, + onChanged: (newCaboPenalty) { + setState(() { + ConfigService.setCaboPenalty(newCaboPenalty); + ConfigService.caboPenalty = newCaboPenalty; + }); + }, + ), + ), + CustomFormRow( + key: _stepperKey2, + prefixText: 'Punkte-Limit', + prefixIcon: FontAwesomeIcons.bullseye, + suffixWidget: Stepper( + initialValue: ConfigService.pointLimit, + minValue: 30, + maxValue: 1000, + step: 10, + onChanged: (newPointLimit) { + setState(() { + ConfigService.setPointLimit(newPointLimit); + ConfigService.pointLimit = newPointLimit; + }); + }, + ), + ), + CustomFormRow( + prefixText: + AppLocalizations.of(context).reset_to_default, + prefixIcon: CupertinoIcons.arrow_counterclockwise, + onPressed: () { + ConfigService.resetConfig(); + setState(() { + _stepperKey1 = UniqueKey(); + _stepperKey2 = UniqueKey(); + print('Config reset to default'); + }); + }, + ) + ])), Padding( padding: const EdgeInsets.fromLTRB(10, 10, 0, 0), child: Text( - AppLocalizations.of(context).game_data, + AppLocalizations.of(context).data, + style: CustomTheme.rowTitle, + ), + ), + Padding( + padding: const EdgeInsets.fromLTRB(10, 15, 10, 10), + child: CupertinoFormSection.insetGrouped( + backgroundColor: CustomTheme.backgroundColor, + margin: EdgeInsets.zero, + children: [ + CustomFormRow( + prefixText: AppLocalizations.of(context).import_data, + prefixIcon: CupertinoIcons.square_arrow_down, + onPressed: () => LocalStorageService.importJsonFile(), + suffixWidget: const CupertinoListTileChevron(), + ), + CustomFormRow( + prefixText: AppLocalizations.of(context).export_data, + prefixIcon: CupertinoIcons.square_arrow_up, + onPressed: () => LocalStorageService.importJsonFile(), + suffixWidget: const CupertinoListTileChevron(), + ), + ])), + Padding( + padding: const EdgeInsets.fromLTRB(10, 10, 0, 0), + child: Text( + AppLocalizations.of(context).app, style: CustomTheme.rowTitle, ), ), @@ -115,54 +138,73 @@ class _SettingsViewState extends State { backgroundColor: CustomTheme.backgroundColor, margin: EdgeInsets.zero, children: [ - CustomFormRow( - prefixText: 'Spieldaten importieren', - prefixIcon: CupertinoIcons.square_arrow_down, - onTap: () {}, - suffixWidget: CupertinoListTileChevron(), - ), - CustomFormRow( - prefixText: 'Spieldaten exportieren', - prefixIcon: CupertinoIcons.square_arrow_up, - onTap: () {}, - suffixWidget: const CupertinoListTileChevron(), - ), CustomFormRow( prefixText: AppLocalizations.of(context).create_issue, prefixIcon: FontAwesomeIcons.github, - onTap: () => launchUrl(Uri.parse( + onPressed: () => launchUrl(Uri.parse( 'https://github.com/flixcoo/Cabo-Counter/issues')), suffixWidget: const CupertinoListTileChevron(), ), + CustomFormRow( + prefixText: 'App-Version', + prefixIcon: CupertinoIcons.info, + onPressed: null, + suffixWidget: FutureBuilder( + future: _getPackageInfo(), + builder: (context, snapshot) { + if (snapshot.hasData) { + return Text( + '${Globals.appDevPhase} ${snapshot.data!.version} ', + style: TextStyle( + color: CustomTheme.primaryColor, + ), + ); + } else if (snapshot.hasError) { + return Text( + '${AppLocalizations.of(context).app_version} -.-.-', + style: TextStyle( + color: CustomTheme.primaryColor, + ), + ); + } + return Text( + AppLocalizations.of(context).loading, + style: TextStyle( + color: CustomTheme.primaryColor, + ), + ); + }, + )), + CustomFormRow( + prefixText: 'Build-Nr.', + prefixIcon: CupertinoIcons.info, + onPressed: null, + suffixWidget: FutureBuilder( + future: _getPackageInfo(), + builder: (context, snapshot) { + if (snapshot.hasData) { + return Text( + snapshot.data!.buildNumber, + style: TextStyle( + color: CustomTheme.primaryColor, + ), + ); + } else if (snapshot.hasError) { + return Text( + '-', + style: TextStyle( + color: CustomTheme.primaryColor, + ), + ); + } + return Text( + AppLocalizations.of(context).loading, + ); + }, + )), ])), ], ), - Positioned( - bottom: 30, - left: 0, - right: 0, - child: Center( - child: FutureBuilder( - future: _getPackageInfo(), - builder: (context, snapshot) { - if (snapshot.hasData) { - return Text( - '${Globals.appDevPhase} ${snapshot.data!.version} ' - '(${AppLocalizations.of(context).build} ${snapshot.data!.buildNumber})', - textAlign: TextAlign.center, - ); - } else if (snapshot.hasError) { - return Text( - '${AppLocalizations.of(context).app_version} -.-.- (${AppLocalizations.of(context).build} -)', - textAlign: TextAlign.center, - ); - } - return Text( - AppLocalizations.of(context).load_version, - textAlign: TextAlign.center, - ); - }, - ))), ], )), ); diff --git a/pubspec.yaml b/pubspec.yaml index 2bae78c..fdf9916 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.9+337 +version: 0.4.0+371 environment: sdk: ^3.5.4 From aba4bf9c0bd8b09a67e0f104145fa81e08d86e1a Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Wed, 9 Jul 2025 17:30:28 +0200 Subject: [PATCH 13/19] Implemented VersionService --- lib/main.dart | 2 + lib/presentation/views/settings_view.dart | 64 ++++------------------- lib/services/version_service.dart | 32 ++++++++++++ pubspec.yaml | 2 +- 4 files changed, 44 insertions(+), 56 deletions(-) create mode 100644 lib/services/version_service.dart diff --git a/lib/main.dart b/lib/main.dart index 06e2d2b..b826072 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,6 +2,7 @@ import 'package:cabo_counter/l10n/app_localizations.dart'; import 'package:cabo_counter/presentation/views/tab_view.dart'; import 'package:cabo_counter/services/config_service.dart'; import 'package:cabo_counter/services/local_storage_service.dart'; +import 'package:cabo_counter/services/version_service.dart'; import 'package:cabo_counter/utility/custom_theme.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/services.dart'; @@ -13,6 +14,7 @@ Future main() async { await ConfigService.initConfig(); ConfigService.pointLimit = await ConfigService.getPointLimit(); ConfigService.caboPenalty = await ConfigService.getCaboPenalty(); + await VersionService.init(); runApp(const App()); } diff --git a/lib/presentation/views/settings_view.dart b/lib/presentation/views/settings_view.dart index 34540a4..2ed422f 100644 --- a/lib/presentation/views/settings_view.dart +++ b/lib/presentation/views/settings_view.dart @@ -3,11 +3,10 @@ import 'package:cabo_counter/presentation/widgets/custom_form_row.dart'; import 'package:cabo_counter/presentation/widgets/stepper.dart'; import 'package:cabo_counter/services/config_service.dart'; import 'package:cabo_counter/services/local_storage_service.dart'; +import 'package:cabo_counter/services/version_service.dart'; import 'package:cabo_counter/utility/custom_theme.dart'; -import 'package:cabo_counter/utility/globals.dart'; import 'package:flutter/cupertino.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:package_info_plus/package_info_plus.dart'; import 'package:url_launcher/url_launcher.dart'; class SettingsView extends StatefulWidget { @@ -149,59 +148,18 @@ class _SettingsViewState extends State { prefixText: 'App-Version', prefixIcon: CupertinoIcons.info, onPressed: null, - suffixWidget: FutureBuilder( - future: _getPackageInfo(), - builder: (context, snapshot) { - if (snapshot.hasData) { - return Text( - '${Globals.appDevPhase} ${snapshot.data!.version} ', - style: TextStyle( - color: CustomTheme.primaryColor, - ), - ); - } else if (snapshot.hasError) { - return Text( - '${AppLocalizations.of(context).app_version} -.-.-', - style: TextStyle( - color: CustomTheme.primaryColor, - ), - ); - } - return Text( - AppLocalizations.of(context).loading, - style: TextStyle( - color: CustomTheme.primaryColor, - ), - ); - }, - )), + suffixWidget: Text(VersionService.getVersion(), + style: TextStyle( + color: CustomTheme.primaryColor, + ))), CustomFormRow( prefixText: 'Build-Nr.', prefixIcon: CupertinoIcons.info, onPressed: null, - suffixWidget: FutureBuilder( - future: _getPackageInfo(), - builder: (context, snapshot) { - if (snapshot.hasData) { - return Text( - snapshot.data!.buildNumber, - style: TextStyle( - color: CustomTheme.primaryColor, - ), - ); - } else if (snapshot.hasError) { - return Text( - '-', - style: TextStyle( - color: CustomTheme.primaryColor, - ), - ); - } - return Text( - AppLocalizations.of(context).loading, - ); - }, - )), + suffixWidget: Text(VersionService.getBuildNumber(), + style: TextStyle( + color: CustomTheme.primaryColor, + ))), ])), ], ), @@ -210,10 +168,6 @@ class _SettingsViewState extends State { ); } - Future _getPackageInfo() async { - return await PackageInfo.fromPlatform(); - } - void showFeedbackDialog(ImportStatus status) { if (status == ImportStatus.canceled) return; final (title, message) = _getDialogContent(status); diff --git a/lib/services/version_service.dart b/lib/services/version_service.dart new file mode 100644 index 0000000..c23d187 --- /dev/null +++ b/lib/services/version_service.dart @@ -0,0 +1,32 @@ +import 'package:cabo_counter/utility/globals.dart'; +import 'package:package_info_plus/package_info_plus.dart'; + +class VersionService { + static String _version = '-.-.-'; + static String _buildNumber = '-'; + + static Future init() async { + var packageInfo = await PackageInfo.fromPlatform(); + _version = packageInfo.version; + _buildNumber = packageInfo.buildNumber; + } + + static String getVersionNumber() { + return _version; + } + + static String getVersion() { + if (_version == '-.-.-') { + return getVersionNumber(); + } + return '${Globals.appDevPhase} $_version'; + } + + static String getBuildNumber() { + return _buildNumber; + } + + static String getVersionWithBuild() { + return '$_version ($_buildNumber)'; + } +} diff --git a/pubspec.yaml b/pubspec.yaml index fdf9916..414389d 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.4.0+371 +version: 0.4.0+376 environment: sdk: ^3.5.4 From 55f3da8052c067b86650aa91d40e787f129c1a6a Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Wed, 9 Jul 2025 17:41:54 +0200 Subject: [PATCH 14/19] Updated strings, added wiki button --- lib/l10n/app_de.arb | 6 ++++-- lib/l10n/app_en.arb | 5 +++-- lib/l10n/app_localizations.dart | 14 ++++++++++---- lib/l10n/app_localizations_de.dart | 7 +++++-- lib/l10n/app_localizations_en.dart | 7 +++++-- lib/presentation/views/settings_view.dart | 18 +++++++++++++----- pubspec.yaml | 4 ++-- 7 files changed, 42 insertions(+), 19 deletions(-) diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index b83c646..9c88d6a 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -82,7 +82,7 @@ "point_limit": "Punkte-Limit", "point_limit_subtitle": "... hier ist Schluss", "reset_to_default": "Auf Standard zurücksetzen", - "data": "Daten", + "game_data": "Spieldaten", "import_data": "Spieldaten importieren", "export_data": "Spieldaten exportieren", "app": "App", @@ -98,10 +98,12 @@ "export_error_title": "Fehler", "export_error_message": "Datei konnte nicht exportiert werden", + "error_found": "Fehler gefunden?", "create_issue": "Issue erstellen", + "wiki": "Wiki", "app_version": "App-Version", - "build": "Build", + "build": "Build-Nr.", "loading": "Lädt...", "about_text": "Hey :) Danke, dass du als eine:r der ersten User meiner ersten eigenen App dabei bist! Ich hab sehr viel Arbeit in dieses Projekt gesteckt und auch, wenn ich (hoffentlich) an vieles Gedacht hab, wird auf jeden Fall noch nicht alles 100% funktionieren. Solltest du also irgendwelche Fehler entdecken oder Feedback zum Design oder der Benutzerfreundlichkeit haben, teile Sie mir gern über die Testflight App oder auf den dir bekannten Wegen mit. Danke! " diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 1c111e2..60fc593 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -82,7 +82,7 @@ "point_limit": "Point Limit", "point_limit_subtitle": "... the game ends here.", "reset_to_default": "Reset to Default", - "data": "Data", + "game_data": "Game Data", "import_data": "Import Data", "export_data": "Export Data", "app": "App", @@ -100,9 +100,10 @@ "export_error_message": "Could not export file", "error_found": "Found a bug?", "create_issue": "Create Issue", + "wiki": "Wiki", "app_version": "App Version", "loading": "Loading...", - "build": "Build", + "build": "Build No.", "about_text": "Hey :) Thanks for being one of the first users of my app! I’ve put a lot of work into this project, and even though I tried to think of everything, it might not work perfectly just yet. So if you discover any bugs or have feedback on the design or usability, please let me know via the TestFlight app or by sending me a message or email. Thank you very much!" } diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 84295df..9f85aab 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -458,11 +458,11 @@ abstract class AppLocalizations { /// **'Auf Standard zurücksetzen'** String get reset_to_default; - /// No description provided for @data. + /// No description provided for @game_data. /// /// In de, this message translates to: - /// **'Daten'** - String get data; + /// **'Spieldaten'** + String get game_data; /// No description provided for @import_data. /// @@ -554,6 +554,12 @@ abstract class AppLocalizations { /// **'Issue erstellen'** String get create_issue; + /// No description provided for @wiki. + /// + /// In de, this message translates to: + /// **'Wiki'** + String get wiki; + /// No description provided for @app_version. /// /// In de, this message translates to: @@ -563,7 +569,7 @@ abstract class AppLocalizations { /// No description provided for @build. /// /// In de, this message translates to: - /// **'Build'** + /// **'Build-Nr.'** String get build; /// No description provided for @loading. diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index f4a2bbd..23b41ac 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -200,7 +200,7 @@ class AppLocalizationsDe extends AppLocalizations { String get reset_to_default => 'Auf Standard zurücksetzen'; @override - String get data => 'Daten'; + String get game_data => 'Spieldaten'; @override String get import_data => 'Spieldaten importieren'; @@ -250,11 +250,14 @@ class AppLocalizationsDe extends AppLocalizations { @override String get create_issue => 'Issue erstellen'; + @override + String get wiki => 'Wiki'; + @override String get app_version => 'App-Version'; @override - String get build => 'Build'; + String get build => 'Build-Nr.'; @override String get loading => 'Lädt...'; diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index aac55f2..eea3896 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -197,7 +197,7 @@ class AppLocalizationsEn extends AppLocalizations { String get reset_to_default => 'Reset to Default'; @override - String get data => 'Data'; + String get game_data => 'Game Data'; @override String get import_data => 'Import Data'; @@ -247,11 +247,14 @@ class AppLocalizationsEn extends AppLocalizations { @override String get create_issue => 'Create Issue'; + @override + String get wiki => 'Wiki'; + @override String get app_version => 'App Version'; @override - String get build => 'Build'; + String get build => 'Build No.'; @override String get loading => 'Loading...'; diff --git a/lib/presentation/views/settings_view.dart b/lib/presentation/views/settings_view.dart index 2ed422f..0d32971 100644 --- a/lib/presentation/views/settings_view.dart +++ b/lib/presentation/views/settings_view.dart @@ -101,7 +101,7 @@ class _SettingsViewState extends State { Padding( padding: const EdgeInsets.fromLTRB(10, 10, 0, 0), child: Text( - AppLocalizations.of(context).data, + AppLocalizations.of(context).game_data, style: CustomTheme.rowTitle, ), ), @@ -145,16 +145,24 @@ class _SettingsViewState extends State { suffixWidget: const CupertinoListTileChevron(), ), CustomFormRow( - prefixText: 'App-Version', - prefixIcon: CupertinoIcons.info, + prefixText: AppLocalizations.of(context).wiki, + prefixIcon: CupertinoIcons.book, + onPressed: () => launchUrl(Uri.parse( + 'https://github.com/flixcoo/Cabo-Counter/wiki')), + suffixWidget: const CupertinoListTileChevron(), + ), + CustomFormRow( + prefixText: + AppLocalizations.of(context).app_version, + prefixIcon: CupertinoIcons.number, onPressed: null, suffixWidget: Text(VersionService.getVersion(), style: TextStyle( color: CustomTheme.primaryColor, ))), CustomFormRow( - prefixText: 'Build-Nr.', - prefixIcon: CupertinoIcons.info, + prefixText: AppLocalizations.of(context).build, + prefixIcon: CupertinoIcons.number, onPressed: null, suffixWidget: Text(VersionService.getBuildNumber(), style: TextStyle( diff --git a/pubspec.yaml b/pubspec.yaml index 414389d..a692f21 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,8 +1,8 @@ name: cabo_counter -description: "Mobile app for the card game Cabo" +description: "Mobile game_data for the card game Cabo" publish_to: 'none' -version: 0.4.0+376 +version: 0.4.0+378 environment: sdk: ^3.5.4 From 17072fb5844c263048f87f849a6eb308b1cb4b8e Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Wed, 9 Jul 2025 17:42:18 +0200 Subject: [PATCH 15/19] Corrected replaced string --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index a692f21..ce04a55 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: cabo_counter -description: "Mobile game_data for the card game Cabo" +description: "Mobile app for the card game Cabo" publish_to: 'none' version: 0.4.0+378 From fd8efb2a56464d8e818bee4891cecb93b63c6a48 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Wed, 9 Jul 2025 18:46:58 +0200 Subject: [PATCH 16/19] Added import dialog feedback (got lost in refactoring) --- lib/presentation/views/settings_view.dart | 6 +++++- pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/presentation/views/settings_view.dart b/lib/presentation/views/settings_view.dart index 0d32971..9b4f91a 100644 --- a/lib/presentation/views/settings_view.dart +++ b/lib/presentation/views/settings_view.dart @@ -114,7 +114,11 @@ class _SettingsViewState extends State { CustomFormRow( prefixText: AppLocalizations.of(context).import_data, prefixIcon: CupertinoIcons.square_arrow_down, - onPressed: () => LocalStorageService.importJsonFile(), + onPressed: () async { + final status = + await LocalStorageService.importJsonFile(); + showFeedbackDialog(status); + }, suffixWidget: const CupertinoListTileChevron(), ), CustomFormRow( diff --git a/pubspec.yaml b/pubspec.yaml index ce04a55..e393fb9 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.4.0+378 +version: 0.4.0+380 environment: sdk: ^3.5.4 From 42e51a092b7436d4737b9ad45f193395820d1ba0 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Wed, 9 Jul 2025 18:49:13 +0200 Subject: [PATCH 17/19] Corrected function duplication --- lib/l10n/app_de.arb | 2 +- lib/l10n/app_en.arb | 1 + lib/presentation/views/settings_view.dart | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 9c88d6a..0a76696 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -93,7 +93,7 @@ "import_validation_error_message": "Es wurden keine Cabo-Counter Spieldaten gefunden. Bitte stellen Sie sicher, dass es sich um eine gültige Cabo-Counter Exportdatei handelt.", "import_format_error_title": "Falsches Format", "import_format_error_message": "Die Datei ist kein gültiges JSON-Format oder enthält ungültige Daten.", - "import_generic_error_title": "Import fehlgeschlagen", + "import_generic_error_title": "Import fehlgeschlagen", "import_generic_error_message": "Der Import ist fehlgeschlagen.", "export_error_title": "Fehler", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 60fc593..edca935 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -98,6 +98,7 @@ "export_error_title": "Export failed", "export_error_message": "Could not export file", + "error_found": "Found a bug?", "create_issue": "Create Issue", "wiki": "Wiki", diff --git a/lib/presentation/views/settings_view.dart b/lib/presentation/views/settings_view.dart index 9b4f91a..7c1df2e 100644 --- a/lib/presentation/views/settings_view.dart +++ b/lib/presentation/views/settings_view.dart @@ -124,7 +124,7 @@ class _SettingsViewState extends State { CustomFormRow( prefixText: AppLocalizations.of(context).export_data, prefixIcon: CupertinoIcons.square_arrow_up, - onPressed: () => LocalStorageService.importJsonFile(), + onPressed: () => LocalStorageService.exportGameData(), suffixWidget: const CupertinoListTileChevron(), ), ])), From 74a27aea24b6fda2979bb72db6c55e9aa4d425c9 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Wed, 9 Jul 2025 18:51:34 +0200 Subject: [PATCH 18/19] changed suffixWidget assignment and moved stepperKeys --- lib/presentation/views/settings_view.dart | 4 ++-- lib/presentation/widgets/custom_form_row.dart | 2 +- pubspec.yaml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/presentation/views/settings_view.dart b/lib/presentation/views/settings_view.dart index 7c1df2e..72365ea 100644 --- a/lib/presentation/views/settings_view.dart +++ b/lib/presentation/views/settings_view.dart @@ -51,10 +51,10 @@ class _SettingsViewState extends State { margin: EdgeInsets.zero, children: [ CustomFormRow( - key: _stepperKey1, prefixText: 'Cabo-Strafe', prefixIcon: CupertinoIcons.minus_square, suffixWidget: Stepper( + key: _stepperKey1, initialValue: ConfigService.caboPenalty, minValue: 0, maxValue: 50, @@ -68,10 +68,10 @@ class _SettingsViewState extends State { ), ), CustomFormRow( - key: _stepperKey2, prefixText: 'Punkte-Limit', prefixIcon: FontAwesomeIcons.bullseye, suffixWidget: Stepper( + key: _stepperKey2, initialValue: ConfigService.pointLimit, minValue: 30, maxValue: 1000, diff --git a/lib/presentation/widgets/custom_form_row.dart b/lib/presentation/widgets/custom_form_row.dart index f03b453..7a266ae 100644 --- a/lib/presentation/widgets/custom_form_row.dart +++ b/lib/presentation/widgets/custom_form_row.dart @@ -24,11 +24,11 @@ class _CustomFormRowState extends State { @override void initState() { super.initState(); - suffixWidget = widget.suffixWidget ?? const SizedBox.shrink(); } @override Widget build(BuildContext context) { + suffixWidget = widget.suffixWidget ?? const SizedBox.shrink(); return CupertinoButton( padding: EdgeInsets.zero, onPressed: widget.onPressed, diff --git a/pubspec.yaml b/pubspec.yaml index e393fb9..7b8621b 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.4.0+380 +version: 0.4.0+381 environment: sdk: ^3.5.4 From d1ad5511f4682709d901b06a5792c0cac4a6b5f7 Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Wed, 9 Jul 2025 19:01:12 +0200 Subject: [PATCH 19/19] Changed icons --- lib/presentation/views/settings_view.dart | 4 ++-- pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/presentation/views/settings_view.dart b/lib/presentation/views/settings_view.dart index 72365ea..84916c2 100644 --- a/lib/presentation/views/settings_view.dart +++ b/lib/presentation/views/settings_view.dart @@ -52,7 +52,7 @@ class _SettingsViewState extends State { children: [ CustomFormRow( prefixText: 'Cabo-Strafe', - prefixIcon: CupertinoIcons.minus_square, + prefixIcon: CupertinoIcons.bolt_fill, suffixWidget: Stepper( key: _stepperKey1, initialValue: ConfigService.caboPenalty, @@ -158,7 +158,7 @@ class _SettingsViewState extends State { CustomFormRow( prefixText: AppLocalizations.of(context).app_version, - prefixIcon: CupertinoIcons.number, + prefixIcon: CupertinoIcons.tag, onPressed: null, suffixWidget: Text(VersionService.getVersion(), style: TextStyle( diff --git a/pubspec.yaml b/pubspec.yaml index 7b8621b..5edeba0 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.4.0+381 +version: 0.4.0+382 environment: sdk: ^3.5.4