MVP-Refactoring #139
@@ -17,7 +17,10 @@ class CustomNavigationBar extends StatefulWidget {
|
|||||||
|
|
||||||
class _CustomNavigationBarState extends State<CustomNavigationBar>
|
class _CustomNavigationBarState extends State<CustomNavigationBar>
|
||||||
with SingleTickerProviderStateMixin {
|
with SingleTickerProviderStateMixin {
|
||||||
|
/// Currently selected tab index
|
||||||
int currentIndex = 0;
|
int currentIndex = 0;
|
||||||
|
|
||||||
|
/// Key count to force rebuild of tab views
|
||||||
int tabKeyCount = 0;
|
int tabKeyCount = 0;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -119,12 +122,14 @@ class _CustomNavigationBarState extends State<CustomNavigationBar>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Handles tab tap events. Updates the current [index] state.
|
||||||
void onTabTapped(int index) {
|
void onTabTapped(int index) {
|
||||||
setState(() {
|
setState(() {
|
||||||
currentIndex = index;
|
currentIndex = index;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the title of the current tab based on [currentIndex].
|
||||||
String _currentTabTitle(context) {
|
String _currentTabTitle(context) {
|
||||||
final loc = AppLocalizations.of(context);
|
final loc = AppLocalizations.of(context);
|
||||||
switch (currentIndex) {
|
switch (currentIndex) {
|
||||||
|
|||||||
@@ -18,15 +18,17 @@ class CreateGroupView extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _CreateGroupViewState extends State<CreateGroupView> {
|
class _CreateGroupViewState extends State<CreateGroupView> {
|
||||||
final _groupNameController = TextEditingController();
|
|
||||||
late final AppDatabase db;
|
late final AppDatabase db;
|
||||||
|
sneeex marked this conversation as resolved
|
|||||||
|
|
||||||
|
/// Controller for the group name input field
|
||||||
|
final _groupNameController = TextEditingController();
|
||||||
|
|
||||||
|
/// List of currently selected players
|
||||||
List<Player> selectedPlayers = [];
|
List<Player> selectedPlayers = [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
db = Provider.of<AppDatabase>(context, listen: false);
|
db = Provider.of<AppDatabase>(context, listen: false);
|
||||||
_groupNameController.addListener(() {
|
_groupNameController.addListener(() {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
|||||||
@@ -21,7 +21,11 @@ class GroupsView extends StatefulWidget {
|
|||||||
|
|
||||||
class _GroupsViewState extends State<GroupsView> {
|
class _GroupsViewState extends State<GroupsView> {
|
||||||
late final AppDatabase db;
|
late final AppDatabase db;
|
||||||
|
flixcoo marked this conversation as resolved
sneeex
commented
hier ebenfalls kein comment? hier ebenfalls kein comment?
|
|||||||
|
|
||||||
|
/// Loaded groups from the database
|
||||||
late List<Group> loadedGroups;
|
late List<Group> loadedGroups;
|
||||||
|
|
||||||
|
/// Loading state
|
||||||
bool isLoading = true;
|
bool isLoading = true;
|
||||||
|
|
||||||
List<Group> groups = List.filled(
|
List<Group> groups = List.filled(
|
||||||
|
|||||||
@@ -21,9 +21,17 @@ class HomeView extends StatefulWidget {
|
|||||||
|
|
||||||
class _HomeViewState extends State<HomeView> {
|
class _HomeViewState extends State<HomeView> {
|
||||||
bool isLoading = true;
|
bool isLoading = true;
|
||||||
|
flixcoo marked this conversation as resolved
sneeex
commented
hier ebenfalls kein comment? hier ebenfalls kein comment?
|
|||||||
|
|
||||||
|
/// Amount of matches in the database
|
||||||
int matchCount = 0;
|
int matchCount = 0;
|
||||||
|
|
||||||
|
/// Amount of groups in the database
|
||||||
int groupCount = 0;
|
int groupCount = 0;
|
||||||
|
|
||||||
|
/// Loaded recent matches from the database
|
||||||
List<Match> loadedRecentMatches = [];
|
List<Match> loadedRecentMatches = [];
|
||||||
|
|
||||||
|
/// Recent matches to display, initially filled with skeleton matches
|
||||||
List<Match> recentMatches = List.filled(
|
List<Match> recentMatches = List.filled(
|
||||||
2,
|
2,
|
||||||
Match(
|
Match(
|
||||||
@@ -42,32 +50,7 @@ class _HomeViewState extends State<HomeView> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
final db = Provider.of<AppDatabase>(context, listen: false);
|
loadHomeViewData();
|
||||||
Future.wait([
|
|
||||||
db.matchDao.getMatchCount(),
|
|
||||||
db.groupDao.getGroupCount(),
|
|
||||||
db.matchDao.getAllMatches(),
|
|
||||||
Future.delayed(Constants.minimumSkeletonDuration),
|
|
||||||
]).then((results) {
|
|
||||||
matchCount = results[0] as int;
|
|
||||||
groupCount = results[1] as int;
|
|
||||||
loadedRecentMatches = results[2] as List<Match>;
|
|
||||||
recentMatches =
|
|
||||||
(loadedRecentMatches
|
|
||||||
..sort((a, b) => b.createdAt.compareTo(a.createdAt)))
|
|
||||||
.take(2)
|
|
||||||
.toList();
|
|
||||||
if (loadedRecentMatches.length < 2) {
|
|
||||||
recentMatches.add(
|
|
||||||
Match(name: 'Dummy Match', winner: null, group: null, players: null),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (mounted) {
|
|
||||||
setState(() {
|
|
||||||
isLoading = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -230,6 +213,40 @@ class _HomeViewState extends State<HomeView> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Loads the data for the HomeView from the database.
|
||||||
|
/// This includes the match count, group count, and recent matches.
|
||||||
|
void loadHomeViewData() {
|
||||||
|
final db = Provider.of<AppDatabase>(context, listen: false);
|
||||||
|
Future.wait([
|
||||||
|
db.matchDao.getMatchCount(),
|
||||||
|
db.groupDao.getGroupCount(),
|
||||||
|
db.matchDao.getAllMatches(),
|
||||||
|
Future.delayed(Constants.minimumSkeletonDuration),
|
||||||
|
]).then((results) {
|
||||||
|
matchCount = results[0] as int;
|
||||||
|
groupCount = results[1] as int;
|
||||||
|
loadedRecentMatches = results[2] as List<Match>;
|
||||||
|
recentMatches =
|
||||||
|
(loadedRecentMatches
|
||||||
|
..sort((a, b) => b.createdAt.compareTo(a.createdAt)))
|
||||||
|
.take(2)
|
||||||
|
.toList();
|
||||||
|
if (loadedRecentMatches.length < 2) {
|
||||||
|
recentMatches.add(
|
||||||
|
Match(name: 'Dummy Match', winner: null, group: null, players: null),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
isLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generates a text representation of the players in the match.
|
||||||
|
/// If the match has a group, it returns the group name and the number of additional players.
|
||||||
|
/// If there is no group, it returns the count of players.
|
||||||
String _getPlayerText(Match game, context) {
|
String _getPlayerText(Match game, context) {
|
||||||
final loc = AppLocalizations.of(context);
|
final loc = AppLocalizations.of(context);
|
||||||
if (game.group == null) {
|
if (game.group == null) {
|
||||||
|
|||||||
@@ -20,10 +20,12 @@ class ChooseGameView extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ChooseGameViewState extends State<ChooseGameView> {
|
class _ChooseGameViewState extends State<ChooseGameView> {
|
||||||
late int selectedGameIndex;
|
/// Controller for the search bar
|
||||||
|
|
||||||
final TextEditingController searchBarController = TextEditingController();
|
final TextEditingController searchBarController = TextEditingController();
|
||||||
|
|
||||||
|
/// Currently selected game index
|
||||||
|
late int selectedGameIndex;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
selectedGameIndex = widget.initialGameIndex;
|
selectedGameIndex = widget.initialGameIndex;
|
||||||
|
|||||||
@@ -136,8 +136,7 @@ class _ChooseGroupViewState extends State<ChooseGroupView> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Filters the groups based on the search query.
|
/// Filters the groups based on the search [query].
|
||||||
/// TODO: Maybe implement also targetting player names?
|
|
||||||
void filterGroups(String query) {
|
void filterGroups(String query) {
|
||||||
setState(() {
|
setState(() {
|
||||||
if (query.isEmpty) {
|
if (query.isEmpty) {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ class ChooseRulesetView extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ChooseRulesetViewState extends State<ChooseRulesetView> {
|
class _ChooseRulesetViewState extends State<ChooseRulesetView> {
|
||||||
|
/// Currently selected ruleset index
|
||||||
late int selectedRulesetIndex;
|
late int selectedRulesetIndex;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ class CreateMatchView extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _CreateMatchViewState extends State<CreateMatchView> {
|
class _CreateMatchViewState extends State<CreateMatchView> {
|
||||||
/// Reference to the app database
|
|
||||||
late final AppDatabase db;
|
late final AppDatabase db;
|
||||||
|
|
||||||
/// Controller for the match name input field
|
/// Controller for the match name input field
|
||||||
|
|||||||
@@ -18,8 +18,12 @@ class MatchResultView extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MatchResultViewState extends State<MatchResultView> {
|
class _MatchResultViewState extends State<MatchResultView> {
|
||||||
late final List<Player> allPlayers;
|
|
||||||
late final AppDatabase db;
|
late final AppDatabase db;
|
||||||
|
|
||||||
|
/// List of all players who participated in the match
|
||||||
|
late final List<Player> allPlayers;
|
||||||
|
|
||||||
|
/// Currently selected winner player
|
||||||
Player? _selectedPlayer;
|
Player? _selectedPlayer;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -132,6 +136,8 @@ class _MatchResultViewState extends State<MatchResultView> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Handles saving or removing the winner in the database
|
||||||
|
/// based on the current selection.
|
||||||
Future<void> _handleWinnerSaving() async {
|
Future<void> _handleWinnerSaving() async {
|
||||||
if (_selectedPlayer == null) {
|
if (_selectedPlayer == null) {
|
||||||
await db.matchDao.removeWinner(matchId: widget.match.id);
|
await db.matchDao.removeWinner(matchId: widget.match.id);
|
||||||
@@ -144,6 +150,10 @@ class _MatchResultViewState extends State<MatchResultView> {
|
|||||||
widget.onWinnerChanged?.call();
|
widget.onWinnerChanged?.call();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retrieves all players associated with the given [match].
|
||||||
|
/// This includes players directly assigned to the match
|
||||||
|
/// as well as members of the group (if any).
|
||||||
|
/// The returned list is sorted alphabetically by player name.
|
||||||
List<Player> getAllPlayers(Match match) {
|
List<Player> getAllPlayers(Match match) {
|
||||||
List<Player> players = [];
|
List<Player> players = [];
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ class _MatchViewState extends State<MatchView> {
|
|||||||
late final AppDatabase db;
|
late final AppDatabase db;
|
||||||
|
flixcoo marked this conversation as resolved
sneeex
commented
kein comment? kein comment?
|
|||||||
bool isLoading = true;
|
bool isLoading = true;
|
||||||
|
flixcoo marked this conversation as resolved
sneeex
commented
kein comment? kein comment?
|
|||||||
|
|
||||||
|
/// Loaded matches from the database,
|
||||||
|
/// initially filled with skeleton matches
|
||||||
List<Match> matches = List.filled(
|
List<Match> matches = List.filled(
|
||||||
4,
|
4,
|
||||||
Match(
|
Match(
|
||||||
@@ -44,7 +46,6 @@ class _MatchViewState extends State<MatchView> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
db = Provider.of<AppDatabase>(context, listen: false);
|
db = Provider.of<AppDatabase>(context, listen: false);
|
||||||
loadGames();
|
loadGames();
|
||||||
}
|
}
|
||||||
@@ -117,6 +118,7 @@ class _MatchViewState extends State<MatchView> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Loads the games from the database and sorts them by creation date.
|
||||||
void loadGames() {
|
void loadGames() {
|
||||||
Future.wait([
|
Future.wait([
|
||||||
db.matchDao.getAllMatches(),
|
db.matchDao.getAllMatches(),
|
||||||
|
|||||||
@@ -25,28 +25,7 @@ class _StatisticsViewState extends State<StatisticsView> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
loadStatisticData();
|
||||||
final db = Provider.of<AppDatabase>(context, listen: false);
|
|
||||||
|
|
||||||
Future.wait([
|
|
||||||
db.matchDao.getAllMatches(),
|
|
||||||
db.playerDao.getAllPlayers(),
|
|
||||||
Future.delayed(Constants.minimumSkeletonDuration),
|
|
||||||
]).then((results) async {
|
|
||||||
if (!mounted) return;
|
|
||||||
final matches = results[0] as List<Match>;
|
|
||||||
final players = results[1] as List<Player>;
|
|
||||||
winCounts = _calculateWinsForAllPlayers(matches, players, context);
|
|
||||||
matchCounts = _calculateMatchAmountsForAllPlayers(
|
|
||||||
matches,
|
|
||||||
players,
|
|
||||||
context,
|
|
||||||
);
|
|
||||||
winRates = computeWinRatePercent(wins: winCounts, matches: matchCounts);
|
|
||||||
setState(() {
|
|
||||||
isLoading = false;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -118,13 +97,43 @@ class _StatisticsViewState extends State<StatisticsView> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Loads matches and players from the database
|
||||||
|
/// and calculates statistics for each player
|
||||||
|
void loadStatisticData() {
|
||||||
|
final db = Provider.of<AppDatabase>(context, listen: false);
|
||||||
|
|
||||||
|
Future.wait([
|
||||||
|
db.matchDao.getAllMatches(),
|
||||||
|
db.playerDao.getAllPlayers(),
|
||||||
|
Future.delayed(Constants.minimumSkeletonDuration),
|
||||||
|
]).then((results) async {
|
||||||
|
if (!mounted) return;
|
||||||
|
final matches = results[0] as List<Match>;
|
||||||
|
final players = results[1] as List<Player>;
|
||||||
|
winCounts = _calculateWinsForAllPlayers(
|
||||||
|
matches: matches,
|
||||||
|
players: players,
|
||||||
|
context: context,
|
||||||
|
);
|
||||||
|
matchCounts = _calculateMatchAmountsForAllPlayers(
|
||||||
|
matches: matches,
|
||||||
|
players: players,
|
||||||
|
context: context,
|
||||||
|
);
|
||||||
|
winRates = computeWinRatePercent(wins: winCounts, matches: matchCounts);
|
||||||
|
setState(() {
|
||||||
|
isLoading = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// Calculates the number of wins for each player
|
/// Calculates the number of wins for each player
|
||||||
/// and returns a sorted list of tuples (playerName, winCount)
|
/// and returns a sorted list of tuples (playerName, winCount)
|
||||||
List<(String, int)> _calculateWinsForAllPlayers(
|
List<(String, int)> _calculateWinsForAllPlayers({
|
||||||
List<Match> matches,
|
required List<Match> matches,
|
||||||
List<Player> players,
|
required List<Player> players,
|
||||||
BuildContext context,
|
required BuildContext context,
|
||||||
) {
|
}) {
|
||||||
List<(String, int)> winCounts = [];
|
List<(String, int)> winCounts = [];
|
||||||
final loc = AppLocalizations.of(context);
|
final loc = AppLocalizations.of(context);
|
||||||
|
|
||||||
@@ -169,11 +178,11 @@ class _StatisticsViewState extends State<StatisticsView> {
|
|||||||
|
|
||||||
/// Calculates the number of matches played for each player
|
/// Calculates the number of matches played for each player
|
||||||
/// and returns a sorted list of tuples (playerName, matchCount)
|
/// and returns a sorted list of tuples (playerName, matchCount)
|
||||||
List<(String, int)> _calculateMatchAmountsForAllPlayers(
|
List<(String, int)> _calculateMatchAmountsForAllPlayers({
|
||||||
List<Match> matches,
|
required List<Match> matches,
|
||||||
List<Player> players,
|
required List<Player> players,
|
||||||
BuildContext context,
|
required BuildContext context,
|
||||||
) {
|
}) {
|
||||||
List<(String, int)> matchCounts = [];
|
List<(String, int)> matchCounts = [];
|
||||||
final loc = AppLocalizations.of(context);
|
final loc = AppLocalizations.of(context);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user
warum für den rest comments aber nicht für db?
Habe Datenbank und
isLoadingnicht kommentiert, weil die so allgegenwärtig sind, dass die eigentlich keinen kommentar brauchen. Soll ich einen hinzufügen?