made icon optional and default to empty string & adjust all game instances
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import 'package:clock/clock.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
import 'package:tallee/core/enums.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class Game {
|
||||
final String id;
|
||||
@@ -18,10 +18,11 @@ class Game {
|
||||
required this.ruleset,
|
||||
String? description,
|
||||
required this.color,
|
||||
required this.icon,
|
||||
String? icon,
|
||||
}) : id = id ?? const Uuid().v4(),
|
||||
createdAt = createdAt ?? clock.now(),
|
||||
description = description ?? '';
|
||||
description = description ?? '',
|
||||
icon = icon ?? '';
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
@@ -49,4 +50,3 @@ class Game {
|
||||
'icon': icon,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@ class Match {
|
||||
String? notes,
|
||||
this.winner,
|
||||
}) : id = id ?? const Uuid().v4(),
|
||||
createdAt = createdAt ?? clock.now(),
|
||||
notes = notes ?? '';
|
||||
createdAt = createdAt ?? clock.now(),
|
||||
notes = notes ?? '';
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
@@ -38,14 +38,21 @@ class Match {
|
||||
/// Creates a Match instance from a JSON object (ID references format).
|
||||
/// Related objects are reconstructed from IDs by the DataTransferService.
|
||||
Match.fromJson(Map<String, dynamic> json)
|
||||
: id = json['id'],
|
||||
createdAt = DateTime.parse(json['createdAt']),
|
||||
endedAt = json['endedAt'] != null ? DateTime.parse(json['endedAt']) : null,
|
||||
name = json['name'],
|
||||
game = Game(name: '', ruleset: Ruleset.singleWinner, description: '', color: GameColor.blue, icon: ''), // Populated during import via DataTransferService
|
||||
group = null, // Populated during import via DataTransferService
|
||||
players = [], // Populated during import via DataTransferService
|
||||
notes = json['notes'] ?? '';
|
||||
: id = json['id'],
|
||||
createdAt = DateTime.parse(json['createdAt']),
|
||||
endedAt = json['endedAt'] != null
|
||||
? DateTime.parse(json['endedAt'])
|
||||
: null,
|
||||
name = json['name'],
|
||||
game = Game(
|
||||
name: '',
|
||||
ruleset: Ruleset.singleWinner,
|
||||
description: '',
|
||||
color: GameColor.blue,
|
||||
), // Populated during import via DataTransferService
|
||||
group = null, // Populated during import via DataTransferService
|
||||
players = [], // Populated during import via DataTransferService
|
||||
notes = json['notes'] ?? '';
|
||||
|
||||
/// Converts the Match instance to a JSON object using normalized format (ID references only).
|
||||
Map<String, dynamic> toJson() => {
|
||||
|
||||
@@ -42,7 +42,12 @@ class _HomeViewState extends State<HomeView> {
|
||||
2,
|
||||
Match(
|
||||
name: 'Skeleton Match',
|
||||
game: Game(name: '', ruleset: Ruleset.singleWinner, description: '', color: GameColor.blue, icon: ''),
|
||||
game: Game(
|
||||
name: '',
|
||||
ruleset: Ruleset.singleWinner,
|
||||
description: '',
|
||||
color: GameColor.blue,
|
||||
),
|
||||
group: Group(
|
||||
name: 'Skeleton Group',
|
||||
description: '',
|
||||
@@ -104,7 +109,9 @@ class _HomeViewState extends State<HomeView> {
|
||||
if (recentMatches.isNotEmpty)
|
||||
for (Match match in recentMatches)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 6.0),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 6.0,
|
||||
),
|
||||
child: MatchTile(
|
||||
compact: true,
|
||||
width: constraints.maxWidth * 0.9,
|
||||
@@ -113,7 +120,8 @@ class _HomeViewState extends State<HomeView> {
|
||||
await Navigator.of(context).push(
|
||||
adaptivePageRoute(
|
||||
fullscreenDialog: true,
|
||||
builder: (context) => MatchResultView(match: match),
|
||||
builder: (context) =>
|
||||
MatchResultView(match: match),
|
||||
),
|
||||
);
|
||||
await updatedWinnerInRecentMatches(match.id);
|
||||
@@ -121,7 +129,10 @@ class _HomeViewState extends State<HomeView> {
|
||||
),
|
||||
)
|
||||
else
|
||||
Center(heightFactor: 5, child: Text(loc.no_recent_matches_available)),
|
||||
Center(
|
||||
heightFactor: 5,
|
||||
child: Text(loc.no_recent_matches_available),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -137,22 +148,40 @@ class _HomeViewState extends State<HomeView> {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
QuickCreateButton(text: 'Category 1', onPressed: () {}),
|
||||
QuickCreateButton(text: 'Category 2', onPressed: () {}),
|
||||
QuickCreateButton(
|
||||
text: 'Category 1',
|
||||
onPressed: () {},
|
||||
),
|
||||
QuickCreateButton(
|
||||
text: 'Category 2',
|
||||
onPressed: () {},
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
QuickCreateButton(text: 'Category 3', onPressed: () {}),
|
||||
QuickCreateButton(text: 'Category 4', onPressed: () {}),
|
||||
QuickCreateButton(
|
||||
text: 'Category 3',
|
||||
onPressed: () {},
|
||||
),
|
||||
QuickCreateButton(
|
||||
text: 'Category 4',
|
||||
onPressed: () {},
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
QuickCreateButton(text: 'Category 5', onPressed: () {}),
|
||||
QuickCreateButton(text: 'Category 6', onPressed: () {}),
|
||||
QuickCreateButton(
|
||||
text: 'Category 5',
|
||||
onPressed: () {},
|
||||
),
|
||||
QuickCreateButton(
|
||||
text: 'Category 6',
|
||||
onPressed: () {},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
@@ -181,9 +210,11 @@ class _HomeViewState extends State<HomeView> {
|
||||
matchCount = results[0] as int;
|
||||
groupCount = results[1] as int;
|
||||
loadedRecentMatches = results[2] as List<Match>;
|
||||
recentMatches = (loadedRecentMatches..sort((a, b) => b.createdAt.compareTo(a.createdAt)))
|
||||
.take(2)
|
||||
.toList();
|
||||
recentMatches =
|
||||
(loadedRecentMatches
|
||||
..sort((a, b) => b.createdAt.compareTo(a.createdAt)))
|
||||
.take(2)
|
||||
.toList();
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
|
||||
@@ -261,7 +261,6 @@ class _CreateGameViewState extends State<CreateGameView> {
|
||||
description: _descriptionController.text.trim(),
|
||||
ruleset: selectedRuleset!,
|
||||
color: selectedColor!,
|
||||
icon: '',
|
||||
);
|
||||
if (isEditing) {
|
||||
await handleGameUpdate(newGame);
|
||||
|
||||
@@ -44,7 +44,6 @@ class _MatchViewState extends State<MatchView> {
|
||||
ruleset: Ruleset.singleWinner,
|
||||
description: '',
|
||||
color: GameColor.blue,
|
||||
icon: '',
|
||||
),
|
||||
group: Group(
|
||||
name: 'Group name',
|
||||
|
||||
@@ -40,33 +40,39 @@ class DataTransferService {
|
||||
'players': players.map((p) => p.toJson()).toList(),
|
||||
'games': games.map((g) => g.toJson()).toList(),
|
||||
'groups': groups
|
||||
.map((g) => {
|
||||
'id': g.id,
|
||||
'name': g.name,
|
||||
'description': g.description,
|
||||
'createdAt': g.createdAt.toIso8601String(),
|
||||
'memberIds': (g.members).map((m) => m.id).toList(),
|
||||
})
|
||||
.map(
|
||||
(g) => {
|
||||
'id': g.id,
|
||||
'name': g.name,
|
||||
'description': g.description,
|
||||
'createdAt': g.createdAt.toIso8601String(),
|
||||
'memberIds': (g.members).map((m) => m.id).toList(),
|
||||
},
|
||||
)
|
||||
.toList(),
|
||||
'teams': teams
|
||||
.map((t) => {
|
||||
'id': t.id,
|
||||
'name': t.name,
|
||||
'createdAt': t.createdAt.toIso8601String(),
|
||||
'memberIds': (t.members).map((m) => m.id).toList(),
|
||||
})
|
||||
.map(
|
||||
(t) => {
|
||||
'id': t.id,
|
||||
'name': t.name,
|
||||
'createdAt': t.createdAt.toIso8601String(),
|
||||
'memberIds': (t.members).map((m) => m.id).toList(),
|
||||
},
|
||||
)
|
||||
.toList(),
|
||||
'matches': matches
|
||||
.map((m) => {
|
||||
'id': m.id,
|
||||
'name': m.name,
|
||||
'createdAt': m.createdAt.toIso8601String(),
|
||||
'endedAt': m.endedAt?.toIso8601String(),
|
||||
'gameId': m.game.id,
|
||||
'groupId': m.group?.id,
|
||||
'playerIds': m.players.map((p) => p.id).toList(),
|
||||
'notes': m.notes,
|
||||
})
|
||||
.map(
|
||||
(m) => {
|
||||
'id': m.id,
|
||||
'name': m.name,
|
||||
'createdAt': m.createdAt.toIso8601String(),
|
||||
'endedAt': m.endedAt?.toIso8601String(),
|
||||
'gameId': m.game.id,
|
||||
'groupId': m.group?.id,
|
||||
'playerIds': m.players.map((p) => p.id).toList(),
|
||||
'notes': m.notes,
|
||||
},
|
||||
)
|
||||
.toList(),
|
||||
};
|
||||
|
||||
@@ -79,9 +85,9 @@ class DataTransferService {
|
||||
/// [jsonString] The JSON string to be exported.
|
||||
/// [fileName] The desired name for the exported file (without extension).
|
||||
static Future<ExportResult> exportData(
|
||||
String jsonString,
|
||||
String fileName
|
||||
) async {
|
||||
String jsonString,
|
||||
String fileName,
|
||||
) async {
|
||||
try {
|
||||
final bytes = Uint8List.fromList(utf8.encode(jsonString));
|
||||
final path = await FilePicker.platform.saveFile(
|
||||
@@ -94,7 +100,6 @@ class DataTransferService {
|
||||
} else {
|
||||
return ExportResult.success;
|
||||
}
|
||||
|
||||
} catch (e, stack) {
|
||||
print('[exportData] $e');
|
||||
print(stack);
|
||||
@@ -122,13 +127,19 @@ class DataTransferService {
|
||||
final isValid = await _validateJsonSchema(jsonString);
|
||||
if (!isValid) return ImportResult.invalidSchema;
|
||||
|
||||
final Map<String, dynamic> decoded = json.decode(jsonString) as Map<String, dynamic>;
|
||||
final Map<String, dynamic> decoded =
|
||||
json.decode(jsonString) as Map<String, dynamic>;
|
||||
|
||||
final List<dynamic> playersJson = (decoded['players'] as List<dynamic>?) ?? [];
|
||||
final List<dynamic> gamesJson = (decoded['games'] as List<dynamic>?) ?? [];
|
||||
final List<dynamic> groupsJson = (decoded['groups'] as List<dynamic>?) ?? [];
|
||||
final List<dynamic> teamsJson = (decoded['teams'] as List<dynamic>?) ?? [];
|
||||
final List<dynamic> matchesJson = (decoded['matches'] as List<dynamic>?) ?? [];
|
||||
final List<dynamic> playersJson =
|
||||
(decoded['players'] as List<dynamic>?) ?? [];
|
||||
final List<dynamic> gamesJson =
|
||||
(decoded['games'] as List<dynamic>?) ?? [];
|
||||
final List<dynamic> groupsJson =
|
||||
(decoded['groups'] as List<dynamic>?) ?? [];
|
||||
final List<dynamic> teamsJson =
|
||||
(decoded['teams'] as List<dynamic>?) ?? [];
|
||||
final List<dynamic> matchesJson =
|
||||
(decoded['matches'] as List<dynamic>?) ?? [];
|
||||
|
||||
// Import Players
|
||||
final List<Player> importedPlayers = playersJson
|
||||
@@ -151,7 +162,8 @@ class DataTransferService {
|
||||
// Import Groups
|
||||
final List<Group> importedGroups = groupsJson.map((g) {
|
||||
final map = g as Map<String, dynamic>;
|
||||
final memberIds = (map['memberIds'] as List<dynamic>? ?? []).cast<String>();
|
||||
final memberIds = (map['memberIds'] as List<dynamic>? ?? [])
|
||||
.cast<String>();
|
||||
|
||||
final members = memberIds
|
||||
.map((id) => playerById[id])
|
||||
@@ -174,7 +186,8 @@ class DataTransferService {
|
||||
// Import Teams
|
||||
final List<Team> importedTeams = teamsJson.map((t) {
|
||||
final map = t as Map<String, dynamic>;
|
||||
final memberIds = (map['memberIds'] as List<dynamic>? ?? []).cast<String>();
|
||||
final memberIds = (map['memberIds'] as List<dynamic>? ?? [])
|
||||
.cast<String>();
|
||||
|
||||
final members = memberIds
|
||||
.map((id) => playerById[id])
|
||||
@@ -195,8 +208,11 @@ class DataTransferService {
|
||||
|
||||
final String gameId = map['gameId'] as String;
|
||||
final String? groupId = map['groupId'] as String?;
|
||||
final List<String> playerIds = (map['playerIds'] as List<dynamic>? ?? []).cast<String>();
|
||||
final DateTime? endedAt = map['endedAt'] != null ? DateTime.parse(map['endedAt'] as String) : null;
|
||||
final List<String> playerIds =
|
||||
(map['playerIds'] as List<dynamic>? ?? []).cast<String>();
|
||||
final DateTime? endedAt = map['endedAt'] != null
|
||||
? DateTime.parse(map['endedAt'] as String)
|
||||
: null;
|
||||
|
||||
final game = gameById[gameId];
|
||||
final group = (groupId == null) ? null : groupById[groupId];
|
||||
@@ -208,7 +224,14 @@ class DataTransferService {
|
||||
return Match(
|
||||
id: map['id'] 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,
|
||||
),
|
||||
group: group,
|
||||
players: players,
|
||||
createdAt: DateTime.parse(map['createdAt'] as String),
|
||||
@@ -266,4 +289,4 @@ class DataTransferService {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user