Added placeholder setting tiles for legal
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m13s
Pull Request Pipeline / lint (pull_request) Successful in 2m14s

This commit is contained in:
2026-01-11 17:09:05 +01:00
parent 857e05127d
commit 7fc4bbfb13
7 changed files with 265 additions and 191 deletions

View File

@@ -13,6 +13,7 @@
"create_match": "Spiel erstellen", "create_match": "Spiel erstellen",
"create_new_group": "Neue Gruppe erstellen", "create_new_group": "Neue Gruppe erstellen",
"create_new_match": "Neues Spiel erstellen", "create_new_match": "Neues Spiel erstellen",
"data": "Daten",
"data_successfully_deleted": "Daten erfolgreich gelöscht", "data_successfully_deleted": "Daten erfolgreich gelöscht",
"data_successfully_exported": "Daten erfolgreich exportiert", "data_successfully_exported": "Daten erfolgreich exportiert",
"data_successfully_imported": "Daten erfolgreich importiert", "data_successfully_imported": "Daten erfolgreich importiert",
@@ -34,8 +35,10 @@
"import_data": "Daten importieren", "import_data": "Daten importieren",
"info": "Info", "info": "Info",
"invalid_schema": "Ungültiges Schema", "invalid_schema": "Ungültiges Schema",
"licenses": "Lizenzen",
"least_points": "Niedrigste Punkte", "least_points": "Niedrigste Punkte",
"legal": "Rechtliches",
"legal_notice": "Impressum",
"licenses": "Lizenzen",
"match_in_progress": "Spiel läuft...", "match_in_progress": "Spiel läuft...",
"match_name": "Spieltitel", "match_name": "Spieltitel",
"matches": "Spiele", "matches": "Spiele",
@@ -58,6 +61,7 @@
"player_name": "Spieler:innenname", "player_name": "Spieler:innenname",
"players": "Spieler:innen", "players": "Spieler:innen",
"players_count": "{count} Spieler", "players_count": "{count} Spieler",
"privacy_policy": "Datenschutzerklärung",
"quick_create": "Schnellzugriff", "quick_create": "Schnellzugriff",
"recent_matches": "Letzte Spiele", "recent_matches": "Letzte Spiele",
"ruleset": "Regelwerk", "ruleset": "Regelwerk",
@@ -69,7 +73,6 @@
"search_for_players": "Nach Spieler:innen suchen", "search_for_players": "Nach Spieler:innen suchen",
"select_winner": "Gewinner:in wählen:", "select_winner": "Gewinner:in wählen:",
"selected_players": "Ausgewählte Spieler:innen", "selected_players": "Ausgewählte Spieler:innen",
"settings": "Einstellungen",
"single_loser": "Ein:e Verlierer:in", "single_loser": "Ein:e Verlierer:in",
"single_winner": "Ein:e Gewinner:in", "single_winner": "Ein:e Gewinner:in",
"statistics": "Statistiken", "statistics": "Statistiken",

View File

@@ -39,6 +39,9 @@
"@create_new_match": { "@create_new_match": {
"description": "Button text to create a new match" "description": "Button text to create a new match"
}, },
"@data": {
"description": "Data label"
},
"@data_successfully_deleted": { "@data_successfully_deleted": {
"description": "Success message after deleting data" "description": "Success message after deleting data"
}, },
@@ -107,12 +110,18 @@
"@invalid_schema": { "@invalid_schema": {
"description": "Error message for invalid schema" "description": "Error message for invalid schema"
}, },
"@licenses": {
"description": "Licenses menu item"
},
"@least_points": { "@least_points": {
"description": "Title for least points ruleset" "description": "Title for least points ruleset"
}, },
"@legal": {
"description": "Legal section header"
},
"@legal_notice": {
"description": "Legal notice menu item"
},
"@licenses": {
"description": "Licenses menu item"
},
"@match_in_progress": { "@match_in_progress": {
"description": "Message when match is in progress" "description": "Message when match is in progress"
}, },
@@ -184,6 +193,9 @@
} }
} }
}, },
"@privacy_policy": {
"description": "Privacy policy menu item"
},
"@quick_create": { "@quick_create": {
"description": "Title for quick create section" "description": "Title for quick create section"
}, },
@@ -217,9 +229,6 @@
"@selected_players": { "@selected_players": {
"description": "Shows the number of selected players" "description": "Shows the number of selected players"
}, },
"@settings": {
"description": "Settings label"
},
"@single_loser": { "@single_loser": {
"description": "Title for single loser ruleset" "description": "Title for single loser ruleset"
}, },
@@ -281,6 +290,7 @@
"create_match": "Create match", "create_match": "Create match",
"create_new_group": "Create new group", "create_new_group": "Create new group",
"create_new_match": "Create new match", "create_new_match": "Create new match",
"data": "Data",
"data_successfully_deleted": "Data successfully deleted", "data_successfully_deleted": "Data successfully deleted",
"data_successfully_exported": "Data successfully exported", "data_successfully_exported": "Data successfully exported",
"data_successfully_imported": "Data successfully imported", "data_successfully_imported": "Data successfully imported",
@@ -302,8 +312,10 @@
"import_data": "Import data", "import_data": "Import data",
"info": "Info", "info": "Info",
"invalid_schema": "Invalid Schema", "invalid_schema": "Invalid Schema",
"licenses": "Licenses",
"least_points": "Least Points", "least_points": "Least Points",
"legal": "Legal",
"legal_notice": "Legal Notice",
"licenses": "Licenses",
"match_in_progress": "Match in progress...", "match_in_progress": "Match in progress...",
"match_name": "Match name", "match_name": "Match name",
"matches": "Matches", "matches": "Matches",
@@ -326,6 +338,7 @@
"player_name": "Player name", "player_name": "Player name",
"players": "Players", "players": "Players",
"players_count": "{count} Players", "players_count": "{count} Players",
"privacy_policy": "Privacy Policy",
"quick_create": "Quick Create", "quick_create": "Quick Create",
"recent_matches": "Recent Matches", "recent_matches": "Recent Matches",
"ruleset": "Ruleset", "ruleset": "Ruleset",
@@ -337,7 +350,6 @@
"search_for_players": "Search for players", "search_for_players": "Search for players",
"select_winner": "Select Winner:", "select_winner": "Select Winner:",
"selected_players": "Selected players", "selected_players": "Selected players",
"settings": "Settings",
"single_loser": "Single Loser", "single_loser": "Single Loser",
"single_winner": "Single Winner", "single_winner": "Single Winner",
"statistics": "Statistics", "statistics": "Statistics",

View File

@@ -176,6 +176,12 @@ abstract class AppLocalizations {
/// **'Create new match'** /// **'Create new match'**
String get create_new_match; String get create_new_match;
/// Data label
///
/// In en, this message translates to:
/// **'Data'**
String get data;
/// Success message after deleting data /// Success message after deleting data
/// ///
/// In en, this message translates to: /// In en, this message translates to:
@@ -302,18 +308,30 @@ abstract class AppLocalizations {
/// **'Invalid Schema'** /// **'Invalid Schema'**
String get invalid_schema; String get invalid_schema;
/// Licenses menu item
///
/// In en, this message translates to:
/// **'Licenses'**
String get licenses;
/// Title for least points ruleset /// Title for least points ruleset
/// ///
/// In en, this message translates to: /// In en, this message translates to:
/// **'Least Points'** /// **'Least Points'**
String get least_points; String get least_points;
/// Legal section header
///
/// In en, this message translates to:
/// **'Legal'**
String get legal;
/// Legal notice menu item
///
/// In en, this message translates to:
/// **'Legal Notice'**
String get legal_notice;
/// Licenses menu item
///
/// In en, this message translates to:
/// **'Licenses'**
String get licenses;
/// Message when match is in progress /// Message when match is in progress
/// ///
/// In en, this message translates to: /// In en, this message translates to:
@@ -446,6 +464,12 @@ abstract class AppLocalizations {
/// **'{count} Players'** /// **'{count} Players'**
String players_count(int count); String players_count(int count);
/// Privacy policy menu item
///
/// In en, this message translates to:
/// **'Privacy Policy'**
String get privacy_policy;
/// Title for quick create section /// Title for quick create section
/// ///
/// In en, this message translates to: /// In en, this message translates to:
@@ -512,12 +536,6 @@ abstract class AppLocalizations {
/// **'Selected players'** /// **'Selected players'**
String get selected_players; String get selected_players;
/// Settings label
///
/// In en, this message translates to:
/// **'Settings'**
String get settings;
/// Title for single loser ruleset /// Title for single loser ruleset
/// ///
/// In en, this message translates to: /// In en, this message translates to:

View File

@@ -49,6 +49,9 @@ class AppLocalizationsDe extends AppLocalizations {
@override @override
String get create_new_match => 'Neues Spiel erstellen'; String get create_new_match => 'Neues Spiel erstellen';
@override
String get data => 'Daten';
@override @override
String get data_successfully_deleted => 'Daten erfolgreich gelöscht'; String get data_successfully_deleted => 'Daten erfolgreich gelöscht';
@@ -116,10 +119,16 @@ class AppLocalizationsDe extends AppLocalizations {
String get invalid_schema => 'Ungültiges Schema'; String get invalid_schema => 'Ungültiges Schema';
@override @override
String get licenses => 'Lizenzen'; String get least_points => 'Niedrigste Punkte';
@override @override
String get least_points => 'Niedrigste Punkte'; String get legal => 'Rechtliches';
@override
String get legal_notice => 'Impressum';
@override
String get licenses => 'Lizenzen';
@override @override
String get match_in_progress => 'Spiel läuft...'; String get match_in_progress => 'Spiel läuft...';
@@ -190,6 +199,9 @@ class AppLocalizationsDe extends AppLocalizations {
return '$count Spieler'; return '$count Spieler';
} }
@override
String get privacy_policy => 'Datenschutzerklärung';
@override @override
String get quick_create => 'Schnellzugriff'; String get quick_create => 'Schnellzugriff';
@@ -227,9 +239,6 @@ class AppLocalizationsDe extends AppLocalizations {
@override @override
String get selected_players => 'Ausgewählte Spieler:innen'; String get selected_players => 'Ausgewählte Spieler:innen';
@override
String get settings => 'Einstellungen';
@override @override
String get single_loser => 'Ein:e Verlierer:in'; String get single_loser => 'Ein:e Verlierer:in';

View File

@@ -49,6 +49,9 @@ class AppLocalizationsEn extends AppLocalizations {
@override @override
String get create_new_match => 'Create new match'; String get create_new_match => 'Create new match';
@override
String get data => 'Data';
@override @override
String get data_successfully_deleted => 'Data successfully deleted'; String get data_successfully_deleted => 'Data successfully deleted';
@@ -116,10 +119,16 @@ class AppLocalizationsEn extends AppLocalizations {
String get invalid_schema => 'Invalid Schema'; String get invalid_schema => 'Invalid Schema';
@override @override
String get licenses => 'Licenses'; String get least_points => 'Least Points';
@override @override
String get least_points => 'Least Points'; String get legal => 'Legal';
@override
String get legal_notice => 'Legal Notice';
@override
String get licenses => 'Licenses';
@override @override
String get match_in_progress => 'Match in progress...'; String get match_in_progress => 'Match in progress...';
@@ -190,6 +199,9 @@ class AppLocalizationsEn extends AppLocalizations {
return '$count Players'; return '$count Players';
} }
@override
String get privacy_policy => 'Privacy Policy';
@override @override
String get quick_create => 'Quick Create'; String get quick_create => 'Quick Create';
@@ -227,9 +239,6 @@ class AppLocalizationsEn extends AppLocalizations {
@override @override
String get selected_players => 'Selected players'; String get selected_players => 'Selected players';
@override
String get settings => 'Settings';
@override @override
String get single_loser => 'Single Loser'; String get single_loser => 'Single Loser';

View File

@@ -40,172 +40,194 @@ class _SettingsViewState extends State<SettingsView> {
child: Scaffold( child: Scaffold(
appBar: AppBar(backgroundColor: CustomTheme.backgroundColor), appBar: AppBar(backgroundColor: CustomTheme.backgroundColor),
backgroundColor: CustomTheme.backgroundColor, backgroundColor: CustomTheme.backgroundColor,
body: Column( body: SingleChildScrollView(
mainAxisAlignment: MainAxisAlignment.start, child: Expanded(
crossAxisAlignment: CrossAxisAlignment.start, child: Column(
children: [ mainAxisAlignment: MainAxisAlignment.start,
Padding( crossAxisAlignment: CrossAxisAlignment.start,
padding: const EdgeInsets.only(left: 16, bottom: 10), children: [
child: Text( Padding(
textAlign: TextAlign.start, padding: const EdgeInsets.only(left: 16, bottom: 10),
loc.menu, child: Text(
style: const TextStyle( textAlign: TextAlign.start,
fontSize: 28, loc.menu,
fontWeight: FontWeight.bold, style: const TextStyle(
), fontSize: 28,
), fontWeight: FontWeight.bold,
), ),
Padding(
padding: const EdgeInsets.only(left: 16, top: 10, bottom: 10),
child: Text(
textAlign: TextAlign.start,
loc.settings,
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
),
),
),
SettingsListTile(
title: loc.export_data,
icon: Icons.upload,
suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16),
onPressed: () async {
final String json = await DataTransferService.getAppDataAsJson(
context,
);
final result = await DataTransferService.exportData(
json,
'game_tracker-data',
);
if (!context.mounted) return;
showExportSnackBar(context: context, result: result);
},
),
SettingsListTile(
title: loc.import_data,
icon: Icons.download,
suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16),
onPressed: () async {
final result = await DataTransferService.importData(context);
if (!context.mounted) return;
showImportSnackBar(context: context, result: result);
},
),
SettingsListTile(
title: loc.delete_all_data,
icon: Icons.delete,
suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16),
onPressed: () {
showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
title: Text('${loc.delete_all_data}?'),
content: Text(loc.this_cannot_be_undone),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(false),
child: Text(loc.cancel),
),
TextButton(
onPressed: () => Navigator.of(context).pop(true),
child: Text(loc.delete),
),
],
), ),
).then((confirmed) { ),
if (confirmed == true && context.mounted) { Padding(
DataTransferService.deleteAllData(context); padding: const EdgeInsets.only(left: 16, top: 10, bottom: 10),
showSnackbar( child: Text(
context: context, textAlign: TextAlign.start,
message: AppLocalizations.of( loc.data,
context, style: const TextStyle(
).data_successfully_deleted, fontSize: 22,
fontWeight: FontWeight.bold,
),
),
),
SettingsListTile(
title: loc.export_data,
icon: Icons.upload,
suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16),
onPressed: () async {
final String json =
await DataTransferService.getAppDataAsJson(context);
final result = await DataTransferService.exportData(
json,
'game_tracker-data',
); );
} if (!context.mounted) return;
}); showExportSnackBar(context: context, result: result);
}, },
), ),
const Padding( SettingsListTile(
padding: EdgeInsets.only(left: 16, top: 10, bottom: 10), title: loc.import_data,
child: Text( icon: Icons.download,
textAlign: TextAlign.start, suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16),
'App', onPressed: () async {
style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold), final result = await DataTransferService.importData(
), context,
), );
SettingsListTile( if (!context.mounted) return;
title: loc.licenses, showImportSnackBar(context: context, result: result);
icon: Icons.insert_drive_file, },
suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16), ),
onPressed: () { SettingsListTile(
Navigator.of(context).push( title: loc.delete_all_data,
MaterialPageRoute(builder: (context) => const LicensesView()), icon: Icons.delete,
); suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16),
}, onPressed: () {
), showDialog<bool>(
const Spacer(), context: context,
Padding( builder: (context) => AlertDialog(
padding: const EdgeInsets.all(20), title: Text('${loc.delete_all_data}?'),
child: Center( content: Text(loc.this_cannot_be_undone),
child: Column( actions: [
spacing: 4, TextButton(
children: [ onPressed: () => Navigator.of(context).pop(false),
Padding( child: Text(loc.cancel),
padding: const EdgeInsets.only(bottom: 12),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
spacing: 40,
children: [
GestureDetector(
child: const Icon(Icons.language),
onTap: () => {
launchUrl(Uri.parse('https://liquid-dev.de')),
},
), ),
GestureDetector( TextButton(
child: const FaIcon(FontAwesomeIcons.github), onPressed: () => Navigator.of(context).pop(true),
onTap: () => { child: Text(loc.delete),
launchUrl(
Uri.parse(
'https://github.com/liquiddevelopmentde',
),
),
},
),
GestureDetector(
child: Icon(
Platform.isIOS
? CupertinoIcons.mail_solid
: Icons.email,
),
onTap: () =>
launchUrl(Uri.parse('mailto:hi@liquid-dev.de')),
), ),
], ],
), ),
), ).then((confirmed) {
Text( if (confirmed == true && context.mounted) {
'© ${DateFormat('yyyy').format(DateTime.now())} Liquid Development', DataTransferService.deleteAllData(context);
style: TextStyle( showSnackbar(
color: Colors.grey.shade600, context: context,
fontSize: 14, message: AppLocalizations.of(
fontWeight: FontWeight.w600, context,
), ).data_successfully_deleted,
), );
Text( }
'Version ${_packageInfo.version} (${_packageInfo.buildNumber})', });
style: TextStyle( },
color: Colors.grey.shade600,
fontSize: 14,
fontWeight: FontWeight.w600,
),
),
],
), ),
), Padding(
padding: const EdgeInsets.only(left: 16, top: 10, bottom: 10),
child: Text(
textAlign: TextAlign.start,
loc.legal,
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
),
),
),
SettingsListTile(
title: loc.licenses,
icon: Icons.insert_drive_file,
suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const LicensesView(),
),
);
},
),
SettingsListTile(
title: loc.legal_notice,
icon: Icons.account_balance_sharp,
suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16),
onPressed: null,
),
SettingsListTile(
title: loc.privacy_policy,
icon: Icons.gpp_good_rounded,
suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16),
onPressed: null,
),
Padding(
padding: const EdgeInsets.only(top: 30, bottom: 20),
child: Center(
child: Column(
spacing: 4,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 12),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
spacing: 40,
children: [
GestureDetector(
child: const Icon(Icons.language),
onTap: () => {
launchUrl(Uri.parse('https://liquid-dev.de')),
},
),
GestureDetector(
child: const FaIcon(FontAwesomeIcons.github),
onTap: () => {
launchUrl(
Uri.parse(
'https://github.com/liquiddevelopmentde',
),
),
},
),
GestureDetector(
child: Icon(
Platform.isIOS
? CupertinoIcons.mail_solid
: Icons.email,
),
onTap: () => launchUrl(
Uri.parse('mailto:hi@liquid-dev.de'),
),
),
],
),
),
Text(
'© ${DateFormat('yyyy').format(DateTime.now())} Liquid Development',
style: TextStyle(
color: Colors.grey.shade600,
fontSize: 14,
fontWeight: FontWeight.w600,
),
),
Text(
'Version ${_packageInfo.version} (${_packageInfo.buildNumber})',
style: TextStyle(
color: Colors.grey.shade600,
fontSize: 14,
fontWeight: FontWeight.w600,
),
),
],
),
),
),
],
), ),
], ),
), ),
), ),
); );
@@ -282,6 +304,7 @@ class _SettingsViewState extends State<SettingsView> {
); );
} }
/// Initializes the package information.
Future<void> _initPackageInfo() async { Future<void> _initPackageInfo() async {
final info = await PackageInfo.fromPlatform(); final info = await PackageInfo.fromPlatform();
setState(() { setState(() {

View File

@@ -1,7 +1,7 @@
name: game_tracker name: game_tracker
description: "Game Tracking App for Card Games" description: "Game Tracking App for Card Games"
publish_to: 'none' publish_to: 'none'
version: 0.0.5+128 version: 0.0.5+130
environment: environment:
sdk: ^3.8.1 sdk: ^3.8.1