GameHistoryView anpassen #20

Merged
flixcoo merged 27 commits from feature/2-gamehistoryview-anpassen into development 2025-11-30 15:59:25 +00:00
Showing only changes of commit bbd200e245 - Show all commits

View File

@@ -1,7 +1,11 @@
import 'package:flutter/material.dart';
import 'package:game_tracker/core/custom_theme.dart';
import 'package:game_tracker/data/db/database.dart';
import 'package:game_tracker/data/dto/game.dart';
import 'package:game_tracker/data/dto/group.dart';
import 'package:game_tracker/data/dto/player.dart';
import 'package:game_tracker/presentation/widgets/tiles/game_history_tile.dart';
import 'package:game_tracker/presentation/widgets/top_centered_message.dart';
import 'package:provider/provider.dart';
import 'package:skeletonizer/skeletonizer.dart';
class GameHistoryView extends StatefulWidget {
const GameHistoryView({super.key});
gelbeinhalb marked this conversation as resolved Outdated

Umbennenung zu GameView stand mal im Raum oder?

Umbennenung zu `GameView` stand mal im Raum oder?

Ist nicht ein GameView das was sich öffnet wenn man auf ein Game klickt?

Ist nicht ein GameView das was sich öffnet wenn man auf ein Game klickt?

@mathiskir hat die jetzt GameResultView genannt, aber quatsch ihr euch da sonst nochmal ab

@mathiskir hat die jetzt `GameResultView` genannt, aber quatsch ihr euch da sonst nochmal ab

Ich finde wir sollten beides von Game....View in Match...View umbenennen.

Game = Das Spiel (Brettspiel, Kartenspiel)
Match = Eine Partie des Spiels

@flixcoo @mathiskir

Ich finde wir sollten beides von `Game....View` in `Match...View` umbenennen. Game = Das Spiel (Brettspiel, Kartenspiel) Match = Eine Partie des Spiels @flixcoo @mathiskir

Ja fand ich glaub ich sinnvoll. Dann müssten wir aber auch die entsprechenden Klassen umbenennen. Ich würde vorschlagen dass gesammelt in einem Ticket zu machen und deins so zu mergen

Ja fand ich glaub ich sinnvoll. Dann müssten wir aber auch die entsprechenden Klassen umbenennen. Ich würde vorschlagen dass gesammelt in einem Ticket zu machen und deins so zu mergen

Ja würde ich auch sagen, weil dann ja sogar die Datenbank implementation geändert werden muss noch. Und auch unsere test json

Ja würde ich auch sagen, weil dann ja sogar die Datenbank implementation geändert werden muss noch. Und auch unsere test json

ja, lass das hier erstmal rauslassen

ja, lass das hier erstmal rauslassen
@@ -11,194 +15,92 @@ class GameHistoryView extends StatefulWidget {
}
class _GameHistoryViewState extends State<GameHistoryView> {
final allGameData = [
{
'game': 'Schach',
'title': 'Abendpartie',
'players': 2,
'group': 'Familie',
'date': '01.06.2024',
},
{
'game': 'Monopoly',
'title': 'Wochenendspaß mit Gras du Saas',
'players': 4,
'group': 'Freunde',
'date': '28.05.2024',
},
{
'game': 'Catan',
'title': 'Strategieabend',
'players': 3,
'group': 'Brettspieler',
'date': '25.05.2024',
},
{
'game': 'Uno',
'title': 'Schnelle Runde',
'players': 5,
'group': 'Kollegen',
'date': '22.05.2024',
},
{
'game': 'Poker',
'title': 'Freitagspoker',
'players': 6,
'group': 'Pokerclub',
'date': '20.05.2024',
},
{
'game': 'Scrabble',
'title': 'Wortschlacht',
'players': 4,
'group': 'Familie',
'date': '18.05.2024',
},
{
'game': 'Risiko',
'title': 'Weltherrschaft',
'players': 5,
'group': 'Strategiegruppe',
'date': '15.05.2024',
},
{
'game': 'Zug um Zug',
'title': 'Zug-Abenteuer',
'players': 4,
'group': 'Reisende',
'date': '12.05.2024',
},
{
'game': 'Carcassonne',
'title': 'Plättchenlegen',
'players': 3,
'group': 'Brettspieler',
'date': '10.05.2024',
},
{
'game': 'Pandemie',
'title': 'Welt retten',
'players': 4,
'group': 'Koop-Team',
'date': '08.05.2024',
},
{
'game': 'Cluedo',
'title': 'Krimiabend',
'players': 6,
'group': 'Detektive',
'date': '05.05.2024',
},
{
'game': 'Dixit',
'title': 'Fantasiespiel',
'players': 5,
'group': 'Künstler',
'date': '02.05.2024',
},
{
'game': 'Azul',
'title': 'Plättchenmeister',
'players': 4,
'group': 'Familie',
'date': '30.04.2024',
},
{
'game': 'Splendor',
'title': 'Edelsteinhändler',
'players': 3,
'group': 'Freunde',
'date': '28.04.2024',
},
{
'game': '7 Wonders',
'title': 'Antike Reiche',
'players': 7,
'group': 'Geschichtsfreunde',
'date': '25.04.2024',
},
];
late List<Map<String, dynamic>> suggestedGameData;
late Future<List<Game>> _gameListFuture;
late final AppDatabase db;
late final List<Game> skeletonData = List.filled(
gelbeinhalb marked this conversation as resolved Outdated

Ich würde die Skeleton-Daten so anpassen, dass du nicht mehr machst als auf den Screen passen. Also bei mir sind das glaub ich so 5

Ich würde die Skeleton-Daten so anpassen, dass du nicht mehr machst als auf den Screen passen. Also bei mir sind das glaub ich so 5

ja save :) hab 10 eingestellt zum testen und dann vergessen zu ändern

ja save :) hab 10 eingestellt zum testen und dann vergessen zu ändern
2,
Game(
name: 'Skeleton Game',
group: Group(
name: 'Skeleton Group',
members: [
Player(name: 'Skeleton Player 1'),
Player(name: 'Skeleton Player 2'),
],
),
winner: Player(name: 'Skeleton Player 1'),
),
);
@override
void initState() {
super.initState();
suggestedGameData = List.from(allGameData);
db = Provider.of<AppDatabase>(context, listen: false);
_gameListFuture = Future.delayed(
const Duration(milliseconds: 250),
() => db.gameDao.getAllGames(),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: CustomTheme.backgroundColor,
body: Stack(
children: [
Column(
children: [
Container(margin: const EdgeInsets.only(bottom: 75)),
Expanded(
child: gameHistoryListView(allGameData, suggestedGameData),
),
],
),
Container(
margin: const EdgeInsets.only(top: 10, bottom: 10, left: 10, right: 10),
child: SearchBar(
leading: const Icon(Icons.search),
onChanged: (value) {
if (value.isEmpty) {
setState(() {
suggestedGameData.clear();
suggestedGameData.addAll(allGameData);
});
return;
}
final suggestions = allGameData.where((currentGame) {
return currentGame['game'].toString().toLowerCase().contains(
value.toLowerCase(),
) ||
currentGame['title'].toString().toLowerCase().contains(
value.toLowerCase(),
) ||
currentGame['group'].toString().toLowerCase().contains(
value.toLowerCase(),
);
});
setState(() {
suggestedGameData.clear();
suggestedGameData.addAll(suggestions);
});
},
return FutureBuilder<List<Game>>(
future: _gameListFuture,
builder: (BuildContext context, AsyncSnapshot<List<Game>> snapshot) {
if (snapshot.hasError) {
return const Center(
heightFactor: 4,
child: Text(
'Error while loading recent games.',
),
);
}
if (snapshot.connectionState == ConnectionState.done &&
(!snapshot.hasData || snapshot.data!.isEmpty)) {
return const Center(
heightFactor: 4,
gelbeinhalb marked this conversation as resolved Outdated

Errormessage anders, handelt sich ja nicht um recent games

Errormessage anders, handelt sich ja nicht um recent games

jo

jo

und besser standartisierte top_centered_message wie in GroupsView benutzen.
Außerdem sieht das Alignement komisch aus:
grafik.png

und besser standartisierte `top_centered_message` wie in GroupsView benutzen. Außerdem sieht das Alignement komisch aus: ![grafik.png](/attachments/51e0ad5c-7df8-43e1-8401-dd459be4abbb)

hab das 1zu1 von felix kopiert

hab das 1zu1 von felix kopiert

Ja das war ein schwerer Fehler, würde nichtmal von mir selbst kopieren

Ja das war ein schwerer Fehler, würde nichtmal von mir selbst kopieren
child: Text('No recent games available.'),
);
}
final bool isLoading = snapshot.connectionState == ConnectionState.waiting;
final List<Game> games = (isLoading
? skeletonData
: (snapshot.data ?? [])
gelbeinhalb marked this conversation as resolved Outdated

Errormessage anders, handelt sich ja nicht um recent games

Errormessage anders, handelt sich ja nicht um recent games

jo

jo

und besser standartisierte top_centered_message wie in GroupsView benutzen.
Außerdem sieht das Alignement komisch aus:
grafik.png

und besser standartisierte `top_centered_message` wie in GroupsView benutzen. Außerdem sieht das Alignement komisch aus: ![grafik.png](/attachments/51e0ad5c-7df8-43e1-8401-dd459be4abbb)
..sort((a, b) => b.createdAt.compareTo(a.createdAt)))
.take(2)
.toList();
gelbeinhalb marked this conversation as resolved Outdated

Die Skeleton-Zeit ist viel kürzer als bei allen anderen Screens. Ich glaube das liegt an dieser Zeile, weil du hier die isLoading Variable setzt und nicht nach dem oben angegebenen 250ms delay.

Die Skeleton-Zeit ist viel kürzer als bei allen anderen Screens. Ich glaube das liegt an dieser Zeile, weil du hier die `isLoading` Variable setzt und nicht nach dem oben angegebenen 250ms delay.

okay danke :) guck ich mir an

okay danke :) guck ich mir an
return Skeletonizer(
effect: PulseEffect(
from: Colors.grey[800]!,
to: Colors.grey[600]!,
duration: const Duration(milliseconds: 800),
),
],
),
enabled: isLoading,
enableSwitchAnimation: true,
switchAnimationConfig: const SwitchAnimationConfig(
duration: Duration(milliseconds: 200),
switchInCurve: Curves.linear,
switchOutCurve: Curves.linear,
transitionBuilder: AnimatedSwitcher.defaultTransitionBuilder,
layoutBuilder: AnimatedSwitcher.defaultLayoutBuilder,
),
gelbeinhalb marked this conversation as resolved Outdated

Bitte das Custom Widget AppSkeleton aus development hier noch Implementieren

Bitte das Custom Widget `AppSkeleton` aus `development` hier noch Implementieren
child: ListView.builder(
padding: const EdgeInsets.only(bottom: 85),
itemCount: games.length + 1,
itemBuilder: (BuildContext context, int index) {
if (index == games.length) {
return SizedBox(
height: MediaQuery.paddingOf(context).bottom - 20,
);
}
return GameHistoryTile(game: games[index]);
},
),
);
gelbeinhalb marked this conversation as resolved Outdated

padding zu groß, zu viel platz unten ohne button, mit button evtl passend

padding zu groß, zu viel platz unten ohne button, mit button evtl passend
},
);
}
}
Widget gameHistoryListView(allGameData, suggestedGameData) {
if (suggestedGameData.isEmpty && allGameData.isEmpty) {
return const TopCenteredMessage(icon: Icons.error, title: 'Keine Spiele erstellt', message: '',);
} else if (suggestedGameData.isEmpty) {
return const TopCenteredMessage(icon: Icons.error, title: 'Keine Spiele mit den Suchparametern gefunden', message: '',);
}
return ListView.separated(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
itemCount: suggestedGameData.length,
separatorBuilder: (context, index) => const Padding(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: Divider(),
),
itemBuilder: (context, index) {
final currentGame = suggestedGameData[index];
return GameHistoryTile(
gameTitle: currentGame['title'],
gameType: currentGame['game'],
date: currentGame['date'],
groupName: currentGame['group'],
winner: 'ich',
);
},
);
}
}