Lokalisierung implementieren #112
@@ -35,14 +35,15 @@ enum Ruleset { singleWinner, singleLoser, mostPoints, leastPoints }
|
||||
|
||||
/// Translates a [Ruleset] enum value to its corresponding localized string.
|
||||
String translateRulesetToString(Ruleset ruleset, BuildContext context) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
switch (ruleset) {
|
||||
case Ruleset.singleWinner:
|
||||
return AppLocalizations.of(context).single_winner;
|
||||
return loc.single_winner;
|
||||
case Ruleset.singleLoser:
|
||||
return AppLocalizations.of(context).single_loser;
|
||||
return loc.single_loser;
|
||||
case Ruleset.mostPoints:
|
||||
return AppLocalizations.of(context).most_points;
|
||||
return loc.most_points;
|
||||
case Ruleset.leastPoints:
|
||||
return AppLocalizations.of(context).least_points;
|
||||
return loc.least_points;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,30 +3,28 @@
|
||||
"choose_group": "Gruppe wählen",
|
||||
"create_new_match": "Neues Match erstellen",
|
||||
"choose_ruleset": "Regelwerk wählen",
|
||||
"choose_game": "Spiel wählen",
|
||||
"select_winner": "Gewinner wählen:",
|
||||
"choose_game": "Spielvorlage wählen",
|
||||
"select_winner": "Gewinner:in wählen:",
|
||||
"no_recent_matches_available": "Keine letzten Matches verfügbar",
|
||||
"no_second_match_available": "Kein zweites Match verfügbar",
|
||||
"delete_all_data": "Alle Daten löschen?",
|
||||
"cancel": "Abbrechen",
|
||||
"delete": "Löschen",
|
||||
"create_new_group": "Neue Gruppe erstellen",
|
||||
"error_while_creating_group_please_try_again": "Fehler beim Erstellen der Gruppe, bitte erneut versuchen",
|
||||
"selected_players": "Ausgewählte Spieler: {count}",
|
||||
"no_players_selected": "Keine Spieler ausgewählt",
|
||||
"all_players": "Alle Spieler:",
|
||||
"successfully_added_player": "Spieler {playerName} erfolgreich hinzugefügt",
|
||||
"could_not_add_player": "Spieler {playerName} konnte nicht hinzugefügt werden",
|
||||
"winner": "Gewinner: {winnerName}",
|
||||
"players": "Spieler",
|
||||
"player_name": "Spielername",
|
||||
"error_creating_group": "Fehler beim Erstellen der Gruppe, bitte erneut versuchen",
|
||||
"selected_players": "Ausgewählte Spieler:in: {count}",
|
||||
"no_players_selected": "Keine Spieler:in ausgewählt",
|
||||
"all_players": "Alle Spieler:innen:",
|
||||
"successfully_added_player": "Spieler:in {playerName} erfolgreich hinzugefügt",
|
||||
"could_not_add_player": "Spieler:in {playerName} konnte nicht hinzugefügt werden",
|
||||
"winner": "Gewinner:in: {winnerName}",
|
||||
"players": "Spieler:in",
|
||||
"player_name": "Spieler:innenname",
|
||||
"no_statistics_available": "Keine Statistiken verfügbar",
|
||||
"matches": "Matches",
|
||||
"groups": "Gruppen",
|
||||
"recent_matches": "Letzte Matches",
|
||||
"quick_create": "Schnellzugriff",
|
||||
"winner_label": "Gewinner",
|
||||
"ruleset_label": "Regelwerk",
|
||||
"match_in_progress": "Match läuft...",
|
||||
"menu": "Menü",
|
||||
"settings": "Einstellungen",
|
||||
@@ -52,15 +50,15 @@
|
||||
"group_name": "Gruppenname",
|
||||
"no_matches_created_yet": "Noch keine Matches erstellt",
|
||||
"match_name": "Matchname",
|
||||
"game": "Spiel",
|
||||
"game": "Spielvorlage",
|
||||
"ruleset": "Regelwerk",
|
||||
"group": "Gruppe",
|
||||
"none": "Kein",
|
||||
"none_group": "Keine",
|
||||
"create_match": "Match erstellen",
|
||||
"no_players_created_yet": "Noch keine Spieler erstellt",
|
||||
"all_players_selected": "Alle Spieler ausgewählt",
|
||||
"no_players_found_with_that_name": "Keine Spieler mit diesem Namen gefunden",
|
||||
"no_players_created_yet": "Noch keine Spieler:in erstellt",
|
||||
"all_players_selected": "Alle Spieler:innen ausgewählt",
|
||||
"no_players_found_with_that_name": "Keine Spieler:in mit diesem Namen gefunden",
|
||||
"today_at": "Heute um {time}",
|
||||
"yesterday_at": "Gestern um {time}",
|
||||
"days_ago": "vor {count} Tagen",
|
||||
@@ -69,16 +67,16 @@
|
||||
"stats": "Statistiken",
|
||||
"players_count": "{count} Spieler",
|
||||
"there_is_no_group_matching_your_search": "Es gibt keine Gruppe, die deiner Suche entspricht",
|
||||
"game_name": "Spielname",
|
||||
"ruleset_single_winner_desc": "Genau ein Gewinner wird gewählt; Unentschieden werden durch einen vordefinierten Tie-Breaker aufgelöst.",
|
||||
"ruleset_single_loser_desc": "Genau ein Verlierer wird bestimmt; der letzte Platz erhält die Strafe oder Konsequenz.",
|
||||
"ruleset_most_points_desc": "Traditionelles Regelwerk: Der Spieler mit den meisten Punkten gewinnt.",
|
||||
"ruleset_least_points_desc": "Umgekehrte Wertung: Der Spieler mit den wenigsten Punkten gewinnt.",
|
||||
"single_winner": "Ein Gewinner",
|
||||
"single_loser": "Ein Verlierer",
|
||||
"game_name": "Spielvorlagenname",
|
||||
|
sneeex marked this conversation as resolved
Outdated
|
||||
"ruleset_single_winner": "Genau ein:e Gewinner:in wird gewählt; Unentschieden werden durch einen vordefinierten Tie-Breaker aufgelöst.",
|
||||
"ruleset_single_loser": "Genau ein:e Verlierer:in wird bestimmt; der letzte Platz erhält die Strafe oder Konsequenz.",
|
||||
"ruleset_most_points": "Traditionelles Regelwerk: Der/die Spieler:in mit den meisten Punkten gewinnt.",
|
||||
"ruleset_least_points": "Umgekehrte Wertung: Der/die Spieler:in mit den wenigsten Punkten gewinnt.",
|
||||
"single_winner": "Ein:e Gewinner:in",
|
||||
"single_loser": "Ein:e Verlierer:in",
|
||||
"most_points": "Höchste Punkte",
|
||||
"least_points": "Niedrigste Punkte",
|
||||
"search_for_players": "Nach Spielern suchen",
|
||||
"search_for_players": "Nach Spieler:innen suchen",
|
||||
"search_for_groups": "Nach Gruppen suchen",
|
||||
"no_data_available": "Keine Daten verfügbar",
|
||||
"not_available": "Nicht verfügbar"
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
"@select_winner": {
|
||||
"description": "Label to select the winner"
|
||||
},
|
||||
"game_tracker": "Game Tracker",
|
||||
"@game_tracker": {
|
||||
"description": "App Name"
|
||||
},
|
||||
"no_recent_matches_available": "No recent matches available",
|
||||
"@no_recent_matches_available": {
|
||||
"description": "Message when no recent matches exist"
|
||||
@@ -44,8 +48,8 @@
|
||||
"@create_new_group": {
|
||||
"description": "Button text to create a new group"
|
||||
},
|
||||
"error_while_creating_group_please_try_again": "Error while creating group, please try again",
|
||||
"@error_while_creating_group_please_try_again": {
|
||||
"error_creating_group": "Error while creating group, please try again",
|
||||
"@error_creating_group": {
|
||||
"description": "Error message when group creation fails"
|
||||
},
|
||||
"selected_players": "Selected players: {count}",
|
||||
@@ -124,14 +128,6 @@
|
||||
"@quick_create": {
|
||||
"description": "Title for quick create section"
|
||||
},
|
||||
"winner_label": "Winner",
|
||||
"@winner_label": {
|
||||
"description": "Label for winner field"
|
||||
},
|
||||
"ruleset_label": "Ruleset",
|
||||
"@ruleset_label": {
|
||||
"description": "Label for ruleset field"
|
||||
},
|
||||
"match_in_progress": "Match in progress...",
|
||||
"@match_in_progress": {
|
||||
"description": "Message when match is in progress"
|
||||
@@ -330,20 +326,20 @@
|
||||
"@game_name": {
|
||||
"description": "Placeholder for game name search"
|
||||
},
|
||||
"ruleset_single_winner_desc": "Exactly one winner is chosen; ties are resolved by a predefined tiebreaker.",
|
||||
"@ruleset_single_winner_desc": {
|
||||
"ruleset_single_winner": "Exactly one winner is chosen; ties are resolved by a predefined tiebreaker.",
|
||||
"@ruleset_single_winner": {
|
||||
"description": "Description for single winner ruleset"
|
||||
},
|
||||
"ruleset_single_loser_desc": "Exactly one loser is determined; last place receives the penalty or consequence.",
|
||||
"@ruleset_single_loser_desc": {
|
||||
"ruleset_single_loser": "Exactly one loser is determined; last place receives the penalty or consequence.",
|
||||
"@ruleset_single_loser": {
|
||||
"description": "Description for single loser ruleset"
|
||||
},
|
||||
"ruleset_most_points_desc": "Traditional ruleset: the player with the most points wins.",
|
||||
"@ruleset_most_points_desc": {
|
||||
"ruleset_most_points": "Traditional ruleset: the player with the most points wins.",
|
||||
"@ruleset_most_points": {
|
||||
"description": "Description for most points ruleset"
|
||||
},
|
||||
"ruleset_least_points_desc": "Inverse scoring: the player with the fewest points wins.",
|
||||
"@ruleset_least_points_desc": {
|
||||
"ruleset_least_points": "Inverse scoring: the player with the fewest points wins.",
|
||||
"@ruleset_least_points": {
|
||||
"description": "Description for least points ruleset"
|
||||
},
|
||||
"single_winner": "Single Winner",
|
||||
|
||||
@@ -128,6 +128,12 @@ abstract class AppLocalizations {
|
||||
/// **'Select Winner:'**
|
||||
String get select_winner;
|
||||
|
||||
/// App Name
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Game Tracker'**
|
||||
String get game_tracker;
|
||||
|
||||
/// Message when no recent matches exist
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
@@ -168,7 +174,7 @@ abstract class AppLocalizations {
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Error while creating group, please try again'**
|
||||
String get error_while_creating_group_please_try_again;
|
||||
String get error_creating_group;
|
||||
|
||||
/// Shows the number of selected players
|
||||
///
|
||||
@@ -248,18 +254,6 @@ abstract class AppLocalizations {
|
||||
/// **'Quick Create'**
|
||||
String get quick_create;
|
||||
|
||||
/// Label for winner field
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Winner'**
|
||||
String get winner_label;
|
||||
|
||||
/// Label for ruleset field
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Ruleset'**
|
||||
String get ruleset_label;
|
||||
|
||||
/// Message when match is in progress
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
@@ -528,25 +522,25 @@ abstract class AppLocalizations {
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Exactly one winner is chosen; ties are resolved by a predefined tiebreaker.'**
|
||||
String get ruleset_single_winner_desc;
|
||||
String get ruleset_single_winner;
|
||||
|
||||
/// Description for single loser ruleset
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Exactly one loser is determined; last place receives the penalty or consequence.'**
|
||||
String get ruleset_single_loser_desc;
|
||||
String get ruleset_single_loser;
|
||||
|
||||
/// Description for most points ruleset
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Traditional ruleset: the player with the most points wins.'**
|
||||
String get ruleset_most_points_desc;
|
||||
String get ruleset_most_points;
|
||||
|
||||
/// Description for least points ruleset
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Inverse scoring: the player with the fewest points wins.'**
|
||||
String get ruleset_least_points_desc;
|
||||
String get ruleset_least_points;
|
||||
|
||||
/// Title for single winner ruleset
|
||||
///
|
||||
|
||||
@@ -18,10 +18,13 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get choose_ruleset => 'Regelwerk wählen';
|
||||
|
||||
@override
|
||||
String get choose_game => 'Spiel wählen';
|
||||
String get choose_game => 'Spielvorlage wählen';
|
||||
|
||||
@override
|
||||
String get select_winner => 'Gewinner wählen:';
|
||||
String get select_winner => 'Gewinner:in wählen:';
|
||||
|
||||
@override
|
||||
String get game_tracker => 'Game Tracker';
|
||||
|
||||
@override
|
||||
String get no_recent_matches_available => 'Keine letzten Matches verfügbar';
|
||||
@@ -42,7 +45,7 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get create_new_group => 'Neue Gruppe erstellen';
|
||||
|
||||
@override
|
||||
String get error_while_creating_group_please_try_again =>
|
||||
String get error_creating_group =>
|
||||
'Fehler beim Erstellen der Gruppe, bitte erneut versuchen';
|
||||
|
||||
@override
|
||||
@@ -52,32 +55,32 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
);
|
||||
final String countString = countNumberFormat.format(count);
|
||||
|
||||
return 'Ausgewählte Spieler: $countString';
|
||||
return 'Ausgewählte Spieler:in: $countString';
|
||||
}
|
||||
|
||||
@override
|
||||
String get no_players_selected => 'Keine Spieler ausgewählt';
|
||||
String get no_players_selected => 'Keine Spieler:in ausgewählt';
|
||||
|
||||
@override
|
||||
String get all_players => 'Alle Spieler:';
|
||||
String get all_players => 'Alle Spieler:innen:';
|
||||
|
||||
@override
|
||||
String successfully_added_player(String playerName) {
|
||||
return 'Spieler $playerName erfolgreich hinzugefügt';
|
||||
return 'Spieler:in $playerName erfolgreich hinzugefügt';
|
||||
}
|
||||
|
||||
@override
|
||||
String could_not_add_player(String playerName) {
|
||||
return 'Spieler $playerName konnte nicht hinzugefügt werden';
|
||||
return 'Spieler:in $playerName konnte nicht hinzugefügt werden';
|
||||
}
|
||||
|
||||
@override
|
||||
String winner(String winnerName) {
|
||||
return 'Gewinner: $winnerName';
|
||||
return 'Gewinner:in: $winnerName';
|
||||
}
|
||||
|
||||
@override
|
||||
String get players => 'Spieler';
|
||||
String get players => 'Spieler:in';
|
||||
|
||||
@override
|
||||
String get no_statistics_available => 'Keine Statistiken verfügbar';
|
||||
@@ -97,12 +100,6 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
@override
|
||||
String get quick_create => 'Schnellzugriff';
|
||||
|
||||
@override
|
||||
String get winner_label => 'Gewinner';
|
||||
|
||||
@override
|
||||
String get ruleset_label => 'Regelwerk';
|
||||
|
||||
@override
|
||||
String get match_in_progress => 'Match läuft...';
|
||||
|
||||
@@ -168,7 +165,7 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get no_groups_created_yet => 'Noch keine Gruppen erstellt';
|
||||
|
||||
@override
|
||||
String get no_players_created_yet => 'Noch keine Spieler erstellt';
|
||||
String get no_players_created_yet => 'Noch keine Spieler:in erstellt';
|
||||
|
||||
@override
|
||||
String get create_group => 'Gruppe erstellen';
|
||||
@@ -177,7 +174,7 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get group_name => 'Gruppenname';
|
||||
|
||||
@override
|
||||
String get player_name => 'Spielername';
|
||||
String get player_name => 'Spieler:innenname';
|
||||
|
||||
@override
|
||||
String get no_matches_created_yet => 'Noch keine Matches erstellt';
|
||||
@@ -186,7 +183,7 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get match_name => 'Matchname';
|
||||
|
||||
@override
|
||||
String get game => 'Spiel';
|
||||
String get game => 'Spielvorlage';
|
||||
|
||||
@override
|
||||
String get ruleset => 'Regelwerk';
|
||||
@@ -205,10 +202,10 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get no_players_found_with_that_name =>
|
||||
'Keine Spieler mit diesem Namen gefunden';
|
||||
'Keine Spieler:in mit diesem Namen gefunden';
|
||||
|
||||
@override
|
||||
String get all_players_selected => 'Alle Spieler ausgewählt';
|
||||
String get all_players_selected => 'Alle Spieler:innen ausgewählt';
|
||||
|
||||
@override
|
||||
String today_at(String time) {
|
||||
@@ -244,29 +241,29 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
'Es gibt keine Gruppe, die deiner Suche entspricht';
|
||||
|
||||
@override
|
||||
String get game_name => 'Spielname';
|
||||
String get game_name => 'Spielvorlagenname';
|
||||
|
||||
@override
|
||||
String get ruleset_single_winner_desc =>
|
||||
'Genau ein Gewinner wird gewählt; Unentschieden werden durch einen vordefinierten Tie-Breaker aufgelöst.';
|
||||
String get ruleset_single_winner =>
|
||||
'Genau ein:e Gewinner:in wird gewählt; Unentschieden werden durch einen vordefinierten Tie-Breaker aufgelöst.';
|
||||
|
||||
@override
|
||||
String get ruleset_single_loser_desc =>
|
||||
'Genau ein Verlierer wird bestimmt; der letzte Platz erhält die Strafe oder Konsequenz.';
|
||||
String get ruleset_single_loser =>
|
||||
'Genau ein:e Verlierer:in wird bestimmt; der letzte Platz erhält die Strafe oder Konsequenz.';
|
||||
|
||||
@override
|
||||
String get ruleset_most_points_desc =>
|
||||
'Traditionelles Regelwerk: Der Spieler mit den meisten Punkten gewinnt.';
|
||||
String get ruleset_most_points =>
|
||||
'Traditionelles Regelwerk: Der/die Spieler:in mit den meisten Punkten gewinnt.';
|
||||
|
||||
@override
|
||||
String get ruleset_least_points_desc =>
|
||||
'Umgekehrte Wertung: Der Spieler mit den wenigsten Punkten gewinnt.';
|
||||
String get ruleset_least_points =>
|
||||
'Umgekehrte Wertung: Der/die Spieler:in mit den wenigsten Punkten gewinnt.';
|
||||
|
||||
@override
|
||||
String get single_winner => 'Ein Gewinner';
|
||||
String get single_winner => 'Ein:e Gewinner:in';
|
||||
|
||||
@override
|
||||
String get single_loser => 'Ein Verlierer';
|
||||
String get single_loser => 'Ein:e Verlierer:in';
|
||||
|
||||
@override
|
||||
String get most_points => 'Höchste Punkte';
|
||||
@@ -275,7 +272,7 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get least_points => 'Niedrigste Punkte';
|
||||
|
||||
@override
|
||||
String get search_for_players => 'Nach Spielern suchen';
|
||||
String get search_for_players => 'Nach Spieler:innen suchen';
|
||||
|
||||
@override
|
||||
String get search_for_groups => 'Nach Gruppen suchen';
|
||||
|
||||
@@ -23,6 +23,9 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
@override
|
||||
String get select_winner => 'Select Winner:';
|
||||
|
||||
@override
|
||||
String get game_tracker => 'Game Tracker';
|
||||
|
||||
@override
|
||||
String get no_recent_matches_available => 'No recent matches available';
|
||||
|
||||
@@ -42,7 +45,7 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get create_new_group => 'Create new group';
|
||||
|
||||
@override
|
||||
String get error_while_creating_group_please_try_again =>
|
||||
String get error_creating_group =>
|
||||
'Error while creating group, please try again';
|
||||
|
||||
@override
|
||||
@@ -97,12 +100,6 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
@override
|
||||
String get quick_create => 'Quick Create';
|
||||
|
||||
@override
|
||||
String get winner_label => 'Winner';
|
||||
|
||||
@override
|
||||
String get ruleset_label => 'Ruleset';
|
||||
|
||||
@override
|
||||
String get match_in_progress => 'Match in progress...';
|
||||
|
||||
@@ -246,19 +243,19 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
String get game_name => 'Game Name';
|
||||
|
||||
@override
|
||||
String get ruleset_single_winner_desc =>
|
||||
String get ruleset_single_winner =>
|
||||
'Exactly one winner is chosen; ties are resolved by a predefined tiebreaker.';
|
||||
|
||||
@override
|
||||
String get ruleset_single_loser_desc =>
|
||||
String get ruleset_single_loser =>
|
||||
'Exactly one loser is determined; last place receives the penalty or consequence.';
|
||||
|
||||
@override
|
||||
String get ruleset_most_points_desc =>
|
||||
String get ruleset_most_points =>
|
||||
'Traditional ruleset: the player with the most points wins.';
|
||||
|
||||
@override
|
||||
String get ruleset_least_points_desc =>
|
||||
String get ruleset_least_points =>
|
||||
'Inverse scoring: the player with the fewest points wins.';
|
||||
|
||||
@override
|
||||
|
||||
@@ -20,7 +20,6 @@ class GameTracker extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
print(AppLocalizations.supportedLocales.first);
|
||||
return MaterialApp(
|
||||
|
sneeex marked this conversation as resolved
Outdated
flixcoo
commented
Debug-Print entfernen Debug-Print entfernen
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
@@ -35,7 +34,7 @@ class GameTracker extends StatelessWidget {
|
||||
);
|
||||
},
|
||||
debugShowCheckedModeBanner: false,
|
||||
title: 'Game Tracker',
|
||||
onGenerateTitle: (context) => AppLocalizations.of(context).game_tracker,
|
||||
darkTheme: ThemeData.dark(),
|
||||
|
sneeex marked this conversation as resolved
Outdated
flixcoo
commented
Lokalisierung fehlt Lokalisierung fehlt
|
||||
|
||||
themeMode: ThemeMode.dark, // forces dark mode
|
||||
|
||||
@@ -20,13 +20,9 @@ class _CustomNavigationBarState extends State<CustomNavigationBar>
|
||||
int currentIndex = 0;
|
||||
int tabKeyCount = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
// Pretty ugly but works
|
||||
final List<Widget> tabs = [
|
||||
KeyedSubtree(key: ValueKey('home_$tabKeyCount'), child: const HomeView()),
|
||||
@@ -47,7 +43,7 @@ class _CustomNavigationBarState extends State<CustomNavigationBar>
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
title: Text(
|
||||
_currentTabTitle(),
|
||||
_currentTabTitle(context),
|
||||
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
backgroundColor: CustomTheme.backgroundColor,
|
||||
@@ -90,28 +86,28 @@ class _CustomNavigationBarState extends State<CustomNavigationBar>
|
||||
index: 0,
|
||||
isSelected: currentIndex == 0,
|
||||
icon: Icons.home_rounded,
|
||||
label: AppLocalizations.of(context).home,
|
||||
label: loc.home,
|
||||
onTabTapped: onTabTapped,
|
||||
),
|
||||
NavbarItem(
|
||||
index: 1,
|
||||
isSelected: currentIndex == 1,
|
||||
icon: Icons.gamepad_rounded,
|
||||
label: AppLocalizations.of(context).matches,
|
||||
label: loc.matches,
|
||||
onTabTapped: onTabTapped,
|
||||
),
|
||||
NavbarItem(
|
||||
index: 2,
|
||||
isSelected: currentIndex == 2,
|
||||
icon: Icons.group_rounded,
|
||||
label: AppLocalizations.of(context).groups,
|
||||
label: loc.groups,
|
||||
onTabTapped: onTabTapped,
|
||||
),
|
||||
NavbarItem(
|
||||
index: 3,
|
||||
isSelected: currentIndex == 3,
|
||||
icon: Icons.bar_chart_rounded,
|
||||
label: AppLocalizations.of(context).statistics,
|
||||
label: loc.statistics,
|
||||
onTabTapped: onTabTapped,
|
||||
),
|
||||
],
|
||||
@@ -129,16 +125,17 @@ class _CustomNavigationBarState extends State<CustomNavigationBar>
|
||||
});
|
||||
}
|
||||
|
||||
String _currentTabTitle() {
|
||||
String _currentTabTitle(context) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
switch (currentIndex) {
|
||||
case 0:
|
||||
return AppLocalizations.of(context).home;
|
||||
return loc.home;
|
||||
case 1:
|
||||
return AppLocalizations.of(context).matches;
|
||||
return loc.matches;
|
||||
case 2:
|
||||
return AppLocalizations.of(context).groups;
|
||||
return loc.groups;
|
||||
case 3:
|
||||
return AppLocalizations.of(context).statistics;
|
||||
return loc.statistics;
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -20,11 +20,13 @@ class CreateGroupView extends StatefulWidget {
|
||||
class _CreateGroupViewState extends State<CreateGroupView> {
|
||||
final _groupNameController = TextEditingController();
|
||||
late final AppDatabase db;
|
||||
|
||||
List<Player> selectedPlayers = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
db = Provider.of<AppDatabase>(context, listen: false);
|
||||
_groupNameController.addListener(() {
|
||||
setState(() {});
|
||||
@@ -39,13 +41,14 @@ class _CreateGroupViewState extends State<CreateGroupView> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
return Scaffold(
|
||||
backgroundColor: CustomTheme.backgroundColor,
|
||||
appBar: AppBar(
|
||||
backgroundColor: CustomTheme.backgroundColor,
|
||||
scrolledUnderElevation: 0,
|
||||
title: Text(
|
||||
AppLocalizations.of(context).create_new_group,
|
||||
loc.create_new_group,
|
||||
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
centerTitle: true,
|
||||
@@ -58,7 +61,7 @@ class _CreateGroupViewState extends State<CreateGroupView> {
|
||||
margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
||||
child: TextInputField(
|
||||
controller: _groupNameController,
|
||||
hintText: AppLocalizations.of(context).group_name,
|
||||
hintText: loc.group_name,
|
||||
onChanged: (value) {
|
||||
setState(() {});
|
||||
},
|
||||
@@ -74,7 +77,7 @@ class _CreateGroupViewState extends State<CreateGroupView> {
|
||||
),
|
||||
),
|
||||
CustomWidthButton(
|
||||
text: AppLocalizations.of(context).create_group,
|
||||
text: loc.create_group,
|
||||
sizeRelativeToWidth: 0.95,
|
||||
buttonType: ButtonType.primary,
|
||||
onPressed:
|
||||
@@ -99,7 +102,7 @@ class _CreateGroupViewState extends State<CreateGroupView> {
|
||||
child: Text(
|
||||
|
sneeex marked this conversation as resolved
Outdated
flixcoo
commented
Abkürzen für etwas generelles, z.B. Abkürzen für etwas generelles, z.B. `creating_group_error` oder `creating_group_error_message`
|
||||
AppLocalizations.of(
|
||||
context,
|
||||
).error_while_creating_group_please_try_again,
|
||||
).error_creating_group,
|
||||
style: const TextStyle(color: Colors.white),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -35,12 +35,14 @@ class _GroupsViewState extends State<GroupsView> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
db = Provider.of<AppDatabase>(context, listen: false);
|
||||
loadGroups();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
return Scaffold(
|
||||
backgroundColor: CustomTheme.backgroundColor,
|
||||
body: Stack(
|
||||
@@ -53,8 +55,8 @@ class _GroupsViewState extends State<GroupsView> {
|
||||
replacement: Center(
|
||||
child: TopCenteredMessage(
|
||||
icon: Icons.info,
|
||||
title: AppLocalizations.of(context).info,
|
||||
message: AppLocalizations.of(context).no_groups_created_yet,
|
||||
title: loc.info,
|
||||
message: loc.no_groups_created_yet,
|
||||
),
|
||||
),
|
||||
child: ListView.builder(
|
||||
@@ -74,7 +76,7 @@ class _GroupsViewState extends State<GroupsView> {
|
||||
Positioned(
|
||||
bottom: MediaQuery.paddingOf(context).bottom,
|
||||
child: CustomWidthButton(
|
||||
text: AppLocalizations.of(context).create_group,
|
||||
text: loc.create_group,
|
||||
sizeRelativeToWidth: 0.90,
|
||||
onPressed: () async {
|
||||
await Navigator.push(
|
||||
|
||||
@@ -72,6 +72,7 @@ class _HomeViewState extends State<HomeView> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
return LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
return AppSkeleton(
|
||||
@@ -87,7 +88,7 @@ class _HomeViewState extends State<HomeView> {
|
||||
QuickInfoTile(
|
||||
width: constraints.maxWidth * 0.45,
|
||||
height: constraints.maxHeight * 0.15,
|
||||
title: AppLocalizations.of(context).matches,
|
||||
title: loc.matches,
|
||||
icon: Icons.groups_rounded,
|
||||
value: matchCount,
|
||||
),
|
||||
@@ -95,7 +96,7 @@ class _HomeViewState extends State<HomeView> {
|
||||
QuickInfoTile(
|
||||
width: constraints.maxWidth * 0.45,
|
||||
height: constraints.maxHeight * 0.15,
|
||||
title: AppLocalizations.of(context).groups,
|
||||
title: loc.groups,
|
||||
icon: Icons.groups_rounded,
|
||||
value: groupCount,
|
||||
),
|
||||
@@ -105,7 +106,7 @@ class _HomeViewState extends State<HomeView> {
|
||||
padding: const EdgeInsets.symmetric(vertical: 16.0),
|
||||
child: InfoTile(
|
||||
width: constraints.maxWidth * 0.95,
|
||||
title: AppLocalizations.of(context).recent_matches,
|
||||
title: loc.recent_matches,
|
||||
icon: Icons.timer,
|
||||
content: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 40.0),
|
||||
@@ -125,11 +126,12 @@ class _HomeViewState extends State<HomeView> {
|
||||
children: [
|
||||
MatchSummaryTile(
|
||||
matchTitle: recentMatches[0].name,
|
||||
game: AppLocalizations.of(context).winner_label,
|
||||
ruleset: AppLocalizations.of(
|
||||
game: 'Winner',
|
||||
ruleset: 'Ruleset',
|
||||
players: _getPlayerText(
|
||||
|
sneeex marked this conversation as resolved
Outdated
flixcoo
commented
Wenn Wenn `winner_label`und `ruleset_label` nirgends anders verwendet werden, einfach die normalen Strings belassen, weil diese ja in Zukunft durch das Ruleset und das Game ersetzt werden
|
||||
recentMatches[0],
|
||||
context,
|
||||
).ruleset_label,
|
||||
players: _getPlayerText(recentMatches[0]),
|
||||
),
|
||||
winner: recentMatches[0].winner == null
|
||||
? AppLocalizations.of(
|
||||
context,
|
||||
@@ -143,11 +145,12 @@ class _HomeViewState extends State<HomeView> {
|
||||
if (loadedRecentMatches.length > 1) ...[
|
||||
MatchSummaryTile(
|
||||
matchTitle: recentMatches[1].name,
|
||||
game: AppLocalizations.of(context).winner_label,
|
||||
ruleset: AppLocalizations.of(
|
||||
game: 'Winner',
|
||||
ruleset: 'Ruleset',
|
||||
players: _getPlayerText(
|
||||
recentMatches[1],
|
||||
context,
|
||||
).ruleset_label,
|
||||
players: _getPlayerText(recentMatches[1]),
|
||||
),
|
||||
winner: recentMatches[1].winner == null
|
||||
? AppLocalizations.of(
|
||||
context,
|
||||
@@ -173,7 +176,7 @@ class _HomeViewState extends State<HomeView> {
|
||||
),
|
||||
InfoTile(
|
||||
width: constraints.maxWidth * 0.95,
|
||||
title: AppLocalizations.of(context).quick_create,
|
||||
title: loc.quick_create,
|
||||
icon: Icons.add_box_rounded,
|
||||
content: Column(
|
||||
children: [
|
||||
@@ -227,10 +230,11 @@ class _HomeViewState extends State<HomeView> {
|
||||
);
|
||||
}
|
||||
|
||||
String _getPlayerText(Match game) {
|
||||
String _getPlayerText(Match game, context) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
if (game.group == null) {
|
||||
final playerCount = game.players?.length ?? 0;
|
||||
return AppLocalizations.of(context).players_count(playerCount);
|
||||
return loc.players_count(playerCount);
|
||||
}
|
||||
if (game.players == null || game.players!.isEmpty) {
|
||||
return game.group!.name;
|
||||
|
||||
@@ -21,6 +21,7 @@ class ChooseGameView extends StatefulWidget {
|
||||
|
||||
class _ChooseGameViewState extends State<ChooseGameView> {
|
||||
late int selectedGameIndex;
|
||||
|
||||
final TextEditingController searchBarController = TextEditingController();
|
||||
|
||||
@override
|
||||
@@ -31,6 +32,7 @@ class _ChooseGameViewState extends State<ChooseGameView> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
return Scaffold(
|
||||
backgroundColor: CustomTheme.backgroundColor,
|
||||
appBar: AppBar(
|
||||
@@ -43,7 +45,7 @@ class _ChooseGameViewState extends State<ChooseGameView> {
|
||||
},
|
||||
),
|
||||
title: Text(
|
||||
AppLocalizations.of(context).choose_game,
|
||||
loc.choose_game,
|
||||
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
centerTitle: true,
|
||||
@@ -64,7 +66,7 @@ class _ChooseGameViewState extends State<ChooseGameView> {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
child: CustomSearchBar(
|
||||
controller: searchBarController,
|
||||
hintText: AppLocalizations.of(context).game_name,
|
||||
hintText: loc.game_name,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
@@ -76,9 +78,9 @@ class _ChooseGameViewState extends State<ChooseGameView> {
|
||||
title: widget.games[index].$1,
|
||||
description: widget.games[index].$2,
|
||||
badgeText: translateRulesetToString(
|
||||
widget.games[index].$3,
|
||||
context,
|
||||
),
|
||||
widget.games[index].$3,
|
||||
context,
|
||||
),
|
||||
isHighlighted: selectedGameIndex == index,
|
||||
onPressed: () async {
|
||||
setState(() {
|
||||
|
||||
@@ -34,6 +34,7 @@ class _ChooseGroupViewState extends State<ChooseGroupView> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
return Scaffold(
|
||||
backgroundColor: CustomTheme.backgroundColor,
|
||||
appBar: AppBar(
|
||||
@@ -52,7 +53,7 @@ class _ChooseGroupViewState extends State<ChooseGroupView> {
|
||||
},
|
||||
),
|
||||
title: Text(
|
||||
AppLocalizations.of(context).choose_group,
|
||||
loc.choose_group,
|
||||
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
centerTitle: true,
|
||||
@@ -79,7 +80,7 @@ class _ChooseGroupViewState extends State<ChooseGroupView> {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
child: CustomSearchBar(
|
||||
controller: controller,
|
||||
hintText: AppLocalizations.of(context).search_for_groups,
|
||||
hintText: loc.search_for_groups,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
filterGroups(value);
|
||||
@@ -94,15 +95,15 @@ class _ChooseGroupViewState extends State<ChooseGroupView> {
|
||||
visible: widget.groups.isNotEmpty,
|
||||
replacement: TopCenteredMessage(
|
||||
icon: Icons.info,
|
||||
title: AppLocalizations.of(context).info,
|
||||
message: AppLocalizations.of(context).no_groups_created_yet,
|
||||
title: loc.info,
|
||||
message: loc.no_groups_created_yet,
|
||||
),
|
||||
child: TopCenteredMessage(
|
||||
icon: Icons.info,
|
||||
title: AppLocalizations.of(context).info,
|
||||
title: loc.info,
|
||||
message: AppLocalizations.of(
|
||||
context,
|
||||
).there_is_no_group_matching_your_search,
|
||||
context,
|
||||
).there_is_no_group_matching_your_search,
|
||||
),
|
||||
),
|
||||
child: ListView.builder(
|
||||
|
||||
@@ -29,6 +29,7 @@ class _ChooseRulesetViewState extends State<ChooseRulesetView> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
return DefaultTabController(
|
||||
length: 2,
|
||||
initialIndex: 0,
|
||||
@@ -48,7 +49,7 @@ class _ChooseRulesetViewState extends State<ChooseRulesetView> {
|
||||
},
|
||||
),
|
||||
title: Text(
|
||||
AppLocalizations.of(context).choose_ruleset,
|
||||
loc.choose_ruleset,
|
||||
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
centerTitle: true,
|
||||
@@ -82,9 +83,9 @@ class _ChooseRulesetViewState extends State<ChooseRulesetView> {
|
||||
});
|
||||
},
|
||||
title: translateRulesetToString(
|
||||
widget.rulesets[index].$1,
|
||||
context,
|
||||
),
|
||||
widget.rulesets[index].$1,
|
||||
context,
|
||||
),
|
||||
description: widget.rulesets[index].$2,
|
||||
isHighlighted: selectedRulesetIndex == index,
|
||||
);
|
||||
|
||||
@@ -90,23 +90,12 @@ class _CreateMatchViewState extends State<CreateMatchView> {
|
||||
}
|
||||
|
||||
List<(Ruleset, String)> _getRulesets(BuildContext context) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
return [
|
||||
(
|
||||
Ruleset.singleWinner,
|
||||
AppLocalizations.of(context).ruleset_single_winner_desc,
|
||||
),
|
||||
(
|
||||
Ruleset.singleLoser,
|
||||
AppLocalizations.of(context).ruleset_single_loser_desc,
|
||||
),
|
||||
(
|
||||
Ruleset.mostPoints,
|
||||
AppLocalizations.of(context).ruleset_most_points_desc,
|
||||
),
|
||||
(
|
||||
Ruleset.leastPoints,
|
||||
AppLocalizations.of(context).ruleset_least_points_desc,
|
||||
),
|
||||
(Ruleset.singleWinner, loc.ruleset_single_winner),
|
||||
(Ruleset.singleLoser, loc.ruleset_single_loser),
|
||||
|
sneeex marked this conversation as resolved
Outdated
flixcoo
commented
Warum Warum `_desc`?
|
||||
(Ruleset.mostPoints, loc.ruleset_most_points),
|
||||
(Ruleset.leastPoints, loc.ruleset_least_points),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -118,13 +107,14 @@ class _CreateMatchViewState extends State<CreateMatchView> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
return Scaffold(
|
||||
backgroundColor: CustomTheme.backgroundColor,
|
||||
appBar: AppBar(
|
||||
backgroundColor: CustomTheme.backgroundColor,
|
||||
scrolledUnderElevation: 0,
|
||||
title: Text(
|
||||
AppLocalizations.of(context).create_new_match,
|
||||
loc.create_new_match,
|
||||
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
centerTitle: true,
|
||||
@@ -141,9 +131,9 @@ class _CreateMatchViewState extends State<CreateMatchView> {
|
||||
),
|
||||
),
|
||||
ChooseTile(
|
||||
title: AppLocalizations.of(context).game,
|
||||
title: loc.game,
|
||||
trailingText: selectedGameIndex == -1
|
||||
? AppLocalizations.of(context).none
|
||||
? loc.none
|
||||
: games[selectedGameIndex].$1,
|
||||
onPressed: () async {
|
||||
selectedGameIndex = await Navigator.of(context).push(
|
||||
@@ -169,9 +159,9 @@ class _CreateMatchViewState extends State<CreateMatchView> {
|
||||
},
|
||||
),
|
||||
ChooseTile(
|
||||
title: AppLocalizations.of(context).ruleset,
|
||||
title: loc.ruleset,
|
||||
trailingText: selectedRuleset == null
|
||||
? AppLocalizations.of(context).none
|
||||
? loc.none
|
||||
: translateRulesetToString(selectedRuleset!, context),
|
||||
onPressed: () async {
|
||||
final rulesets = _getRulesets(context);
|
||||
@@ -192,9 +182,9 @@ class _CreateMatchViewState extends State<CreateMatchView> {
|
||||
},
|
||||
),
|
||||
ChooseTile(
|
||||
title: AppLocalizations.of(context).group,
|
||||
title: loc.group,
|
||||
trailingText: selectedGroup == null
|
||||
? AppLocalizations.of(context).none_group
|
||||
? loc.none_group
|
||||
: selectedGroup!.name,
|
||||
onPressed: () async {
|
||||
selectedGroup = await Navigator.of(context).push(
|
||||
@@ -231,7 +221,7 @@ class _CreateMatchViewState extends State<CreateMatchView> {
|
||||
),
|
||||
),
|
||||
CustomWidthButton(
|
||||
text: AppLocalizations.of(context).create_match,
|
||||
text: loc.create_match,
|
||||
sizeRelativeToWidth: 0.95,
|
||||
buttonType: ButtonType.primary,
|
||||
onPressed: _enableCreateGameButton()
|
||||
|
||||
@@ -36,6 +36,7 @@ class _MatchResultViewState extends State<MatchResultView> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
return Scaffold(
|
||||
backgroundColor: CustomTheme.backgroundColor,
|
||||
appBar: AppBar(
|
||||
@@ -81,7 +82,7 @@ class _MatchResultViewState extends State<MatchResultView> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
AppLocalizations.of(context).select_winner,
|
||||
loc.select_winner,
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
|
||||
@@ -44,12 +44,14 @@ class _MatchViewState extends State<MatchView> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
db = Provider.of<AppDatabase>(context, listen: false);
|
||||
loadGames();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
return Scaffold(
|
||||
backgroundColor: CustomTheme.backgroundColor,
|
||||
body: Stack(
|
||||
@@ -62,8 +64,8 @@ class _MatchViewState extends State<MatchView> {
|
||||
replacement: Center(
|
||||
child: TopCenteredMessage(
|
||||
icon: Icons.report,
|
||||
title: AppLocalizations.of(context).info,
|
||||
message: AppLocalizations.of(context).no_matches_created_yet,
|
||||
title: loc.info,
|
||||
message: loc.no_matches_created_yet,
|
||||
),
|
||||
),
|
||||
child: ListView.builder(
|
||||
@@ -97,7 +99,7 @@ class _MatchViewState extends State<MatchView> {
|
||||
Positioned(
|
||||
bottom: MediaQuery.paddingOf(context).bottom,
|
||||
child: CustomWidthButton(
|
||||
text: AppLocalizations.of(context).create_match,
|
||||
text: loc.create_match,
|
||||
sizeRelativeToWidth: 0.90,
|
||||
onPressed: () async {
|
||||
Navigator.push(
|
||||
|
||||
@@ -13,8 +13,14 @@ class SettingsView extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _SettingsViewState extends State<SettingsView> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
return Scaffold(
|
||||
appBar: AppBar(backgroundColor: CustomTheme.backgroundColor),
|
||||
backgroundColor: CustomTheme.backgroundColor,
|
||||
@@ -29,7 +35,7 @@ class _SettingsViewState extends State<SettingsView> {
|
||||
padding: const EdgeInsets.fromLTRB(24, 0, 24, 10),
|
||||
child: Text(
|
||||
textAlign: TextAlign.start,
|
||||
AppLocalizations.of(context).menu,
|
||||
loc.menu,
|
||||
style: const TextStyle(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -43,7 +49,7 @@ class _SettingsViewState extends State<SettingsView> {
|
||||
),
|
||||
child: Text(
|
||||
textAlign: TextAlign.start,
|
||||
AppLocalizations.of(context).settings,
|
||||
loc.settings,
|
||||
style: const TextStyle(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -51,7 +57,7 @@ class _SettingsViewState extends State<SettingsView> {
|
||||
),
|
||||
),
|
||||
SettingsListTile(
|
||||
title: AppLocalizations.of(context).export_data,
|
||||
title: loc.export_data,
|
||||
icon: Icons.upload_outlined,
|
||||
suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16),
|
||||
onPressed: () async {
|
||||
@@ -66,7 +72,7 @@ class _SettingsViewState extends State<SettingsView> {
|
||||
},
|
||||
),
|
||||
SettingsListTile(
|
||||
title: AppLocalizations.of(context).import_data,
|
||||
title: loc.import_data,
|
||||
icon: Icons.download_outlined,
|
||||
suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16),
|
||||
onPressed: () async {
|
||||
@@ -78,27 +84,23 @@ class _SettingsViewState extends State<SettingsView> {
|
||||
},
|
||||
),
|
||||
SettingsListTile(
|
||||
title: AppLocalizations.of(context).delete_all_data,
|
||||
title: loc.delete_all_data,
|
||||
icon: Icons.download_outlined,
|
||||
suffixWidget: const Icon(Icons.arrow_forward_ios, size: 16),
|
||||
onPressed: () {
|
||||
showDialog<bool>(
|
||||
context: context,
|
||||
|
flixcoo marked this conversation as resolved
Outdated
flixcoo
commented
Hier auch sowas wie Hier auch sowas wie `popup` oder so mit einbauen, dass klar wird, wozu dieser text ist
sneeex
commented
finde nicht, das kann man für verschiedene sachen nutzen und reicht so m. M. n. finde nicht, das kann man für verschiedene sachen nutzen und reicht so m. M. n.
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text(
|
||||
AppLocalizations.of(context).delete_all_data,
|
||||
),
|
||||
content: Text(
|
||||
AppLocalizations.of(context).this_cannot_be_undone,
|
||||
),
|
||||
title: Text(loc.delete_all_data),
|
||||
content: Text(loc.this_cannot_be_undone),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(false),
|
||||
child: Text(AppLocalizations.of(context).cancel),
|
||||
child: Text(loc.cancel),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(true),
|
||||
child: Text(AppLocalizations.of(context).delete),
|
||||
child: Text(loc.delete),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -130,37 +132,20 @@ class _SettingsViewState extends State<SettingsView> {
|
||||
required BuildContext context,
|
||||
required ImportResult result,
|
||||
}) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
switch (result) {
|
||||
case ImportResult.success:
|
||||
|
flixcoo marked this conversation as resolved
Outdated
flixcoo
commented
hier sowas wie hier sowas wie `snackbar`?
sneeex
commented
auch nicht relevant m. M. n. auch nicht relevant m. M. n.
|
||||
showSnackbar(
|
||||
context: context,
|
||||
message: AppLocalizations.of(context).data_successfully_imported,
|
||||
);
|
||||
showSnackbar(context: context, message: loc.data_successfully_imported);
|
||||
case ImportResult.invalidSchema:
|
||||
showSnackbar(
|
||||
context: context,
|
||||
message: AppLocalizations.of(context).invalid_schema,
|
||||
);
|
||||
showSnackbar(context: context, message: loc.invalid_schema);
|
||||
case ImportResult.fileReadError:
|
||||
showSnackbar(
|
||||
context: context,
|
||||
message: AppLocalizations.of(context).error_reading_file,
|
||||
);
|
||||
showSnackbar(context: context, message: loc.error_reading_file);
|
||||
case ImportResult.canceled:
|
||||
showSnackbar(
|
||||
context: context,
|
||||
message: AppLocalizations.of(context).import_canceled,
|
||||
);
|
||||
showSnackbar(context: context, message: loc.import_canceled);
|
||||
case ImportResult.formatException:
|
||||
showSnackbar(
|
||||
context: context,
|
||||
message: AppLocalizations.of(context).format_exception,
|
||||
);
|
||||
showSnackbar(context: context, message: loc.format_exception);
|
||||
case ImportResult.unknownException:
|
||||
showSnackbar(
|
||||
context: context,
|
||||
message: AppLocalizations.of(context).unknown_exception,
|
||||
);
|
||||
showSnackbar(context: context, message: loc.unknown_exception);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,22 +157,14 @@ class _SettingsViewState extends State<SettingsView> {
|
||||
required BuildContext context,
|
||||
required ExportResult result,
|
||||
}) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
switch (result) {
|
||||
case ExportResult.success:
|
||||
showSnackbar(
|
||||
context: context,
|
||||
message: AppLocalizations.of(context).data_successfully_exported,
|
||||
);
|
||||
showSnackbar(context: context, message: loc.data_successfully_exported);
|
||||
case ExportResult.canceled:
|
||||
showSnackbar(
|
||||
context: context,
|
||||
message: AppLocalizations.of(context).export_canceled,
|
||||
);
|
||||
showSnackbar(context: context, message: loc.export_canceled);
|
||||
case ExportResult.unknownException:
|
||||
showSnackbar(
|
||||
context: context,
|
||||
message: AppLocalizations.of(context).unknown_exception,
|
||||
);
|
||||
showSnackbar(context: context, message: loc.unknown_exception);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,6 +180,7 @@ class _SettingsViewState extends State<SettingsView> {
|
||||
Duration duration = const Duration(seconds: 3),
|
||||
VoidCallback? action,
|
||||
}) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
final messenger = ScaffoldMessenger.of(context);
|
||||
messenger.hideCurrentSnackBar();
|
||||
messenger.showSnackBar(
|
||||
@@ -211,10 +189,7 @@ class _SettingsViewState extends State<SettingsView> {
|
||||
backgroundColor: CustomTheme.onBoxColor,
|
||||
duration: duration,
|
||||
action: action != null
|
||||
? SnackBarAction(
|
||||
label: AppLocalizations.of(context).undo,
|
||||
onPressed: action,
|
||||
)
|
||||
? SnackBarAction(label: loc.undo, onPressed: action)
|
||||
: null,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -25,6 +25,7 @@ class _StatisticsViewState extends State<StatisticsView> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
final db = Provider.of<AppDatabase>(context, listen: false);
|
||||
|
||||
Future.wait([
|
||||
@@ -32,21 +33,25 @@ class _StatisticsViewState extends State<StatisticsView> {
|
||||
db.playerDao.getAllPlayers(),
|
||||
Future.delayed(minimumSkeletonDuration),
|
||||
]).then((results) async {
|
||||
if (!mounted) return;
|
||||
final matches = results[0] as List<Match>;
|
||||
final players = results[1] as List<Player>;
|
||||
winCounts = _calculateWinsForAllPlayers(matches, players);
|
||||
matchCounts = _calculateMatchAmountsForAllPlayers(matches, players);
|
||||
winCounts = _calculateWinsForAllPlayers(matches, players, context);
|
||||
matchCounts = _calculateMatchAmountsForAllPlayers(
|
||||
matches,
|
||||
players,
|
||||
context,
|
||||
);
|
||||
winRates = computeWinRatePercent(wins: winCounts, matches: matchCounts);
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
}
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
return LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
return SingleChildScrollView(
|
||||
@@ -69,7 +74,7 @@ class _StatisticsViewState extends State<StatisticsView> {
|
||||
children: [
|
||||
StatisticsTile(
|
||||
icon: Icons.sports_score,
|
||||
title: AppLocalizations.of(context).wins,
|
||||
title: loc.wins,
|
||||
width: constraints.maxWidth * 0.95,
|
||||
values: winCounts,
|
||||
itemCount: 3,
|
||||
@@ -78,7 +83,7 @@ class _StatisticsViewState extends State<StatisticsView> {
|
||||
SizedBox(height: constraints.maxHeight * 0.02),
|
||||
StatisticsTile(
|
||||
icon: Icons.percent,
|
||||
title: AppLocalizations.of(context).winrate,
|
||||
title: loc.winrate,
|
||||
width: constraints.maxWidth * 0.95,
|
||||
values: winRates,
|
||||
itemCount: 5,
|
||||
@@ -87,7 +92,7 @@ class _StatisticsViewState extends State<StatisticsView> {
|
||||
SizedBox(height: constraints.maxHeight * 0.02),
|
||||
StatisticsTile(
|
||||
icon: Icons.casino,
|
||||
title: AppLocalizations.of(context).amount_of_matches,
|
||||
title: loc.amount_of_matches,
|
||||
width: constraints.maxWidth * 0.95,
|
||||
values: matchCounts,
|
||||
itemCount: 10,
|
||||
@@ -97,7 +102,7 @@ class _StatisticsViewState extends State<StatisticsView> {
|
||||
),
|
||||
child: TopCenteredMessage(
|
||||
icon: Icons.info,
|
||||
title: AppLocalizations.of(context).info,
|
||||
title: loc.info,
|
||||
message: AppLocalizations.of(
|
||||
context,
|
||||
).no_statistics_available,
|
||||
@@ -118,8 +123,10 @@ class _StatisticsViewState extends State<StatisticsView> {
|
||||
List<(String, int)> _calculateWinsForAllPlayers(
|
||||
List<Match> matches,
|
||||
List<Player> players,
|
||||
BuildContext context,
|
||||
) {
|
||||
List<(String, int)> winCounts = [];
|
||||
final loc = AppLocalizations.of(context);
|
||||
|
||||
// Getting the winners
|
||||
for (var match in matches) {
|
||||
@@ -150,10 +157,7 @@ class _StatisticsViewState extends State<StatisticsView> {
|
||||
final playerId = winCounts[i].$1;
|
||||
final player = players.firstWhere(
|
||||
(p) => p.id == playerId,
|
||||
orElse: () => Player(
|
||||
id: playerId,
|
||||
name: AppLocalizations.of(context).not_available,
|
||||
),
|
||||
orElse: () => Player(id: playerId, name: loc.not_available),
|
||||
);
|
||||
winCounts[i] = (player.name, winCounts[i].$2);
|
||||
}
|
||||
@@ -168,8 +172,10 @@ class _StatisticsViewState extends State<StatisticsView> {
|
||||
List<(String, int)> _calculateMatchAmountsForAllPlayers(
|
||||
List<Match> matches,
|
||||
List<Player> players,
|
||||
BuildContext context,
|
||||
) {
|
||||
List<(String, int)> matchCounts = [];
|
||||
final loc = AppLocalizations.of(context);
|
||||
|
||||
// Counting matches for each player
|
||||
for (var match in matches) {
|
||||
@@ -215,10 +221,7 @@ class _StatisticsViewState extends State<StatisticsView> {
|
||||
final playerId = matchCounts[i].$1;
|
||||
final player = players.firstWhere(
|
||||
(p) => p.id == playerId,
|
||||
orElse: () => Player(
|
||||
id: playerId,
|
||||
name: AppLocalizations.of(context).not_available,
|
||||
),
|
||||
orElse: () => Player(id: playerId, name: loc.not_available),
|
||||
);
|
||||
matchCounts[i] = (player.name, matchCounts[i].$2);
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@ class _PlayerSelectionState extends State<PlayerSelection> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
||||
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 10),
|
||||
@@ -97,7 +98,7 @@ class _PlayerSelectionState extends State<PlayerSelection> {
|
||||
CustomSearchBar(
|
||||
controller: _searchBarController,
|
||||
constraints: const BoxConstraints(maxHeight: 45, minHeight: 45),
|
||||
hintText: AppLocalizations.of(context).search_for_players,
|
||||
hintText: loc.search_for_players,
|
||||
trailingButtonShown: true,
|
||||
trailingButtonicon: Icons.add_circle,
|
||||
trailingButtonEnabled: _searchBarController.text.trim().isNotEmpty,
|
||||
@@ -139,11 +140,7 @@ class _PlayerSelectionState extends State<PlayerSelection> {
|
||||
SizedBox(
|
||||
height: 50,
|
||||
child: selectedPlayers.isEmpty
|
||||
? Center(
|
||||
child: Text(
|
||||
AppLocalizations.of(context).no_players_selected,
|
||||
),
|
||||
)
|
||||
? Center(child: Text(loc.no_players_selected))
|
||||
: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
@@ -185,7 +182,7 @@ class _PlayerSelectionState extends State<PlayerSelection> {
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
AppLocalizations.of(context).all_players,
|
||||
loc.all_players,
|
||||
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
@@ -196,8 +193,8 @@ class _PlayerSelectionState extends State<PlayerSelection> {
|
||||
visible: suggestedPlayers.isNotEmpty,
|
||||
replacement: TopCenteredMessage(
|
||||
icon: Icons.info,
|
||||
title: 'Info',
|
||||
message: _getInfoText(),
|
||||
title: loc.info,
|
||||
message: _getInfoText(context),
|
||||
),
|
||||
child: ListView.builder(
|
||||
itemCount: suggestedPlayers.length,
|
||||
@@ -234,6 +231,7 @@ class _PlayerSelectionState extends State<PlayerSelection> {
|
||||
/// Shows a snackbar indicating success or failure.
|
||||
/// [context] - BuildContext to show the snackbar.
|
||||
void addNewPlayerFromSearch({required BuildContext context}) async {
|
||||
final loc = AppLocalizations.of(context);
|
||||
String playerName = _searchBarController.text.trim();
|
||||
Player createdPlayer = Player(name: playerName);
|
||||
bool success = await db.playerDao.addPlayer(player: createdPlayer);
|
||||
@@ -267,7 +265,7 @@ class _PlayerSelectionState extends State<PlayerSelection> {
|
||||
backgroundColor: CustomTheme.boxColor,
|
||||
content: Center(
|
||||
child: Text(
|
||||
AppLocalizations.of(context).could_not_add_player(playerName),
|
||||
loc.could_not_add_player(playerName),
|
||||
style: const TextStyle(color: Colors.white),
|
||||
),
|
||||
),
|
||||
@@ -278,18 +276,19 @@ class _PlayerSelectionState extends State<PlayerSelection> {
|
||||
|
||||
/// Determines the appropriate info text to display when no players
|
||||
/// are available in the suggested players list.
|
||||
String _getInfoText() {
|
||||
String _getInfoText(BuildContext context) {
|
||||
final loc = AppLocalizations.of(context);
|
||||
if (allPlayers.isEmpty) {
|
||||
// No players exist in the database
|
||||
return AppLocalizations.of(context).no_players_created_yet;
|
||||
return loc.no_players_created_yet;
|
||||
} else if (selectedPlayers.length == allPlayers.length ||
|
||||
widget.availablePlayers?.isEmpty == true) {
|
||||
// All players have been selected or
|
||||
// available players list is provided but empty
|
||||
return AppLocalizations.of(context).all_players_selected;
|
||||
return loc.all_players_selected;
|
||||
} else {
|
||||
// No players match the search query
|
||||
return AppLocalizations.of(context).no_players_found_with_that_name;
|
||||
return loc.no_players_found_with_that_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ class _MatchTileState extends State<MatchTile> {
|
||||
final group = widget.match.group;
|
||||
final winner = widget.match.winner;
|
||||
final allPlayers = _getAllPlayers();
|
||||
final loc = AppLocalizations.of(context);
|
||||
|
||||
return GestureDetector(
|
||||
onTap: widget.onTap,
|
||||
@@ -49,7 +50,7 @@ class _MatchTileState extends State<MatchTile> {
|
||||
),
|
||||
),
|
||||
Text(
|
||||
_formatDate(widget.match.createdAt),
|
||||
_formatDate(widget.match.createdAt, context),
|
||||
style: const TextStyle(fontSize: 12, color: Colors.grey),
|
||||
),
|
||||
],
|
||||
@@ -98,7 +99,7 @@ class _MatchTileState extends State<MatchTile> {
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
AppLocalizations.of(context).winner(winner.name),
|
||||
loc.winner(winner.name),
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
@@ -115,7 +116,7 @@ class _MatchTileState extends State<MatchTile> {
|
||||
|
||||
if (allPlayers.isNotEmpty) ...[
|
||||
Text(
|
||||
AppLocalizations.of(context).players,
|
||||
loc.players,
|
||||
style: const TextStyle(
|
||||
fontSize: 13,
|
||||
color: Colors.grey,
|
||||
@@ -137,9 +138,10 @@ class _MatchTileState extends State<MatchTile> {
|
||||
);
|
||||
}
|
||||
|
||||
String _formatDate(DateTime dateTime) {
|
||||
String _formatDate(DateTime dateTime, BuildContext context) {
|
||||
final now = DateTime.now();
|
||||
final difference = now.difference(dateTime);
|
||||
final loc = AppLocalizations.of(context);
|
||||
|
||||
if (difference.inDays == 0) {
|
||||
return AppLocalizations.of(
|
||||
@@ -150,7 +152,7 @@ class _MatchTileState extends State<MatchTile> {
|
||||
context,
|
||||
).yesterday_at(DateFormat('HH:mm').format(dateTime));
|
||||
} else if (difference.inDays < 7) {
|
||||
return AppLocalizations.of(context).days_ago(difference.inDays);
|
||||
return loc.days_ago(difference.inDays);
|
||||
} else {
|
||||
return DateFormat('MMM d, yyyy').format(dateTime);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ class StatisticsTile extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final maxBarWidth = MediaQuery.of(context).size.width * 0.65;
|
||||
final loc = AppLocalizations.of(context);
|
||||
|
||||
return InfoTile(
|
||||
width: width,
|
||||
@@ -36,7 +37,7 @@ class StatisticsTile extends StatelessWidget {
|
||||
visible: values.isNotEmpty,
|
||||
replacement: Center(
|
||||
heightFactor: 4,
|
||||
child: Text(AppLocalizations.of(context).no_data_available),
|
||||
child: Text(loc.no_data_available),
|
||||
),
|
||||
child: Column(
|
||||
children: List.generate(min(values.length, itemCount), (index) {
|
||||
|
||||
Reference in New Issue
Block a user
Gendern? (auch generell)