GameHistoryView anpassen #20
@@ -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
|
||||
@@ -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
flixcoo
commented
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
gelbeinhalb
commented
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),
|
||||
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.',
|
||||
),
|
||||
],
|
||||
),
|
||||
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);
|
||||
});
|
||||
}
|
||||
if (snapshot.connectionState == ConnectionState.done &&
|
||||
(!snapshot.hasData || snapshot.data!.isEmpty)) {
|
||||
return const Center(
|
||||
heightFactor: 4,
|
||||
|
gelbeinhalb marked this conversation as resolved
Outdated
sneeex
commented
Errormessage anders, handelt sich ja nicht um recent games Errormessage anders, handelt sich ja nicht um recent games
gelbeinhalb
commented
jo jo
sneeex
commented
und besser standartisierte und besser standartisierte `top_centered_message` wie in GroupsView benutzen.
Außerdem sieht das Alignement komisch aus:

gelbeinhalb
commented
hab das 1zu1 von felix kopiert hab das 1zu1 von felix kopiert
flixcoo
commented
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
sneeex
commented
Errormessage anders, handelt sich ja nicht um recent games Errormessage anders, handelt sich ja nicht um recent games
gelbeinhalb
commented
jo jo
sneeex
commented
und besser standartisierte und besser standartisierte `top_centered_message` wie in GroupsView benutzen.
Außerdem sieht das Alignement komisch aus:

|
||||
..sort((a, b) => b.createdAt.compareTo(a.createdAt)))
|
||||
.take(2)
|
||||
.toList();
|
||||
|
||||
|
gelbeinhalb marked this conversation as resolved
Outdated
flixcoo
commented
Die Skeleton-Zeit ist viel kürzer als bei allen anderen Screens. Ich glaube das liegt an dieser Zeile, weil du hier die 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.
gelbeinhalb
commented
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
flixcoo
commented
Bitte das Custom Widget 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]);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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',
|
||||
);
|
||||
|
gelbeinhalb marked this conversation as resolved
Outdated
sneeex
commented
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
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
Umbennenung zu
GameViewstand mal im Raum oder?Ist nicht ein GameView das was sich öffnet wenn man auf ein Game klickt?
@mathiskir hat die jetzt
GameResultViewgenannt, aber quatsch ihr euch da sonst nochmal abIch finde wir sollten beides von
Game....ViewinMatch...Viewumbenennen.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 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