players cant be null
Some checks failed
Pull Request Pipeline / test (pull_request) Failing after 40s
Pull Request Pipeline / lint (pull_request) Failing after 44s

This commit is contained in:
gelbeinhalb
2026-02-01 18:23:58 +01:00
parent dbef735a82
commit 7aba8554c0
7 changed files with 46 additions and 61 deletions

View File

@@ -29,7 +29,7 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
} }
final players = await db.playerMatchDao.getPlayersOfMatch( final players = await db.playerMatchDao.getPlayersOfMatch(
matchId: row.id, matchId: row.id,
); ) ?? [];
return Match( return Match(
id: row.id, id: row.id,
name: row.name ?? '', name: row.name ?? '',
@@ -56,10 +56,7 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
group = await db.groupDao.getGroupById(groupId: result.groupId!); group = await db.groupDao.getGroupById(groupId: result.groupId!);
} }
List<Player>? players; final players = await db.playerMatchDao.getPlayersOfMatch(matchId: matchId) ?? [];
if (await db.playerMatchDao.matchHasPlayers(matchId: matchId)) {
players = await db.playerMatchDao.getPlayersOfMatch(matchId: matchId);
}
return Match( return Match(
id: result.id, id: result.id,
@@ -91,13 +88,11 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
mode: InsertMode.insertOrReplace, mode: InsertMode.insertOrReplace,
); );
if (match.players != null) { for (final p in match.players) {
for (final p in match.players!) { await db.playerMatchDao.addPlayerToMatch(
await db.playerMatchDao.addPlayerToMatch( matchId: match.id,
matchId: match.id, playerId: p.id,
playerId: p.id, );
);
}
} }
}); });
} }
@@ -180,10 +175,8 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
// Add all players of the matches in batch (unique) // Add all players of the matches in batch (unique)
final uniquePlayers = <String, Player>{}; final uniquePlayers = <String, Player>{};
for (final match in matches) { for (final match in matches) {
if (match.players != null) { for (final p in match.players) {
for (final p in match.players!) { uniquePlayers[p.id] = p;
uniquePlayers[p.id] = p;
}
} }
// Also include members of groups // Also include members of groups
if (match.group != null) { if (match.group != null) {
@@ -215,18 +208,16 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
// Add all player-match associations in batch // Add all player-match associations in batch
await db.batch((b) { await db.batch((b) {
for (final match in matches) { for (final match in matches) {
if (match.players != null) { for (final p in match.players) {
for (final p in match.players!) { b.insert(
b.insert( db.playerMatchTable,
db.playerMatchTable, PlayerMatchTableCompanion.insert(
PlayerMatchTableCompanion.insert( matchId: match.id,
matchId: match.id, playerId: p.id,
playerId: p.id, score: 0,
score: 0, ),
), mode: InsertMode.insertOrIgnore,
mode: InsertMode.insertOrIgnore, );
);
}
} }
} }
}); });
@@ -372,15 +363,15 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
/// TEMPORARY: Checks if a match has a winner. /// TEMPORARY: Checks if a match has a winner.
/// Currently returns true if the match has any players. /// Currently returns true if the match has any players.
Future<bool> hasWinner({required String matchId}) async { Future<bool> hasWinner({required String matchId}) async {
final players = await db.playerMatchDao.getPlayersOfMatch(matchId: matchId); final players = await db.playerMatchDao.getPlayersOfMatch(matchId: matchId) ?? [];
return players?.isNotEmpty ?? false; return players.isNotEmpty;
} }
/// TEMPORARY: Gets the winner of a match. /// TEMPORARY: Gets the winner of a match.
/// Currently returns the first player in the match's player list. /// Currently returns the first player in the match's player list.
Future<Player?> getWinner({required String matchId}) async { Future<Player?> getWinner({required String matchId}) async {
final players = await db.playerMatchDao.getPlayersOfMatch(matchId: matchId); final players = await db.playerMatchDao.getPlayersOfMatch(matchId: matchId) ?? [];
return (players?.isNotEmpty ?? false) ? players!.first : null; return players.isNotEmpty ? players.first : null;
} }
/// TEMPORARY: Sets the winner of a match. /// TEMPORARY: Sets the winner of a match.

View File

@@ -12,7 +12,7 @@ class Match {
final String name; final String name;
final Game game; final Game game;
final Group? group; final Group? group;
final List<Player>? players; final List<Player> players;
final String notes; final String notes;
Player? winner; Player? winner;
@@ -23,7 +23,7 @@ class Match {
required this.name, required this.name,
required this.game, required this.game,
this.group, this.group,
this.players, this.players = const [],
required this.notes, required this.notes,
this.winner, this.winner,
}) : id = id ?? const Uuid().v4(), }) : id = id ?? const Uuid().v4(),
@@ -54,7 +54,7 @@ class Match {
'name': name, 'name': name,
'gameId': game.id, 'gameId': game.id,
'groupId': group?.id, 'groupId': group?.id,
'playerIds': (players ?? []).map((player) => player.id).toList(), 'playerIds': players.map((player) => player.id).toList(),
'notes': notes, 'notes': notes,
}; };
} }

View File

@@ -63,7 +63,7 @@ class _CreateMatchViewState extends State<CreateMatchView> {
int selectedGameIndex = -1; int selectedGameIndex = -1;
/// The currently selected players /// The currently selected players
List<Player>? selectedPlayers; List<Player> selectedPlayers = [];
@override @override
void initState() { void initState() {
@@ -178,7 +178,7 @@ class _CreateMatchViewState extends State<CreateMatchView> {
Expanded( Expanded(
child: PlayerSelection( child: PlayerSelection(
key: ValueKey(selectedGroup?.id ?? 'no_group'), key: ValueKey(selectedGroup?.id ?? 'no_group'),
initialSelectedPlayers: selectedPlayers ?? [], initialSelectedPlayers: selectedPlayers,
availablePlayers: filteredPlayerList, availablePlayers: filteredPlayerList,
onChanged: (value) { onChanged: (value) {
setState(() { setState(() {
@@ -259,6 +259,6 @@ class _CreateMatchViewState extends State<CreateMatchView> {
/// - Either a group is selected OR at least 2 players are selected /// - Either a group is selected OR at least 2 players are selected
bool _enableCreateGameButton() { bool _enableCreateGameButton() {
return (selectedGroup != null || return (selectedGroup != null ||
(selectedPlayers != null && selectedPlayers!.length > 1)); (selectedPlayers.length > 1));
} }
} }

View File

@@ -153,12 +153,10 @@ class _MatchResultViewState extends State<MatchResultView> {
List<Player> getAllPlayers(Match match) { List<Player> getAllPlayers(Match match) {
List<Player> players = []; List<Player> players = [];
if (match.group == null && match.players != null) { if (match.group == null) {
players = [...match.players!]; players = [...match.players];
} else if (match.group != null && match.players != null) {
players = [...match.players!, ...match.group!.members];
} else { } else {
players = [...match.group!.members]; players = [...match.players, ...match.group!.members];
} }
players.sort((a, b) => a.name.compareTo(b.name)); players.sort((a, b) => a.name.compareTo(b.name));

View File

@@ -202,19 +202,17 @@ class _StatisticsViewState extends State<StatisticsView> {
} }
} }
} }
if (match.players != null) { final members = match.players.map((p) => p.id).toList();
final members = match.players!.map((p) => p.id).toList(); for (var playerId in members) {
for (var playerId in members) { final index = matchCounts.indexWhere((entry) => entry.$1 == playerId);
final index = matchCounts.indexWhere((entry) => entry.$1 == playerId); // -1 means player not found in matchCounts
// -1 means player not found in matchCounts if (index != -1) {
if (index != -1) { final current = matchCounts[index].$2;
final current = matchCounts[index].$2;
matchCounts[index] = (playerId, current + 1); matchCounts[index] = (playerId, current + 1);
} else { } else {
matchCounts.add((playerId, 1)); matchCounts.add((playerId, 1));
} }
} }
}
} }
// Adding all players with zero matches // Adding all players with zero matches

View File

@@ -91,7 +91,7 @@ class _MatchTileState extends State<MatchTile> {
const SizedBox(width: 6), const SizedBox(width: 6),
Expanded( Expanded(
child: Text( child: Text(
'${group.name}${widget.match.players != null ? ' + ${widget.match.players?.length}' : ''}', '${group.name} + ${widget.match.players.length}',
style: const TextStyle(fontSize: 14, color: Colors.grey), style: const TextStyle(fontSize: 14, color: Colors.grey),
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
@@ -106,7 +106,7 @@ class _MatchTileState extends State<MatchTile> {
const SizedBox(width: 6), const SizedBox(width: 6),
Expanded( Expanded(
child: Text( child: Text(
'${widget.match.players!.length} ${loc.players}', '${widget.match.players.length} ${loc.players}',
style: const TextStyle(fontSize: 14, color: Colors.grey), style: const TextStyle(fontSize: 14, color: Colors.grey),
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
@@ -241,12 +241,10 @@ class _MatchTileState extends State<MatchTile> {
final playerIds = <String>{}; final playerIds = <String>{};
// Add players from game.players // Add players from game.players
if (widget.match.players != null) { for (var player in widget.match.players) {
for (var player in widget.match.players!) { if (!playerIds.contains(player.id)) {
if (!playerIds.contains(player.id)) { allPlayers.add(player);
allPlayers.add(player); playerIds.add(player.id);
playerIds.add(player.id);
}
} }
} }

View File

@@ -64,7 +64,7 @@ class DataTransferService {
'endedAt': m.endedAt?.toIso8601String(), 'endedAt': m.endedAt?.toIso8601String(),
'gameId': m.game.id, 'gameId': m.game.id,
'groupId': m.group?.id, 'groupId': m.group?.id,
'playerIds': (m.players ?? []).map((p) => p.id).toList(), 'playerIds': m.players.map((p) => p.id).toList(),
'notes': m.notes, 'notes': m.notes,
}) })
.toList(), .toList(),
@@ -210,7 +210,7 @@ class DataTransferService {
name: map['name'] as String, name: map['name'] as String,
game: game ?? Game(name: 'Unknown', ruleset: Ruleset.singleWinner, description: '', color: GameColor.blue, icon: ''), game: game ?? Game(name: 'Unknown', ruleset: Ruleset.singleWinner, description: '', color: GameColor.blue, icon: ''),
group: group, group: group,
players: players.isNotEmpty ? players : null, players: players,
createdAt: DateTime.parse(map['createdAt'] as String), createdAt: DateTime.parse(map['createdAt'] as String),
endedAt: endedAt, endedAt: endedAt,
notes: map['notes'] as String? ?? '', notes: map['notes'] as String? ?? '',