Compare commits
5 Commits
df0a5207c2
...
7732c6ceb9
| Author | SHA1 | Date | |
|---|---|---|---|
| 7732c6ceb9 | |||
| a747d91c5d | |||
| 06a9c0cd84 | |||
| 9ad5c4ad6f | |||
| 9b3d61e5b0 |
@@ -19,15 +19,15 @@ class GroupsView extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _GroupsViewState extends State<GroupsView> {
|
class _GroupsViewState extends State<GroupsView> {
|
||||||
late Future<List<Group>> _allGroupsFuture;
|
|
||||||
late final AppDatabase db;
|
late final AppDatabase db;
|
||||||
|
late List<Group> loadedGroups;
|
||||||
|
bool isLoading = true;
|
||||||
|
|
||||||
final player = Player(name: 'Skeleton Player');
|
List<Group> groups = List.filled(
|
||||||
late final List<Group> skeletonData = List.filled(
|
|
||||||
7,
|
7,
|
||||||
Group(
|
Group(
|
||||||
name: 'Skeleton Match',
|
name: 'Skeleton Group',
|
||||||
members: [player, player, player, player, player, player],
|
members: List.filled(6, Player(name: 'Skeleton Player')),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -35,10 +35,7 @@ class _GroupsViewState extends State<GroupsView> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
db = Provider.of<AppDatabase>(context, listen: false);
|
db = Provider.of<AppDatabase>(context, listen: false);
|
||||||
_allGroupsFuture = Future.wait([
|
loadGroups();
|
||||||
db.groupDao.getAllGroups(),
|
|
||||||
Future.delayed(minimumSkeletonDuration),
|
|
||||||
]).then((results) => results[0] as List<Group>);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -48,50 +45,30 @@ class _GroupsViewState extends State<GroupsView> {
|
|||||||
body: Stack(
|
body: Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
children: [
|
children: [
|
||||||
FutureBuilder<List<Group>>(
|
AppSkeleton(
|
||||||
future: _allGroupsFuture,
|
enabled: isLoading,
|
||||||
builder:
|
child: Visibility(
|
||||||
(BuildContext context, AsyncSnapshot<List<Group>> snapshot) {
|
visible: groups.isNotEmpty,
|
||||||
if (snapshot.hasError) {
|
replacement: const Center(
|
||||||
return const Center(
|
child: TopCenteredMessage(
|
||||||
child: TopCenteredMessage(
|
icon: Icons.info,
|
||||||
icon: Icons.report,
|
title: 'Info',
|
||||||
title: 'Error',
|
message: 'No groups created yet',
|
||||||
message: 'Group data couldn\'t\nbe loaded',
|
),
|
||||||
),
|
),
|
||||||
|
child: ListView.builder(
|
||||||
|
padding: const EdgeInsets.only(bottom: 85),
|
||||||
|
itemCount: groups.length + 1,
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
if (index == groups.length) {
|
||||||
|
return SizedBox(
|
||||||
|
height: MediaQuery.paddingOf(context).bottom - 20,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (snapshot.connectionState == ConnectionState.done &&
|
return GroupTile(group: groups[index]);
|
||||||
(!snapshot.hasData || snapshot.data!.isEmpty)) {
|
|
||||||
return const Center(
|
|
||||||
child: TopCenteredMessage(
|
|
||||||
icon: Icons.info,
|
|
||||||
title: 'Info',
|
|
||||||
message: 'No groups created yet',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
final bool isLoading =
|
|
||||||
snapshot.connectionState == ConnectionState.waiting;
|
|
||||||
final List<Group> groups =
|
|
||||||
isLoading ? skeletonData : (snapshot.data ?? [])
|
|
||||||
..sort((a, b) => b.createdAt.compareTo(a.createdAt));
|
|
||||||
return AppSkeleton(
|
|
||||||
enabled: isLoading,
|
|
||||||
child: ListView.builder(
|
|
||||||
padding: const EdgeInsets.only(bottom: 85),
|
|
||||||
itemCount: groups.length + 1,
|
|
||||||
itemBuilder: (BuildContext context, int index) {
|
|
||||||
if (index == groups.length) {
|
|
||||||
return SizedBox(
|
|
||||||
height: MediaQuery.paddingOf(context).bottom - 20,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return GroupTile(group: groups[index]);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: MediaQuery.paddingOf(context).bottom,
|
bottom: MediaQuery.paddingOf(context).bottom,
|
||||||
@@ -108,7 +85,7 @@ class _GroupsViewState extends State<GroupsView> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
setState(() {
|
setState(() {
|
||||||
_allGroupsFuture = db.groupDao.getAllGroups();
|
loadGroups();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -117,4 +94,18 @@ class _GroupsViewState extends State<GroupsView> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void loadGroups() {
|
||||||
|
Future.wait([
|
||||||
|
db.groupDao.getAllGroups(),
|
||||||
|
Future.delayed(minimumSkeletonDuration),
|
||||||
|
]).then((results) {
|
||||||
|
loadedGroups = results[0] as List<Group>;
|
||||||
|
setState(() {
|
||||||
|
groups = loadedGroups
|
||||||
|
..sort((a, b) => b.createdAt.compareTo(a.createdAt));
|
||||||
|
});
|
||||||
|
isLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,16 +24,16 @@ class MatchView extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MatchViewState extends State<MatchView> {
|
class _MatchViewState extends State<MatchView> {
|
||||||
late Future<List<Match>> _gameListFuture;
|
|
||||||
late final AppDatabase db;
|
late final AppDatabase db;
|
||||||
|
bool isLoading = true;
|
||||||
|
|
||||||
late final List<Match> skeletonData = List.filled(
|
List<Match> matches = List.filled(
|
||||||
4,
|
4,
|
||||||
Match(
|
Match(
|
||||||
name: 'Skeleton Gamename',
|
name: 'Skeleton Gamename',
|
||||||
group: Group(
|
group: Group(
|
||||||
name: 'Groupname',
|
name: 'Groupname',
|
||||||
members: List.generate(5, (index) => Player(name: 'Player')),
|
members: List.filled(5, Player(name: 'Player')),
|
||||||
),
|
),
|
||||||
winner: Player(name: 'Player'),
|
winner: Player(name: 'Player'),
|
||||||
players: [Player(name: 'Player')],
|
players: [Player(name: 'Player')],
|
||||||
@@ -44,10 +44,7 @@ class _MatchViewState extends State<MatchView> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
db = Provider.of<AppDatabase>(context, listen: false);
|
db = Provider.of<AppDatabase>(context, listen: false);
|
||||||
_gameListFuture = Future.wait([
|
loadGames();
|
||||||
db.matchDao.getAllMatches(),
|
|
||||||
Future.delayed(minimumSkeletonDuration),
|
|
||||||
]).then((results) => results[0] as List<Match>);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -57,67 +54,44 @@ class _MatchViewState extends State<MatchView> {
|
|||||||
body: Stack(
|
body: Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
children: [
|
children: [
|
||||||
FutureBuilder<List<Match>>(
|
AppSkeleton(
|
||||||
future: _gameListFuture,
|
enabled: isLoading,
|
||||||
builder:
|
child: Visibility(
|
||||||
(BuildContext context, AsyncSnapshot<List<Match>> snapshot) {
|
visible: matches.isNotEmpty,
|
||||||
if (snapshot.hasError) {
|
replacement: const Center(
|
||||||
return const Center(
|
child: TopCenteredMessage(
|
||||||
child: TopCenteredMessage(
|
icon: Icons.report,
|
||||||
icon: Icons.report,
|
title: 'Info',
|
||||||
title: 'Error',
|
message: 'No games created yet',
|
||||||
message: 'Game data could not be loaded',
|
),
|
||||||
),
|
),
|
||||||
|
child: ListView.builder(
|
||||||
|
padding: const EdgeInsets.only(bottom: 85),
|
||||||
|
itemCount: matches.length + 1,
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
if (index == matches.length) {
|
||||||
|
return SizedBox(
|
||||||
|
height: MediaQuery.paddingOf(context).bottom - 80,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (snapshot.connectionState == ConnectionState.done &&
|
return GameHistoryTile(
|
||||||
(!snapshot.hasData || snapshot.data!.isEmpty)) {
|
onTap: () async {
|
||||||
return const Center(
|
Navigator.push(
|
||||||
child: TopCenteredMessage(
|
context,
|
||||||
icon: Icons.report,
|
CupertinoPageRoute(
|
||||||
title: 'Info',
|
fullscreenDialog: true,
|
||||||
message: 'No games created yet',
|
builder: (context) => GameResultView(
|
||||||
),
|
match: matches[index],
|
||||||
);
|
onWinnerChanged: loadGames,
|
||||||
}
|
),
|
||||||
final bool isLoading =
|
),
|
||||||
snapshot.connectionState == ConnectionState.waiting;
|
);
|
||||||
final List<Match> matches =
|
},
|
||||||
(isLoading ? skeletonData : (snapshot.data ?? [])
|
match: matches[index],
|
||||||
..sort(
|
|
||||||
(a, b) => b.createdAt.compareTo(a.createdAt),
|
|
||||||
))
|
|
||||||
.toList();
|
|
||||||
return AppSkeleton(
|
|
||||||
enabled: isLoading,
|
|
||||||
child: ListView.builder(
|
|
||||||
padding: const EdgeInsets.only(bottom: 85),
|
|
||||||
itemCount: matches.length + 1,
|
|
||||||
itemBuilder: (BuildContext context, int index) {
|
|
||||||
if (index == matches.length) {
|
|
||||||
return SizedBox(
|
|
||||||
height: MediaQuery.paddingOf(context).bottom - 80,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return GameHistoryTile(
|
|
||||||
onTap: () async {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
CupertinoPageRoute(
|
|
||||||
fullscreenDialog: true,
|
|
||||||
builder: (context) => GameResultView(
|
|
||||||
match: matches[index],
|
|
||||||
onWinnerChanged: refreshGameList,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
match: matches[index],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: MediaQuery.paddingOf(context).bottom,
|
bottom: MediaQuery.paddingOf(context).bottom,
|
||||||
@@ -129,7 +103,7 @@ class _MatchViewState extends State<MatchView> {
|
|||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) =>
|
builder: (context) =>
|
||||||
CreateMatchView(onWinnerChanged: refreshGameList),
|
CreateMatchView(onWinnerChanged: loadGames),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -140,9 +114,17 @@ class _MatchViewState extends State<MatchView> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void refreshGameList() {
|
void loadGames() {
|
||||||
setState(() {
|
Future.wait([
|
||||||
_gameListFuture = db.matchDao.getAllMatches();
|
db.matchDao.getAllMatches(),
|
||||||
|
Future.delayed(minimumSkeletonDuration),
|
||||||
|
]).then((results) {
|
||||||
|
final loadedMatches = results[0] as List<Match>;
|
||||||
|
matches = loadedMatches
|
||||||
|
..sort((a, b) => b.createdAt.compareTo(a.createdAt));
|
||||||
|
setState(() {
|
||||||
|
isLoading = false;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ class _PlayerSelectionState extends State<PlayerSelection> {
|
|||||||
List<Player> selectedPlayers = [];
|
List<Player> selectedPlayers = [];
|
||||||
List<Player> suggestedPlayers = [];
|
List<Player> suggestedPlayers = [];
|
||||||
List<Player> allPlayers = [];
|
List<Player> allPlayers = [];
|
||||||
|
bool isLoading = true;
|
||||||
late final TextEditingController _searchBarController =
|
late final TextEditingController _searchBarController =
|
||||||
TextEditingController();
|
TextEditingController();
|
||||||
late final AppDatabase db;
|
late final AppDatabase db;
|
||||||
@@ -43,6 +44,7 @@ class _PlayerSelectionState extends State<PlayerSelection> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
db = Provider.of<AppDatabase>(context, listen: false);
|
db = Provider.of<AppDatabase>(context, listen: false);
|
||||||
|
suggestedPlayers = skeletonData;
|
||||||
loadPlayerList();
|
loadPlayerList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +53,6 @@ class _PlayerSelectionState extends State<PlayerSelection> {
|
|||||||
db.playerDao.getAllPlayers(),
|
db.playerDao.getAllPlayers(),
|
||||||
Future.delayed(minimumSkeletonDuration),
|
Future.delayed(minimumSkeletonDuration),
|
||||||
]).then((results) => results[0] as List<Player>);
|
]).then((results) => results[0] as List<Player>);
|
||||||
suggestedPlayers = skeletonData;
|
|
||||||
_allPlayersFuture.then((loadedPlayers) {
|
_allPlayersFuture.then((loadedPlayers) {
|
||||||
setState(() {
|
setState(() {
|
||||||
// If a list of available players is provided, use that list.
|
// If a list of available players is provided, use that list.
|
||||||
@@ -77,6 +78,7 @@ class _PlayerSelectionState extends State<PlayerSelection> {
|
|||||||
suggestedPlayers = [...loadedPlayers];
|
suggestedPlayers = [...loadedPlayers];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
isLoading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,75 +165,44 @@ class _PlayerSelectionState extends State<PlayerSelection> {
|
|||||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
FutureBuilder(
|
/*
|
||||||
future: _allPlayersFuture,
|
|
||||||
builder:
|
*/
|
||||||
(BuildContext context, AsyncSnapshot<List<Player>> snapshot) {
|
Expanded(
|
||||||
if (snapshot.hasError) {
|
child: AppSkeleton(
|
||||||
return const Center(
|
enabled: isLoading,
|
||||||
child: TopCenteredMessage(
|
child: Visibility(
|
||||||
icon: Icons.report,
|
visible: suggestedPlayers.isNotEmpty,
|
||||||
title: 'Error',
|
replacement: TopCenteredMessage(
|
||||||
message: 'Player data couldn\'t\nbe loaded.',
|
icon: Icons.info,
|
||||||
),
|
title: 'Info',
|
||||||
|
message: allPlayers.isEmpty
|
||||||
|
? 'No players created yet.'
|
||||||
|
: (selectedPlayers.length == allPlayers.length)
|
||||||
|
? 'No more players to add.'
|
||||||
|
: 'No players found with that name.',
|
||||||
|
),
|
||||||
|
child: ListView.builder(
|
||||||
|
itemCount: suggestedPlayers.length,
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
return TextIconListTile(
|
||||||
|
text: suggestedPlayers[index].name,
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
if (!selectedPlayers.contains(
|
||||||
|
suggestedPlayers[index],
|
||||||
|
)) {
|
||||||
|
selectedPlayers.add(suggestedPlayers[index]);
|
||||||
|
widget.onChanged([...selectedPlayers]);
|
||||||
|
suggestedPlayers.remove(suggestedPlayers[index]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
bool doneLoading =
|
),
|
||||||
snapshot.connectionState == ConnectionState.done;
|
),
|
||||||
bool snapshotDataEmpty =
|
),
|
||||||
!snapshot.hasData || snapshot.data!.isEmpty;
|
|
||||||
if (doneLoading &&
|
|
||||||
(snapshotDataEmpty && allPlayers.isEmpty)) {
|
|
||||||
return const Center(
|
|
||||||
child: TopCenteredMessage(
|
|
||||||
icon: Icons.info,
|
|
||||||
title: 'Info',
|
|
||||||
message: 'No players created yet.',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
final bool isLoading =
|
|
||||||
snapshot.connectionState == ConnectionState.waiting;
|
|
||||||
return Expanded(
|
|
||||||
child: AppSkeleton(
|
|
||||||
enabled: isLoading,
|
|
||||||
child: Visibility(
|
|
||||||
visible:
|
|
||||||
(suggestedPlayers.isEmpty && allPlayers.isNotEmpty),
|
|
||||||
replacement: ListView.builder(
|
|
||||||
itemCount: suggestedPlayers.length,
|
|
||||||
itemBuilder: (BuildContext context, int index) {
|
|
||||||
return TextIconListTile(
|
|
||||||
text: suggestedPlayers[index].name,
|
|
||||||
onPressed: () {
|
|
||||||
setState(() {
|
|
||||||
if (!selectedPlayers.contains(
|
|
||||||
suggestedPlayers[index],
|
|
||||||
)) {
|
|
||||||
selectedPlayers.add(
|
|
||||||
suggestedPlayers[index],
|
|
||||||
);
|
|
||||||
widget.onChanged([...selectedPlayers]);
|
|
||||||
suggestedPlayers.remove(
|
|
||||||
suggestedPlayers[index],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
child: TopCenteredMessage(
|
|
||||||
icon: Icons.info,
|
|
||||||
title: 'Info',
|
|
||||||
message: (selectedPlayers.length == allPlayers.length)
|
|
||||||
? 'No more players to add.'
|
|
||||||
: 'No players found with that name.',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user