fix: correct placement implementation

This commit is contained in:
2026-05-18 00:27:14 +02:00
parent 092dd5ec0a
commit 0a1e14a32d
3 changed files with 67 additions and 48 deletions

View File

@@ -154,6 +154,7 @@ class _MatchDetailViewState extends State<MatchDetailView> {
const SizedBox(height: 20), const SizedBox(height: 20),
], ],
// Teams or Players
if (match.isTeamMatch) ...[ if (match.isTeamMatch) ...[
// Teams // Teams
InfoTile( InfoTile(
@@ -301,15 +302,21 @@ class _MatchDetailViewState extends State<MatchDetailView> {
/// Returns the result row for single winner/loser rulesets or a placeholder /// Returns the result row for single winner/loser rulesets or a placeholder
/// if no result is entered yet /// if no result is entered yet
List<Widget> getSingleResultRow(AppLocalizations loc) { List<Widget> getSingleResultRow(AppLocalizations loc) {
// Single Winner final ruleset = match.game.ruleset;
if (match.mvp.isNotEmpty && match.game.ruleset == Ruleset.singleWinner) {
if (match.mvp.isNotEmpty || match.mvt.isNotEmpty) {
// Single Winner / Loser
final mvpName = match.isTeamMatch
? match.mvt.first.name
: match.mvp.first.name;
return [ return [
Text( Text(
loc.winner, ruleset == Ruleset.singleWinner ? loc.winner : loc.loser,
style: const TextStyle(fontSize: 16, color: CustomTheme.textColor), style: const TextStyle(fontSize: 16, color: CustomTheme.textColor),
), ),
Text( Text(
match.mvp.first.name, mvpName,
style: const TextStyle( style: const TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@@ -317,24 +324,8 @@ class _MatchDetailViewState extends State<MatchDetailView> {
), ),
), ),
]; ];
// Single Loser
} else if (match.game.ruleset == Ruleset.singleLoser) {
return [
Text(
loc.loser,
style: const TextStyle(fontSize: 16, color: CustomTheme.textColor),
),
Text(
match.mvp.first.name,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: CustomTheme.primaryColor,
),
),
];
// No result entered yet
} else { } else {
// No result entered yet
return [ return [
Text( Text(
loc.no_results_entered_yet, loc.no_results_entered_yet,
@@ -346,40 +337,63 @@ class _MatchDetailViewState extends State<MatchDetailView> {
/// Returns the result widget for scores or placement /// Returns the result widget for scores or placement
Widget getMultiResultRows(AppLocalizations loc) { Widget getMultiResultRows(AppLocalizations loc) {
List<(String, int)> playerScores = []; List<(String, int)> scores = getSortedScores();
for (var player in match.players) {
int score = match.scores[player.id]?.score ?? 0;
playerScores.add((player.name, score));
}
final ruleset = match.game.ruleset;
if (ruleset == Ruleset.highestScore || ruleset == Ruleset.placement) {
playerScores.sort((a, b) => b.$2.compareTo(a.$2));
} else if (ruleset == Ruleset.lowestScore) {
playerScores.sort((a, b) => a.$2.compareTo(b.$2));
}
return Column( return Column(
children: [ children: [
for (var i = 0; i < playerScores.length; i++) for (var i = 0; i < scores.length; i++)
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
playerScores[i].$1, scores[i].$1,
style: const TextStyle( style: const TextStyle(
fontSize: 16, fontSize: 16,
color: CustomTheme.textColor, color: CustomTheme.textColor,
), ),
), ),
getResultValueText(loc, i, playerScores[i].$2), getResultValueText(loc, i, scores[i].$2),
], ],
), ),
], ],
); );
} }
/// 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 = [];
if (match.isTeamMatch) {
for (var team in match.teams!) {
int score = team.score ?? 0;
scores.add((team.name, score));
}
final ruleset = match.game.ruleset;
if (ruleset == Ruleset.highestScore || ruleset == Ruleset.placement) {
scores.sort((a, b) => b.$2.compareTo(a.$2));
} else if (ruleset == Ruleset.lowestScore) {
scores.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));
}
final ruleset = match.game.ruleset;
if (ruleset == Ruleset.highestScore || ruleset == Ruleset.placement) {
scores.sort((a, b) => b.$2.compareTo(a.$2));
} else if (ruleset == Ruleset.lowestScore) {
scores.sort((a, b) => a.$2.compareTo(b.$2));
}
}
return scores;
}
/// Returns the text widget for the score or placement value, styled according to the ruleset
Widget getResultValueText(AppLocalizations loc, int index, int score) { Widget getResultValueText(AppLocalizations loc, int index, int score) {
final ruleset = match.game.ruleset; final ruleset = match.game.ruleset;

View File

@@ -197,7 +197,7 @@ class _MatchResultViewState extends State<MatchResultView> {
} }
void initializeAsTeamMatch() { void initializeAsTeamMatch() {
allTeams = widget.match.teams ?? []; allTeams = [...(widget.match.teams ?? [])];
allTeams.sort((a, b) => a.name.compareTo(b.name)); allTeams.sort((a, b) => a.name.compareTo(b.name));
controller = List.generate( controller = List.generate(
@@ -218,10 +218,8 @@ class _MatchResultViewState extends State<MatchResultView> {
} }
} else if (rulesetSupportsPlacement()) { } else if (rulesetSupportsPlacement()) {
allTeams.sort((a, b) { allTeams.sort((a, b) {
final scoreA = final scoreA = a.score ?? 0;
allTeams.where((team) => a.id == team.id).first.score ?? 0; final scoreB = b.score ?? 0;
final scoreB =
allTeams.where((team) => b.id == team.id).first.score ?? 0;
return scoreB.compareTo(scoreA); return scoreB.compareTo(scoreA);
}); });
} }
@@ -229,7 +227,7 @@ class _MatchResultViewState extends State<MatchResultView> {
} }
void inizializeAsNormalMatch() { void inizializeAsNormalMatch() {
allPlayers = widget.match.players; allPlayers = [...widget.match.players];
allPlayers.sort((a, b) => a.name.compareTo(b.name)); allPlayers.sort((a, b) => a.name.compareTo(b.name));
controller = List.generate( controller = List.generate(
@@ -370,10 +368,17 @@ class _MatchResultViewState extends State<MatchResultView> {
/// Handles saving the placement for each player in the database. /// Handles saving the placement for each player in the database.
Future<void> _handlePlacement() async { Future<void> _handlePlacement() async {
await db.scoreEntryDao.setPlacements( if (isTeamMatch) {
matchId: widget.match.id, await db.teamDao.setTeamPlacements(
players: allPlayers, matchId: widget.match.id,
); teams: allTeams,
);
} else {
await db.scoreEntryDao.setPlacements(
matchId: widget.match.id,
players: allPlayers,
);
}
} }
String getTitleForRuleset(AppLocalizations loc) { String getTitleForRuleset(AppLocalizations loc) {

View File

@@ -1,7 +1,7 @@
name: tallee name: tallee
description: "Tracking App for Card Games" description: "Tracking App for Card Games"
publish_to: 'none' publish_to: 'none'
version: 0.0.30+294 version: 0.0.30+299
environment: environment:
sdk: ^3.8.1 sdk: ^3.8.1