GameHistoryView anpassen #20
@@ -1,21 +1,15 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:game_tracker/core/custom_theme.dart';
|
import 'package:game_tracker/core/custom_theme.dart';
|
||||||
import 'package:skeletonizer/skeletonizer.dart';
|
import 'package:game_tracker/data/dto/game.dart';
|
||||||
|
import 'package:game_tracker/presentation/widgets/tiles/text_icon_tile.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
sneeex marked this conversation as resolved
|
|||||||
|
|
||||||
class GameHistoryTile extends StatefulWidget {
|
class GameHistoryTile extends StatefulWidget {
|
||||||
|
gelbeinhalb marked this conversation as resolved
flixcoo
commented
(Code-Zeile ist falsch, weil die Datei wird nicht angezeigt) (Code-Zeile ist falsch, weil die Datei wird nicht angezeigt) `doubleRowInfoTile` entfernen, wird nicht mehr genutzt
gelbeinhalb
commented
check ich nicht. wo wird das denn verwendet? check ich nicht. wo wird das denn verwendet?
flixcoo
commented
Nirgendwo, deswegen kann es ja weg. Wurde vorher in Nirgendwo, deswegen kann es ja weg. Wurde vorher in `GameHistoryView` verwendet
gelbeinhalb
commented
nirgendwo in meinem code steht nirgendwo in meinem code steht `doubleRowInfoTile` 😭 oder ich bin blöd und finde es nicht
|
|||||||
final String gameTitle;
|
final Game game;
|
||||||
final String gameType;
|
|
||||||
final String date;
|
|
||||||
final String groupName;
|
|
||||||
final String winner;
|
|
||||||
|
|
||||||
const GameHistoryTile({
|
const GameHistoryTile({
|
||||||
super.key,
|
super.key,
|
||||||
required this.gameTitle,
|
required this.game,
|
||||||
required this.gameType,
|
|
||||||
required this.date,
|
|
||||||
required this.groupName,
|
|
||||||
required this.winner,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -23,55 +17,171 @@ class GameHistoryTile extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _GameHistoryTileState extends State<GameHistoryTile> {
|
class _GameHistoryTileState extends State<GameHistoryTile> {
|
||||||
|
String _formatDate(DateTime dateTime) {
|
||||||
|
final now = DateTime.now();
|
||||||
|
final difference = now.difference(dateTime);
|
||||||
|
|
||||||
|
if (difference.inDays == 0) {
|
||||||
|
return 'Today at ${DateFormat('HH:mm').format(dateTime)}';
|
||||||
|
} else if (difference.inDays == 1) {
|
||||||
|
return 'Yesterday at ${DateFormat('HH:mm').format(dateTime)}';
|
||||||
|
} else if (difference.inDays < 7) {
|
||||||
|
return '${difference.inDays} days ago';
|
||||||
|
} else {
|
||||||
|
return DateFormat('MMM d, yyyy').format(dateTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<dynamic> _getAllPlayers() {
|
||||||
|
gelbeinhalb marked this conversation as resolved
flixcoo
commented
Hier auch hinter Hier auch hinter `buid()` Methode schieben
gelbeinhalb
commented
👍 👍
|
|||||||
|
final allPlayers = <dynamic>[];
|
||||||
|
final playerIds = <String>{};
|
||||||
|
|
||||||
|
// Add players from game.players
|
||||||
|
if (widget.game.players != null) {
|
||||||
|
for (var player in widget.game.players!) {
|
||||||
|
if (!playerIds.contains(player.id)) {
|
||||||
|
allPlayers.add(player);
|
||||||
|
playerIds.add(player.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add players from game.group.players
|
||||||
|
if (widget.game.group?.members != null) {
|
||||||
|
for (var player in widget.game.group!.members) {
|
||||||
|
if (!playerIds.contains(player.id)) {
|
||||||
|
allPlayers.add(player);
|
||||||
|
playerIds.add(player.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return allPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Column(
|
final group = widget.game.group;
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
final winner = widget.game.winner;
|
||||||
children: [
|
final allPlayers = _getAllPlayers();
|
||||||
Container(
|
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: CustomTheme.boxColor,
|
|
||||||
border: Border.all(color: CustomTheme.boxBorder),
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
widget.gameTitle,
|
|
||||||
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
widget.date,
|
|
||||||
style: const TextStyle(fontSize: 14, color: Colors.grey),
|
|
||||||
textAlign: TextAlign.left,
|
|
||||||
),
|
|
||||||
const SizedBox(width: 5),
|
|
||||||
const Text('·'),
|
|
||||||
const SizedBox(width: 5),
|
|
||||||
Text(
|
|
||||||
widget.gameType,
|
|
||||||
style: const TextStyle(fontSize: 14, color: Colors.grey),
|
|
||||||
textAlign: TextAlign.left,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 15),
|
|
||||||
|
|
||||||
]
|
return Container(
|
||||||
)
|
margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||||
),
|
padding: const EdgeInsets.all(16),
|
||||||
],
|
decoration: BoxDecoration(
|
||||||
|
color: CustomTheme.boxColor,
|
||||||
|
border: Border.all(color: CustomTheme.boxBorder),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
widget.game.name,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
_formatDate(widget.game.createdAt),
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
|
||||||
|
if (group != null)
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
const Icon(
|
||||||
|
Icons.group,
|
||||||
|
size: 16,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 6),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
group.name,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
if (group != null) const SizedBox(height: 12),
|
||||||
|
|
||||||
|
if (winner != null)
|
||||||
|
gelbeinhalb marked this conversation as resolved
flixcoo
commented
Hier auch zusammenfassen oder Hier auch zusammenfassen oder `Visibility` bzw. `Offstage` Widget nutzen
|
|||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.green.withValues(alpha: 0.1),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(
|
||||||
|
color: Colors.green.withValues(alpha: 0.3),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const Icon(
|
||||||
|
Icons.emoji_events,
|
||||||
|
size: 20,
|
||||||
|
color: Colors.amber,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
'Winner: ${winner.name}',
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
if (winner != null) const SizedBox(height: 12),
|
||||||
|
|
||||||
|
if (allPlayers.isNotEmpty) ...[
|
||||||
|
const Text(
|
||||||
|
'Players:',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
color: Colors.grey,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 6),
|
||||||
|
Wrap(
|
||||||
|
spacing: 6,
|
||||||
|
runSpacing: 6,
|
||||||
|
children: allPlayers.map((player) {
|
||||||
|
final isWinner = winner != null && player.id == winner.id;
|
||||||
|
return TextIconTile(
|
||||||
|
text: player.name,
|
||||||
|
iconEnabled: false,
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user
Wofür intl?
Zur berechnung vom datum :) idk ob das der optimalste weg ist
Aber nutzt du da nicht nur datetime?
Die
DateFormatklasse kommt daher: