Lokalisierung erweitert

This commit is contained in:
2025-06-27 19:28:22 +02:00
parent 7710646cd0
commit 943b0440aa
9 changed files with 168 additions and 24 deletions

View File

@@ -64,7 +64,12 @@
"done": "Fertig",
"next_round": "Nächste Runde",
"game_statistics": "Spielstatistiken",
"statistics": "Statistiken",
"delete_game": "Spiel löschen",
"new_game_same_settings": "Neues Spiel mit gleichen Einstellungen",
"export_game": "Spiel exportieren",
"game_process": "Spielverlauf",
"settings": "Einstellungen",
"cabo_penalty": "Cabo-Strafe",

View File

@@ -14,6 +14,7 @@
"player": "Player",
"players": "Players",
"name": "Name",
"back": "Back",
"home": "Home",
"about": "About",
@@ -63,6 +64,13 @@
"done": "Done",
"next_round": "Next Round",
"statistics": "Statistics",
"delete_game": "Delete Game",
"new_game_same_settings": "New Game with same Settings",
"export_game": "Export Game",
"game_process": "Spielverlauf",
"settings": "Settings",
"cabo_penalty": "Cabo Penalty",
"cabo_penalty_subtitle": "... for falsely calling Cabo.",
@@ -80,5 +88,6 @@
"app_version": "App Version",
"load_version": "Loading version...",
"build": "Build",
"about_text": "Hey :) Thanks for being one of the first users of my app! Ive 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!"
}

View File

@@ -362,11 +362,35 @@ abstract class AppLocalizations {
/// **'Nächste Runde'**
String get next_round;
/// No description provided for @game_statistics.
/// No description provided for @statistics.
///
/// In de, this message translates to:
/// **'Spielstatistiken'**
String get game_statistics;
/// **'Statistiken'**
String get statistics;
/// No description provided for @delete_game.
///
/// In de, this message translates to:
/// **'Spiel löschen'**
String get delete_game;
/// No description provided for @new_game_same_settings.
///
/// In de, this message translates to:
/// **'Neues Spiel mit gleichen Einstellungen'**
String get new_game_same_settings;
/// No description provided for @export_game.
///
/// In de, this message translates to:
/// **'Spiel exportieren'**
String get export_game;
/// No description provided for @game_process.
///
/// In de, this message translates to:
/// **'Spielverlauf'**
String get game_process;
/// No description provided for @settings.
///

View File

@@ -150,7 +150,19 @@ class AppLocalizationsDe extends AppLocalizations {
String get next_round => 'Nächste Runde';
@override
String get game_statistics => 'Spielstatistiken';
String get statistics => 'Statistiken';
@override
String get delete_game => 'Spiel löschen';
@override
String get new_game_same_settings => 'Neues Spiel mit gleichen Einstellungen';
@override
String get export_game => 'Spiel exportieren';
@override
String get game_process => 'Spielverlauf';
@override
String get settings => 'Einstellungen';

View File

@@ -48,7 +48,7 @@ class AppLocalizationsEn extends AppLocalizations {
String get name => 'Name';
@override
String get back => 'Zurück';
String get back => 'Back';
@override
String get home => 'Home';
@@ -147,7 +147,19 @@ class AppLocalizationsEn extends AppLocalizations {
String get next_round => 'Next Round';
@override
String get game_statistics => 'Spielstatistiken';
String get statistics => 'Statistics';
@override
String get delete_game => 'Delete Game';
@override
String get new_game_same_settings => 'New Game with same Settings';
@override
String get export_game => 'Export Game';
@override
String get game_process => 'Spielverlauf';
@override
String get settings => 'Settings';

View File

@@ -1,6 +1 @@
{
"en": [
"back",
"game_statistics"
]
}
{}

View File

@@ -82,6 +82,8 @@ class _ActiveGameViewState extends State<ActiveGameView> {
return Padding(
padding: const EdgeInsets.all(1),
child: CupertinoListTile(
backgroundColorActivated:
CustomTheme.backgroundColor,
title: Text(
'${AppLocalizations.of(context).round} ${index + 1}',
),
@@ -119,17 +121,39 @@ class _ActiveGameViewState extends State<ActiveGameView> {
Column(
children: [
CupertinoListTile(
title: const Text('Statistiken'),
backgroundColorActivated:
CustomTheme.backgroundColor,
title: Text(
AppLocalizations.of(context).statistics,
),
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const GraphView()))),
const CupertinoListTile(title: Text('Spiel löschen')),
const CupertinoListTile(
builder: (_) => GraphView(
gameSession: widget.gameSession,
)))),
CupertinoListTile(
title:
Text(AppLocalizations.of(context).delete_game,
style: const TextStyle(
color: Colors.white30,
)),
onTap: () {},
),
CupertinoListTile(
title: Text(
'Neues Spiel mit gleichen Einstellungen')),
const CupertinoListTile(
title: Text('Spiel exportieren')),
AppLocalizations.of(context)
.new_game_same_settings,
style: const TextStyle(
color: Colors.white30,
))),
CupertinoListTile(
title:
Text(AppLocalizations.of(context).export_game,
style: const TextStyle(
color: Colors.white30,
)),
),
],
)
],

View File

@@ -1,22 +1,84 @@
import 'package:cabo_counter/data/game_session.dart';
import 'package:cabo_counter/l10n/app_localizations.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
class GraphView extends StatefulWidget {
const GraphView({super.key});
final GameSession gameSession;
const GraphView({super.key, required this.gameSession});
@override
State<GraphView> createState() => _GraphViewState();
}
class _GraphViewState extends State<GraphView> {
/// List of colors for the graph lines.
List<Color> lineColors = [
Colors.red,
Colors.blue,
Colors.orange.shade400,
Colors.purple,
Colors.green,
];
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text(AppLocalizations.of(context).game_statistics),
middle: Text(AppLocalizations.of(context).game_process),
previousPageTitle: AppLocalizations.of(context).back,
),
child: const Center(child: Text('GraphView')),
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 100, 0, 0),
child: SfCartesianChart(
legend:
const Legend(isVisible: true, position: LegendPosition.bottom),
primaryXAxis: const NumericAxis(),
primaryYAxis: const NumericAxis(),
series: getCumulativeScores(),
),
),
);
}
/// Returns a list of LineSeries representing the cumulative scores of each player.
/// Each series contains data points for each round, showing the cumulative score up to that round.
/// The x-axis represents the round number, and the y-axis represents the cumulative score.
List<LineSeries<(int, int), int>> getCumulativeScores() {
final rounds = widget.gameSession.roundList;
final playerCount = widget.gameSession.players.length;
final playerNames = widget.gameSession.players;
List<List<int>> cumulativeScores = List.generate(playerCount, (_) => []);
List<int> runningTotals = List.filled(playerCount, 0);
for (var round in rounds) {
for (int i = 0; i < playerCount; i++) {
runningTotals[i] += round.scores[i];
cumulativeScores[i].add(runningTotals[i]);
}
}
/// Create a list of LineSeries for each player
/// Each series contains data points for each round
return List.generate(playerCount, (i) {
final data = List.generate(
cumulativeScores[i].length,
(j) => (j + 1, cumulativeScores[i][j]), // (round, score)
);
/// Create a LineSeries for the player
/// The xValueMapper maps the round number, and the yValueMapper maps the cumulative score.
return LineSeries<(int, int), int>(
name: playerNames[i],
dataSource: data,
xValueMapper: (record, _) => record.$1, // Runde
yValueMapper: (record, _) => record.$2, // Punktestand
markerSettings: const MarkerSettings(isVisible: true),
color: lineColors[i],
);
});
}
}