Compare commits
7 Commits
0567fce02b
...
4f0a1eec6d
| Author | SHA1 | Date | |
|---|---|---|---|
| 4f0a1eec6d | |||
| 24b60bb18b | |||
| c8532adfde | |||
| 76186787e7 | |||
| f05114a99e | |||
| d96494f608 | |||
| 0eaf3d251b |
2
lib/core/constants.dart
Normal file
2
lib/core/constants.dart
Normal file
@@ -0,0 +1,2 @@
|
||||
/// Minimum duration of all app skeletons
|
||||
Duration minimumSkeletonDuration = Duration(milliseconds: 250);
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:game_tracker/core/constants.dart';
|
||||
import 'package:game_tracker/core/custom_theme.dart';
|
||||
import 'package:game_tracker/data/db/database.dart';
|
||||
import 'package:game_tracker/data/dto/group.dart';
|
||||
@@ -34,10 +35,10 @@ class _GroupsViewState extends State<GroupsView> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
db = Provider.of<AppDatabase>(context, listen: false);
|
||||
_allGroupsFuture = Future.delayed(
|
||||
const Duration(milliseconds: 250),
|
||||
() => db.groupDao.getAllGroups(),
|
||||
);
|
||||
_allGroupsFuture = Future.wait([
|
||||
db.groupDao.getAllGroups(),
|
||||
Future.delayed(minimumSkeletonDuration),
|
||||
]).then((results) => results[0] as List<Group>);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:game_tracker/core/constants.dart';
|
||||
import 'package:game_tracker/data/db/database.dart';
|
||||
import 'package:game_tracker/data/dto/group.dart';
|
||||
import 'package:game_tracker/data/dto/match.dart';
|
||||
@@ -18,12 +19,10 @@ class HomeView extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _HomeViewState extends State<HomeView> {
|
||||
late Future<int> _matchCountFuture;
|
||||
late Future<int> _groupCountFuture;
|
||||
late Future<List<Match>> _recentMatchesFuture;
|
||||
bool isLoading = true;
|
||||
|
||||
late final List<Match> skeletonData = List.filled(
|
||||
int matchCount = 0;
|
||||
int groupCount = 0;
|
||||
List<Match> recentMatches = List.filled(
|
||||
2,
|
||||
Match(
|
||||
name: 'Skeleton Match',
|
||||
@@ -39,19 +38,24 @@ class _HomeViewState extends State<HomeView> {
|
||||
);
|
||||
|
||||
@override
|
||||
initState() {
|
||||
void initState() {
|
||||
super.initState();
|
||||
final db = Provider.of<AppDatabase>(context, listen: false);
|
||||
_matchCountFuture = db.matchDao.getMatchCount();
|
||||
_groupCountFuture = db.groupDao.getGroupCount();
|
||||
_recentMatchesFuture = db.matchDao.getAllMatches();
|
||||
|
||||
Future.wait([
|
||||
_matchCountFuture,
|
||||
_groupCountFuture,
|
||||
_recentMatchesFuture,
|
||||
]).then((_) async {
|
||||
await Future.delayed(const Duration(milliseconds: 250));
|
||||
db.matchDao.getMatchCount(),
|
||||
db.groupDao.getGroupCount(),
|
||||
db.matchDao.getAllMatches(),
|
||||
Future.delayed(minimumSkeletonDuration),
|
||||
]).then((results) {
|
||||
matchCount = results[0] as int;
|
||||
groupCount = results[1] as int;
|
||||
recentMatches = results[2] as List<Match>;
|
||||
|
||||
recentMatches =
|
||||
(recentMatches..sort((a, b) => b.createdAt.compareTo(a.createdAt)))
|
||||
.take(2)
|
||||
.toList();
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
@@ -73,38 +77,20 @@ class _HomeViewState extends State<HomeView> {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
FutureBuilder<int>(
|
||||
future: _matchCountFuture,
|
||||
builder: (context, snapshot) {
|
||||
final int count = (snapshot.hasData)
|
||||
? snapshot.data!
|
||||
: 0;
|
||||
return QuickInfoTile(
|
||||
QuickInfoTile(
|
||||
width: constraints.maxWidth * 0.45,
|
||||
height: constraints.maxHeight * 0.15,
|
||||
title: 'Matches',
|
||||
icon: Icons.groups_rounded,
|
||||
value: count,
|
||||
);
|
||||
},
|
||||
value: matchCount,
|
||||
),
|
||||
SizedBox(width: constraints.maxWidth * 0.05),
|
||||
FutureBuilder<int>(
|
||||
future: _groupCountFuture,
|
||||
builder: (context, snapshot) {
|
||||
final int count =
|
||||
(snapshot.connectionState == ConnectionState.done &&
|
||||
snapshot.hasData)
|
||||
? snapshot.data!
|
||||
: 0;
|
||||
return QuickInfoTile(
|
||||
QuickInfoTile(
|
||||
width: constraints.maxWidth * 0.45,
|
||||
height: constraints.maxHeight * 0.15,
|
||||
title: 'Groups',
|
||||
icon: Icons.groups_rounded,
|
||||
value: count,
|
||||
);
|
||||
},
|
||||
value: groupCount,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -116,80 +102,48 @@ class _HomeViewState extends State<HomeView> {
|
||||
icon: Icons.timer,
|
||||
content: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 40.0),
|
||||
child: FutureBuilder(
|
||||
future: _recentMatchesFuture,
|
||||
builder:
|
||||
(
|
||||
BuildContext context,
|
||||
AsyncSnapshot<List<Match>> snapshot,
|
||||
) {
|
||||
if (snapshot.hasError) {
|
||||
return const Center(
|
||||
heightFactor: 4,
|
||||
child: Text(
|
||||
'Error while loading recent matches.',
|
||||
child: Visibility(
|
||||
visible: !isLoading,
|
||||
replacement: const Center(
|
||||
heightFactor: 12,
|
||||
child: Text('No recent games available.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
final List<Match> matches =
|
||||
(isLoading
|
||||
? skeletonData
|
||||
: (snapshot.data ?? [])
|
||||
..sort(
|
||||
(a, b) => b.createdAt.compareTo(
|
||||
a.createdAt,
|
||||
),
|
||||
))
|
||||
.take(2)
|
||||
.toList();
|
||||
if (matches.isNotEmpty) {
|
||||
return Column(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
MatchTile(
|
||||
matchTitle: matches[0].name,
|
||||
matchTitle: recentMatches[0].name,
|
||||
game: 'Winner',
|
||||
ruleset: 'Ruleset',
|
||||
players: _getPlayerText(matches[0]),
|
||||
winner: matches[0].winner == null
|
||||
players: _getPlayerText(recentMatches[0]),
|
||||
winner: recentMatches[0].winner == null
|
||||
? 'Match in progress...'
|
||||
: matches[0].winner!.name,
|
||||
: recentMatches[0].winner!.name,
|
||||
),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 8.0,
|
||||
),
|
||||
padding: EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: Divider(),
|
||||
),
|
||||
if (matches.length > 1) ...[
|
||||
if (recentMatches.length > 1) ...[
|
||||
MatchTile(
|
||||
matchTitle: matches[1].name,
|
||||
matchTitle: recentMatches[1].name,
|
||||
game: 'Winner',
|
||||
ruleset: 'Ruleset',
|
||||
players: _getPlayerText(matches[1]),
|
||||
winner: matches[1].winner == null
|
||||
players: _getPlayerText(recentMatches[1]),
|
||||
winner: recentMatches[1].winner == null
|
||||
? 'Game in progress...'
|
||||
: matches[1].winner!.name,
|
||||
: recentMatches[1].winner!.name,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
] else ...[
|
||||
const Center(
|
||||
heightFactor: 4,
|
||||
child: Text(
|
||||
'No second game available.',
|
||||
),
|
||||
child: Text('No second game available.'),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return const Center(
|
||||
heightFactor: 12,
|
||||
child: Text('No recent games available.'),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -199,7 +153,6 @@ class _HomeViewState extends State<HomeView> {
|
||||
title: 'Quick Create',
|
||||
icon: Icons.add_box_rounded,
|
||||
content: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
|
||||
@@ -28,12 +28,6 @@ class _CreateMatchViewState extends State<CreateMatchView> {
|
||||
/// Reference to the app database
|
||||
late final AppDatabase db;
|
||||
|
||||
/// Futures to load all groups and players from the database
|
||||
late Future<List<Group>> _allGroupsFuture;
|
||||
|
||||
/// Future to load all players from the database
|
||||
late Future<List<Player>> _allPlayersFuture;
|
||||
|
||||
/// Controller for the game name input field
|
||||
final TextEditingController _gameNameController = TextEditingController();
|
||||
|
||||
@@ -107,10 +101,10 @@ class _CreateMatchViewState extends State<CreateMatchView> {
|
||||
|
||||
db = Provider.of<AppDatabase>(context, listen: false);
|
||||
|
||||
_allGroupsFuture = db.groupDao.getAllGroups();
|
||||
_allPlayersFuture = db.playerDao.getAllPlayers();
|
||||
|
||||
Future.wait([_allGroupsFuture, _allPlayersFuture]).then((result) async {
|
||||
Future.wait([
|
||||
db.groupDao.getAllGroups(),
|
||||
db.playerDao.getAllPlayers(),
|
||||
]).then((result) async {
|
||||
groupsList = result[0] as List<Group>;
|
||||
playerList = result[1] as List<Player>;
|
||||
});
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:core' hide Match;
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:game_tracker/core/constants.dart';
|
||||
import 'package:game_tracker/core/custom_theme.dart';
|
||||
import 'package:game_tracker/data/db/database.dart';
|
||||
import 'package:game_tracker/data/dto/group.dart';
|
||||
@@ -43,10 +44,10 @@ class _MatchViewState extends State<MatchView> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
db = Provider.of<AppDatabase>(context, listen: false);
|
||||
_gameListFuture = Future.delayed(
|
||||
const Duration(milliseconds: 250),
|
||||
() => db.matchDao.getAllMatches(),
|
||||
);
|
||||
_gameListFuture = Future.wait([
|
||||
db.matchDao.getAllMatches(),
|
||||
Future.delayed(minimumSkeletonDuration),
|
||||
]).then((results) => results[0] as List<Match>);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:game_tracker/core/constants.dart';
|
||||
import 'package:game_tracker/data/db/database.dart';
|
||||
import 'package:game_tracker/data/dto/match.dart';
|
||||
import 'package:game_tracker/data/dto/player.dart';
|
||||
@@ -14,8 +15,6 @@ class StatisticsView extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _StatisticsViewState extends State<StatisticsView> {
|
||||
late Future<List<Match>> _matchesFuture;
|
||||
late Future<List<Player>> _playersFuture;
|
||||
List<(String, int)> winCounts = List.filled(6, ('Skeleton Player', 1));
|
||||
List<(String, int)> matchCounts = List.filled(6, ('Skeleton Player', 1));
|
||||
List<(String, double)> winRates = List.filled(6, ('Skeleton Player', 1));
|
||||
@@ -25,11 +24,12 @@ class _StatisticsViewState extends State<StatisticsView> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
final db = Provider.of<AppDatabase>(context, listen: false);
|
||||
_matchesFuture = db.matchDao.getAllMatches();
|
||||
_playersFuture = db.playerDao.getAllPlayers();
|
||||
|
||||
Future.wait([_matchesFuture, _playersFuture]).then((results) async {
|
||||
await Future.delayed(const Duration(milliseconds: 250));
|
||||
Future.wait([
|
||||
db.matchDao.getAllMatches(),
|
||||
db.playerDao.getAllPlayers(),
|
||||
Future.delayed(minimumSkeletonDuration),
|
||||
]).then((results) async {
|
||||
final matches = results[0] as List<Match>;
|
||||
final players = results[1] as List<Player>;
|
||||
winCounts = _calculateWinsForAllPlayers(matches, players);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:game_tracker/core/constants.dart';
|
||||
import 'package:game_tracker/core/custom_theme.dart';
|
||||
import 'package:game_tracker/data/db/database.dart';
|
||||
import 'package:game_tracker/data/dto/player.dart';
|
||||
@@ -46,10 +47,10 @@ class _PlayerSelectionState extends State<PlayerSelection> {
|
||||
}
|
||||
|
||||
void loadPlayerList() {
|
||||
_allPlayersFuture = Future.delayed(
|
||||
const Duration(milliseconds: 250),
|
||||
() => db.playerDao.getAllPlayers(),
|
||||
);
|
||||
_allPlayersFuture = Future.wait([
|
||||
db.playerDao.getAllPlayers(),
|
||||
Future.delayed(minimumSkeletonDuration),
|
||||
]).then((results) => results[0] as List<Player>);
|
||||
suggestedPlayers = skeletonData;
|
||||
_allPlayersFuture.then((loadedPlayers) {
|
||||
setState(() {
|
||||
|
||||
Reference in New Issue
Block a user