diff --git a/lib/data/dao/team_dao.dart b/lib/data/dao/team_dao.dart index e85e76f..a6f03f0 100644 --- a/lib/data/dao/team_dao.dart +++ b/lib/data/dao/team_dao.dart @@ -124,6 +124,24 @@ class TeamDao extends DatabaseAccessor with _$TeamDaoMixin { ); } + Future> getTeamsByMatchId({required String matchId}) async { + final playerMatchQuery = select(db.playerMatchTable) + ..where((pm) => pm.matchId.equals(matchId)); + final playerMatches = await playerMatchQuery.get(); + + if (playerMatches.isEmpty) return []; + + final teamIds = playerMatches + .map((pm) => pm.teamId) + .whereType() + .toSet(); + + final teams = await Future.wait( + teamIds.map((id) => getTeamById(teamId: id)), + ); + return teams; + } + /// Retrieves a [Team] by its [teamId], including its members. Future getTeamById({required String teamId}) async { final query = select(teamTable)..where((t) => t.id.equals(teamId)); diff --git a/lib/data/models/match.dart b/lib/data/models/match.dart index f7c81a2..4b14ff9 100644 --- a/lib/data/models/match.dart +++ b/lib/data/models/match.dart @@ -19,7 +19,7 @@ class Match { final bool isTeamMatch; final List? teams; final String notes; - Map scores; + final Map scores; Match({ required this.name, diff --git a/lib/presentation/views/main_menu/match_view/match_detail_view.dart b/lib/presentation/views/main_menu/match_view/match_detail_view.dart index 6a02bbc..e00ebc6 100644 --- a/lib/presentation/views/main_menu/match_view/match_detail_view.dart +++ b/lib/presentation/views/main_menu/match_view/match_detail_view.dart @@ -8,6 +8,8 @@ import 'package:tallee/core/custom_theme.dart'; import 'package:tallee/core/enums.dart'; import 'package:tallee/data/db/database.dart'; import 'package:tallee/data/models/match.dart'; +import 'package:tallee/data/models/score_entry.dart'; +import 'package:tallee/data/models/team.dart'; import 'package:tallee/l10n/generated/app_localizations.dart'; import 'package:tallee/presentation/views/main_menu/match_view/create_match/create_match_view.dart'; import 'package:tallee/presentation/views/main_menu/match_view/match_result_view.dart'; @@ -43,13 +45,19 @@ class MatchDetailView extends StatefulWidget { class _MatchDetailViewState extends State { late final AppDatabase db; - late Match match; + late Match localMatch; + + late List localTeams; + + late Map localScores; @override void initState() { super.initState(); db = Provider.of(context, listen: false); - match = widget.match; + localMatch = widget.match; + localScores = localMatch.scores; + localTeams = localMatch.teams ?? []; } @override @@ -83,7 +91,7 @@ class _MatchDetailViewState extends State { ), ).then((confirmed) async { if (confirmed! && context.mounted) { - await db.matchDao.deleteMatch(matchId: match.id); + await db.matchDao.deleteMatch(matchId: localMatch.id); if (!context.mounted) return; Navigator.pop(context); widget.onMatchUpdate.call(); @@ -117,7 +125,7 @@ class _MatchDetailViewState extends State { // Match Name Text( - match.name, + localMatch.name, style: const TextStyle( fontSize: 28, fontWeight: FontWeight.bold, @@ -129,7 +137,7 @@ class _MatchDetailViewState extends State { // Creation Date Text( - '${loc.created_on} ${DateFormat.yMMMd(Localizations.localeOf(context).toString()).format(match.createdAt)}', + '${loc.created_on} ${DateFormat.yMMMd(Localizations.localeOf(context).toString()).format(localMatch.createdAt)}', style: const TextStyle( fontSize: 12, color: CustomTheme.textColor, @@ -139,14 +147,14 @@ class _MatchDetailViewState extends State { const SizedBox(height: 10), // Group Name - if (match.group != null) ...[ + if (localMatch.group != null) ...[ Row( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon(Icons.group), const SizedBox(width: 8), Text( - '${match.group!.name}${getExtraPlayerCount(match)}', + '${localMatch.group!.name}${getExtraPlayerCount(localMatch)}', style: const TextStyle(fontWeight: FontWeight.bold), ), ], @@ -155,7 +163,7 @@ class _MatchDetailViewState extends State { ], // Teams or Players - if (match.isTeamMatch) ...[ + if (localMatch.isTeamMatch) ...[ // Teams InfoTile( title: loc.teams, @@ -166,7 +174,7 @@ class _MatchDetailViewState extends State { crossAxisAlignment: WrapCrossAlignment.start, spacing: 12, runSpacing: 8, - children: match.teams!.map((team) { + children: localMatch.teams!.map((team) { return TeamCard(team: team); }).toList(), ), @@ -182,7 +190,7 @@ class _MatchDetailViewState extends State { crossAxisAlignment: WrapCrossAlignment.start, spacing: 12, runSpacing: 8, - children: match.players.map((player) { + children: localMatch.players.map((player) { return TextIconTile( text: player.name, suffixText: getNameCountText(player), @@ -205,12 +213,12 @@ class _MatchDetailViewState extends State { horizontal: 8, ), child: GameLabel( - title: match.game.name, + title: localMatch.game.name, description: translateRulesetToString( - match.game.ruleset, + localMatch.game.ruleset, context, ), - color: match.game.color, + color: localMatch.game.color, ), ), ), @@ -241,7 +249,7 @@ class _MatchDetailViewState extends State { adaptivePageRoute( fullscreenDialog: true, builder: (context) => CreateMatchView( - matchToEdit: match, + matchToEdit: localMatch, onMatchUpdated: onMatchUpdated, ), ), @@ -257,12 +265,10 @@ class _MatchDetailViewState extends State { adaptivePageRoute( fullscreenDialog: true, builder: (context) => MatchResultView( - match: match, - onWinnerChanged: () { + match: localMatch, + onWinnerChanged: () async { widget.onMatchUpdate.call(); - setState(() { - updateScoresForCurrentMatch(); - }); + await updateScoresForCurrentMatch(); }, ), ), @@ -282,7 +288,7 @@ class _MatchDetailViewState extends State { /// updates the match in this view void onMatchUpdated(Match editedMatch) { setState(() { - match = editedMatch; + localMatch = editedMatch; }); widget.onMatchUpdate.call(); } @@ -302,13 +308,13 @@ class _MatchDetailViewState extends State { /// Returns the result row for single winner/loser rulesets or a placeholder /// if no result is entered yet List getSingleResultRow(AppLocalizations loc) { - final ruleset = match.game.ruleset; + final ruleset = localMatch.game.ruleset; - if (match.mvp.isNotEmpty || match.mvt.isNotEmpty) { + if (localMatch.mvp.isNotEmpty || localMatch.mvt.isNotEmpty) { // Single Winner / Loser - final mvpName = match.isTeamMatch - ? match.mvt.first.name - : match.mvp.first.name; + final mvpName = localMatch.isTeamMatch + ? localMatch.mvt.first.name + : localMatch.mvp.first.name; return [ Text( @@ -361,41 +367,41 @@ class _MatchDetailViewState extends State { /// Returns a list of player/team names and their corresponding scores, sorted by score according to the ruleset List<(String, int)> getSortedScores() { - List<(String, int)> scores = []; + List<(String, int)> namedScores = []; - if (match.isTeamMatch) { - for (var team in match.teams!) { + if (localMatch.isTeamMatch) { + for (var team in localTeams) { int score = team.score ?? 0; - scores.add((team.name, score)); + namedScores.add((team.name, score)); } - final ruleset = match.game.ruleset; + final ruleset = localMatch.game.ruleset; if (ruleset == Ruleset.highestScore || ruleset == Ruleset.placement) { - scores.sort((a, b) => b.$2.compareTo(a.$2)); + namedScores.sort((a, b) => b.$2.compareTo(a.$2)); } else if (ruleset == Ruleset.lowestScore) { - scores.sort((a, b) => a.$2.compareTo(b.$2)); + namedScores.sort((a, b) => a.$2.compareTo(b.$2)); } } else { - for (var player in match.players) { - int score = match.scores[player.id]?.score ?? 0; - scores.add((player.name, score)); + for (var player in localMatch.players) { + int score = localScores[player.id]?.score ?? 0; + namedScores.add((player.name, score)); } - final ruleset = match.game.ruleset; + final ruleset = localMatch.game.ruleset; if (ruleset == Ruleset.highestScore || ruleset == Ruleset.placement) { - scores.sort((a, b) => b.$2.compareTo(a.$2)); + namedScores.sort((a, b) => b.$2.compareTo(a.$2)); } else if (ruleset == Ruleset.lowestScore) { - scores.sort((a, b) => a.$2.compareTo(b.$2)); + namedScores.sort((a, b) => a.$2.compareTo(b.$2)); } } - return scores; + return namedScores; } /// Returns the text widget for the score or placement value, styled according to the ruleset Widget getResultValueText(AppLocalizations loc, int index, int score) { - final ruleset = match.game.ruleset; + final ruleset = localMatch.game.ruleset; if (ruleset == Ruleset.placement) { return Text( @@ -433,8 +439,8 @@ class _MatchDetailViewState extends State { // Returns if the result can be displayed in a single row bool isSingleRowResult() { - return match.game.ruleset == Ruleset.singleWinner || - match.game.ruleset == Ruleset.singleLoser; + return localMatch.game.ruleset == Ruleset.singleWinner || + localMatch.game.ruleset == Ruleset.singleLoser; } String getPlacementText(BuildContext context, int rank) { @@ -465,9 +471,16 @@ class _MatchDetailViewState extends State { } } - void updateScoresForCurrentMatch() { - db.scoreEntryDao - .getAllMatchScores(matchId: match.id) - .then((scores) => match.scores = scores); + // Die Methode selbst: + Future updateScoresForCurrentMatch() async { + if (widget.match.isTeamMatch) { + final teams = await db.teamDao.getTeamsByMatchId(matchId: localMatch.id); + if (mounted) setState(() => localTeams = teams); + } else { + final scores = await db.scoreEntryDao.getAllMatchScores( + matchId: localMatch.id, + ); + if (mounted) setState(() => localScores = scores); + } } } diff --git a/lib/presentation/views/main_menu/match_view/match_result_view.dart b/lib/presentation/views/main_menu/match_view/match_result_view.dart index 4287d5b..fac95bf 100644 --- a/lib/presentation/views/main_menu/match_view/match_result_view.dart +++ b/lib/presentation/views/main_menu/match_view/match_result_view.dart @@ -186,7 +186,7 @@ class _MatchResultViewState extends State { ); await _handleSaving(); if (!context.mounted) return; - Navigator.of(context).pop(_selectedPlayer); + Navigator.pop(context); } : null, ), diff --git a/pubspec.yaml b/pubspec.yaml index 18f210e..be86af2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: tallee description: "Tracking App for Card Games" publish_to: 'none' -version: 0.0.30+299 +version: 0.0.30+304 environment: sdk: ^3.8.1