748 Commits

Author SHA1 Message Date
ab20bd764b implement draft blur navbar
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m0s
Pull Request Pipeline / lint (pull_request) Failing after 2m6s
2026-01-11 11:30:00 +01:00
8ca4e3210e remove button in match view for testing 2026-01-11 11:28:21 +01:00
a480530919 Merge branch 'development' into enhancement/138-neues-navbar-design
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m31s
Pull Request Pipeline / lint (pull_request) Successful in 2m34s
# Conflicts:
#	pubspec.yaml
2026-01-10 22:18:54 +01:00
906c8d8450 Merge pull request 'Versions- und Build Nr in Einstellungen' (#149) from enhancement/146-versions-und-build-nr-in-einstellungen into development
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 1m58s
Pull Request Pipeline / lint (pull_request) Successful in 2m7s
Reviewed-on: #149
Reviewed-by: Mathis Kirchner <mathis.kirchner.mk@gmail.com>
2026-01-10 20:56:25 +00:00
000bdc8cbc Merge remote-tracking branch 'origin/development' into enhancement/146-versions-und-build-nr-in-einstellungen
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m1s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2026-01-10 21:54:09 +01:00
497f30421d Updated string
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m9s
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
2026-01-10 21:29:45 +01:00
adedb85eb2 Merge pull request 'Gruppen nach Spielern durchsuchen' (#147) from enhancement/136-gruppen-nach-spielern-durchsuchen into development
Reviewed-on: #147
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2026-01-10 20:27:53 +00:00
2a72332bcd Updated error string
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m1s
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
2026-01-10 21:23:28 +01:00
7aa41abe61 Implemented version number 2026-01-10 16:20:21 +01:00
e1263d51ad Merge branch 'development' into enhancement/136-gruppen-nach-spielern-durchsuchen
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m0s
Pull Request Pipeline / lint (pull_request) Successful in 2m3s
2026-01-10 15:06:17 +00:00
8791b5296e Merge pull request 'MatchSummaryTile durch MatchTile ersetzen' (#142) from enhancement/137-matchsummarytile-durch-matchtile-ersetzen into development
Reviewed-on: #142
Reviewed-by: Mathis Kirchner <mathis.kirchner.mk@gmail.com>
2026-01-10 15:05:42 +00:00
f2a4327166 Implemented adaptive page route
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2026-01-10 15:55:19 +01:00
d34990ed50 Removed print 2026-01-10 15:54:41 +01:00
2ef671884d New method for specific winner refreshing 2026-01-10 15:54:11 +01:00
2ef8eb6534 Made winner field non final 2026-01-10 15:53:31 +01:00
6f0e5ba5c2 add ability to search for groups members in choose_group_view.dart
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m3s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2026-01-10 15:19:18 +01:00
1c07346aaf Updated version
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m20s
Pull Request Pipeline / lint (pull_request) Successful in 2m28s
2026-01-10 15:16:09 +01:00
830a64b5dd Small changes
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m29s
Pull Request Pipeline / lint (pull_request) Successful in 2m32s
2026-01-10 15:15:52 +01:00
9221f64fa5 Merge branch 'development' into enhancement/137-matchsummarytile-durch-matchtile-ersetzen
# Conflicts:
#	lib/presentation/views/main_menu/match_view/match_view.dart
#	pubspec.yaml
2026-01-10 15:15:14 +01:00
c4f6749882 Fixed state issue in home view
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m2s
Pull Request Pipeline / lint (pull_request) Successful in 2m3s
2026-01-10 15:13:56 +01:00
14a043785e Merge pull request 'PageRoutes adaptable machen' (#145) from enhancement/128-PageRoutes-adaptable-machen into development
Reviewed-on: #145
Reviewed-by: gelbeinhalb <spam@yannick-weigert.de>
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2026-01-10 14:06:10 +00:00
9eb9c0eb7f remove unneccessary import
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m18s
Pull Request Pipeline / lint (pull_request) Successful in 2m18s
2026-01-10 15:02:01 +01:00
54ec865f04 fix merge issues
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m14s
Pull Request Pipeline / lint (pull_request) Failing after 2m23s
2026-01-10 15:00:33 +01:00
d5e7a17127 Merge remote-tracking branch 'origin/development' into enhancement/128-PageRoutes-adaptable-machen
# Conflicts:
#	lib/presentation/views/main_menu/match_view/create_match/create_match_view.dart
2026-01-10 14:57:33 +01:00
275f64b296 Merge pull request 'SnackBar Sichtbarkeit' (#144) from bug/130-Snackbar-Sichtbarkeit into development
Reviewed-on: #144
Reviewed-by: gelbeinhalb <spam@yannick-weigert.de>
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2026-01-10 13:54:57 +00:00
97ca62b083 refactor: rename AdaptivePageRoute to adaptivePageRoute for lowerCamelCase
All checks were successful
Pull Request Pipeline / lint (pull_request) Successful in 2m13s
Pull Request Pipeline / test (pull_request) Successful in 2m18s
2026-01-10 14:52:59 +01:00
32fb1550ff Merge remote-tracking branch 'origin/enhancement/128-PageRoutes-adaptable-machen' into enhancement/128-PageRoutes-adaptable-machen
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Failing after 2m10s
# Conflicts:
#	lib/main.dart
2026-01-10 14:44:53 +01:00
d67972624e replaced ternary operator solution with custom adaptive_page_route.dart 2026-01-10 14:44:33 +01:00
595cf6ead0 Changed skeleton data from 3 to 2 tiles
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m2s
Pull Request Pipeline / lint (pull_request) Successful in 2m4s
2026-01-10 14:20:09 +01:00
6faafe9fab Changed android page transition to Android U transition
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m5s
Pull Request Pipeline / lint (pull_request) Successful in 2m8s
2026-01-10 14:16:16 +01:00
66b90aac25 Fixed issue with android page transition
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m1s
Pull Request Pipeline / lint (pull_request) Successful in 2m5s
2026-01-10 14:09:08 +01:00
d22855fc1a Fixed match view tile width
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2026-01-10 13:57:54 +01:00
1be86bc3c5 Added theme box design 2026-01-10 13:57:46 +01:00
db3e8215fa Added ios swipe back gesture
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m1s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2026-01-10 13:42:09 +01:00
2c4cef76d8 Reimplemented info tile & match tile into it
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m1s
Pull Request Pipeline / lint (pull_request) Successful in 2m3s
2026-01-09 23:55:29 +01:00
a4ef9705f9 made PageRoutes adapt to os, default to MaterialPageRoute
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Successful in 2m7s
2026-01-09 22:22:26 +01:00
799c849570 wrap every view that uses a snackbar in ScaffoldMessenger
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m1s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2026-01-09 21:55:58 +01:00
799b7d8403 Implemented new nav bar with selected animation
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m3s
Pull Request Pipeline / lint (pull_request) Successful in 2m7s
2026-01-09 21:12:09 +01:00
644728a9df Removed unneccesary code
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m1s
Pull Request Pipeline / lint (pull_request) Successful in 2m4s
2026-01-09 20:19:23 +01:00
afb7a5f1d4 MatchTiles only show when recent games are available 2026-01-09 20:15:50 +01:00
3d510d5b3d Implemented compact mode for match tiles 2026-01-09 20:04:10 +01:00
a9d2325eee Implemented match tile in home view 2026-01-09 19:50:51 +01:00
349ff948de Modified match tile 2026-01-09 19:50:44 +01:00
c2394c3733 Merge pull request 'MVP-Refactoring' (#139) from refactoring/68-mvp-refactoring into development
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Successful in 2m8s
Reviewed-on: #139
Reviewed-by: gelbeinhalb <spam@yannick-weigert.de>
Reviewed-by: Mathis Kirchner <mathis.kirchner.mk@gmail.com>
2026-01-08 20:24:01 +00:00
88766652b9 Small loc corrections
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Successful in 2m21s
2026-01-08 21:21:33 +01:00
2a1573ee2d Remove Whitespace
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m12s
Pull Request Pipeline / lint (pull_request) Successful in 2m15s
2026-01-08 21:15:01 +01:00
cfb07bfe28 Updated localizations
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m14s
Pull Request Pipeline / lint (pull_request) Successful in 2m18s
2026-01-08 21:13:24 +01:00
d741990f2f Fixed navbar issue
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
2026-01-08 21:07:30 +01:00
76121eb4fb Updated localizations
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Successful in 2m18s
2026-01-07 17:30:19 +01:00
d5ee6449b0 Updated localizations
All checks were successful
Pull Request Pipeline / lint (pull_request) Successful in 2m11s
Pull Request Pipeline / test (pull_request) Successful in 2m10s
2026-01-07 17:02:06 +01:00
7d9757abb6 Merge branch 'development' into refactoring/68-mvp-refactoring
# Conflicts:
#	lib/l10n/generated/app_localizations.dart
#	lib/l10n/generated/app_localizations_de.dart
#	lib/l10n/generated/app_localizations_en.dart
2026-01-07 16:58:15 +01:00
d94d51c6ea Merge pull request 'change settings icons to filled and rounded' (#140) from enhancement/135-settings-icons into development
Reviewed-on: #140
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2026-01-07 14:23:27 +00:00
gelbeinhalb
803cf8a972 update app_localizations
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m0s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2026-01-07 15:17:13 +01:00
gelbeinhalb
13be75a65b change settings icons to filled and rounded
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m3s
Pull Request Pipeline / lint (pull_request) Successful in 2m5s
2026-01-07 15:12:12 +01:00
aef12bd65a Refactored several theme settings into custom theme
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m3s
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
2026-01-07 14:54:53 +01:00
02d79574dd Simplified app bar logic in views 2026-01-07 14:43:13 +01:00
fdd0e7579a Updated game title process 2026-01-07 14:35:07 +01:00
cd2770be26 Removed unnessecary setStates 2026-01-07 14:33:52 +01:00
e196d6e5ef Corrected strings 2026-01-07 14:32:40 +01:00
bc3beac866 Replaced Matches with Spiele 2026-01-07 14:25:14 +01:00
aa936a938d Corrected translation 2026-01-07 14:23:47 +01:00
2811ea892e Added dispose & formatting 2026-01-07 14:15:23 +01:00
4b1d3923a0 Optimized ruleset touples 2026-01-07 14:11:14 +01:00
0f824bb30a Optimized statistics tile 2026-01-07 14:10:09 +01:00
21c74b74bc Refactored components 2026-01-07 14:05:19 +01:00
6e45e9435b Refactored views 2026-01-07 13:27:39 +01:00
a78614851b Added constants class 2026-01-07 13:02:09 +01:00
8df9a27dc7 Merge pull request 'Lokalisierung implementieren' (#112) from feature/100-lokalisierung-hinzufügen into development
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m1s
Pull Request Pipeline / lint (pull_request) Successful in 2m7s
Reviewed-on: #112
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2026-01-07 11:30:11 +00:00
52180eeb6d Merge branch 'development' into feature/100-lokalisierung-hinzufügen
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m2s
Pull Request Pipeline / lint (pull_request) Successful in 2m4s
2026-01-07 11:28:04 +00:00
0893667e41 Merge pull request 'Konsistenzfehler im JSON Vermeiden' (#125) from enhancement/70-konsistenzfehler-im-json-vermeiden into development
Reviewed-on: #125
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2026-01-07 11:27:44 +00:00
1dc5286c6b change double to single quotes
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m2s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2026-01-07 12:08:21 +01:00
gelbeinhalb
f140ebae2e Merge branch 'enhancement/70-konsistenzfehler-im-json-vermeiden' of git.yannick-weigert.de:liquid-development/game-tracker into enhancement/70-konsistenzfehler-im-json-vermeiden
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m16s
Pull Request Pipeline / lint (pull_request) Successful in 2m22s
2026-01-07 12:00:33 +01:00
a487e4071f Sort files
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m17s
Pull Request Pipeline / lint (pull_request) Failing after 2m24s
2026-01-07 12:00:25 +01:00
gelbeinhalb
99044c0ea0 remove unnecessary check 2026-01-07 12:00:25 +01:00
69effa2b7d change winner localization to not include placeholder 2026-01-07 11:49:10 +01:00
5db008c274 Merge branch 'development' into feature/100-lokalisierung-hinzufügen
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m8s
Pull Request Pipeline / lint (pull_request) Successful in 2m12s
2026-01-05 15:04:19 +00:00
feaa0709a7 Merge branch 'development' into enhancement/70-konsistenzfehler-im-json-vermeiden
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m14s
Pull Request Pipeline / lint (pull_request) Successful in 2m17s
2026-01-05 15:03:39 +00:00
gelbeinhalb
2fea3597fe Merge branch 'enhancement/70-konsistenzfehler-im-json-vermeiden' of git.yannick-weigert.de:liquid-development/game-tracker into enhancement/70-konsistenzfehler-im-json-vermeiden
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m3s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2026-01-05 11:46:34 +01:00
gelbeinhalb
7b2314a25e fix null error for winnerId and groupId in match import 2026-01-05 11:46:26 +01:00
gelbeinhalb
7f6c1cb9a6 change InsertMode to insertOrIgnore not insertOrReplace 2026-01-05 11:40:57 +01:00
dcfed75a93 Merge pull request 'Player in Gewinner Auswahl, Match- und Grouptile sortieren' (#134) from enhancement/133-gewinner-auswahl-sortieren into development
Reviewed-on: #134
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2026-01-04 20:46:04 +00:00
7fa434782c remove semicolon and empty line
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m3s
Pull Request Pipeline / lint (pull_request) Successful in 2m5s
2026-01-03 17:49:37 +01:00
bdcee85eb9 sort players in group tile 2026-01-03 17:49:15 +01:00
072dba1cde sort players in match tile 2026-01-03 17:45:35 +01:00
3c7c4598ff sort players in winner selection 2026-01-03 17:42:25 +01:00
1a20d7b64c Merge branch 'development' into enhancement/70-konsistenzfehler-im-json-vermeiden
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m24s
Pull Request Pipeline / lint (pull_request) Successful in 2m27s
2026-01-03 14:39:40 +00:00
ec94e12ed7 implement changes
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m27s
Pull Request Pipeline / lint (pull_request) Successful in 2m33s
2026-01-03 15:38:25 +01:00
9fc308554c Merge remote-tracking branch 'origin/development' into feature/100-lokalisierung-hinzufügen
# Conflicts:
#	lib/presentation/views/main_menu/match_view/create_match/choose_game_view.dart
#	lib/presentation/views/main_menu/match_view/create_match/choose_group_view.dart
#	lib/presentation/views/main_menu/match_view/create_match/choose_ruleset_view.dart
2026-01-03 14:42:53 +01:00
42cef337aa Merge pull request 'ChooseViews Speichern nicht bei Zurück gehen' (#127) from bug/126-ChooseViews-Speichern-nicht-bei-Zurück-gehen into development
Reviewed-on: #127
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2026-01-03 12:53:51 +00:00
gelbeinhalb
d9980edf0e Merge branch 'enhancement/70-konsistenzfehler-im-json-vermeiden' of git.yannick-weigert.de:liquid-development/game-tracker into enhancement/70-konsistenzfehler-im-json-vermeiden
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m7s
Pull Request Pipeline / lint (pull_request) Successful in 2m7s
2026-01-03 13:20:59 +01:00
gelbeinhalb
4c084cae4a remove ?? as members cant be null 2026-01-03 13:20:36 +01:00
gelbeinhalb
cecfd5da4e update schema.json to current data import version 2026-01-03 13:19:58 +01:00
5289660327 add comment
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m5s
Pull Request Pipeline / lint (pull_request) Successful in 2m8s
2026-01-03 11:02:43 +01:00
16e1f542f5 fix choose rulset & choose group view not saving 2026-01-03 11:02:38 +01:00
e4ae526d93 fix choose_game_view not saving
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m3s
Pull Request Pipeline / lint (pull_request) Successful in 2m5s
2026-01-03 10:16:28 +01:00
2f65316a51 Merge branch 'development' into enhancement/70-konsistenzfehler-im-json-vermeiden
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m5s
Pull Request Pipeline / lint (pull_request) Failing after 2m8s
2026-01-02 20:45:47 +00:00
31abb7f1e4 Merge remote-tracking branch 'origin/development' into feature/100-lokalisierung-hinzufügen
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m7s
Pull Request Pipeline / lint (pull_request) Successful in 2m12s
# Conflicts:
#	lib/presentation/widgets/player_selection.dart
2026-01-02 21:32:40 +01:00
132966f3d2 increase title_description_list_tile width to make german translation fully visible
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m9s
Pull Request Pipeline / lint (pull_request) Successful in 2m23s
2026-01-02 21:28:46 +01:00
77095725de fix game choose view highlighting not working 2026-01-02 21:26:54 +01:00
d081a597db Merge pull request 'Ausgewählte Spieler durch Gruppe werden nicht aussortiert' (#124) from bug/113-ausgewählte-spieler-durch-gruppe-werden-nicht-aussortiert into development
Reviewed-on: #124
Reviewed-by: Mathis Kirchner <mathis.kirchner.mk@gmail.com>
2026-01-02 20:22:45 +00:00
bdc3453d7f correct spelling mistake
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m9s
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
2026-01-02 21:20:30 +01:00
678ab90af3 removed unneccessary null assertion operators
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m3s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2026-01-02 21:16:13 +01:00
a038c22ba6 removed else in fallback 2026-01-02 21:13:00 +01:00
22fcff73bd configure en locale as fallback
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m5s
Pull Request Pipeline / lint (pull_request) Failing after 2m7s
2026-01-02 21:11:37 +01:00
gelbeinhalb
4a67dae456 change import/export json logic to remove redundant data
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Failing after 2m5s
2026-01-02 20:37:10 +01:00
3c22b084d6 made getters non nullable and removed all null assertion operators
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m10s
Pull Request Pipeline / lint (pull_request) Failing after 2m11s
2026-01-02 19:01:44 +01:00
7f923f6dff Merge remote-tracking branch 'origin/development' into feature/100-lokalisierung-hinzufügen
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m15s
Pull Request Pipeline / lint (pull_request) Successful in 2m15s
# Conflicts:
#	lib/presentation/views/main_menu/home_view.dart
#	lib/presentation/views/main_menu/match_view/create_match/create_match_view.dart
#	lib/presentation/views/main_menu/match_view/match_view.dart
2026-01-02 18:49:34 +01:00
87856e6548 Simplified info texts
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m8s
Pull Request Pipeline / lint (pull_request) Successful in 2m8s
2026-01-02 18:41:39 +01:00
cb7804cf55 Fixed Problem with widget state 2026-01-02 18:38:13 +01:00
304fa82a93 Fixed bug in player selection
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m7s
Pull Request Pipeline / lint (pull_request) Successful in 2m7s
2026-01-01 23:14:52 +01:00
f84a645e61 Merge pull request 'Optionaler Match-Name' (#121) from enhancement/115-Optionaler-Match-Name into development
Reviewed-on: #121
2026-01-01 21:50:11 +00:00
b0073addf8 remove unnecessary trim
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m18s
Pull Request Pipeline / lint (pull_request) Successful in 2m18s
2026-01-01 22:45:55 +01:00
b5c17ac5a9 Merge branch 'development' into enhancement/115-Optionaler-Match-Name
All checks were successful
Pull Request Pipeline / lint (pull_request) Successful in 2m41s
Pull Request Pipeline / test (pull_request) Successful in 2m44s
2026-01-01 21:43:37 +00:00
4451f9e2a9 Merge branch 'development' into feature/100-lokalisierung-hinzufügen
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m34s
Pull Request Pipeline / lint (pull_request) Successful in 2m36s
2026-01-01 21:43:19 +00:00
1d4fdae84b Hotfix: Missing game renames
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m5s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2026-01-01 22:40:26 +01:00
60862de4c4 Merge pull request 'Letztes Tile in Matchview nicht lesbar' (#123) from bug/122-Letztes-Tile-in-MatchView-nicht-lesbar into development
Reviewed-on: #123
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2026-01-01 21:33:02 +00:00
6899bb0c3c add comment
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Successful in 2m11s
2026-01-01 21:47:13 +01:00
55a22b292f changed bottom padding
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Successful in 2m7s
2026-01-01 21:40:18 +01:00
db30b0fd5a removed double quotes
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m19s
Pull Request Pipeline / lint (pull_request) Successful in 2m23s
2026-01-01 19:15:57 +01:00
5ee0d59377 implement optional match name with game name as default
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m23s
Pull Request Pipeline / lint (pull_request) Failing after 2m24s
2026-01-01 19:13:50 +01:00
f22595e678 Add localization for 'none_group' option in English and German
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m3s
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
2026-01-01 18:44:43 +01:00
25fe10eb9a added missing square bracket 2026-01-01 18:44:28 +01:00
5a318f9760 Merge remote-tracking branch 'origin/feature/100-lokalisierung-hinzufügen' into feature/100-lokalisierung-hinzufügen 2026-01-01 18:44:03 +01:00
0051990168 Remove auto_localize dependency from pubspec.yaml 2026-01-01 18:43:06 +01:00
7e21c65026 Merge branch 'development' into feature/100-lokalisierung-hinzufügen
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m11s
Pull Request Pipeline / lint (pull_request) Failing after 2m35s
2026-01-01 17:33:47 +00:00
cc23c03f6b Add localization for 'not available' message in English and German
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Failing after 2m15s
2026-01-01 18:32:01 +01:00
d77b5f20f9 Update statistics_view.dart to use localized 'not available' message for players 2026-01-01 18:31:53 +01:00
3c3bf506cb Add TODO for implementing quick create functionality in home_view.dart 2026-01-01 18:31:37 +01:00
8afba5680b Add localization for no statistics available message and removed dots from all messages
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Successful in 2m11s
2026-01-01 18:18:14 +01:00
7103765054 Update statistics_view.dart to use localized message no statistics available instead of no data available 2026-01-01 18:17:53 +01:00
bc01a6de9a Add localization for search input fields in English and German
All checks were successful
Pull Request Pipeline / lint (pull_request) Successful in 2m26s
Pull Request Pipeline / test (pull_request) Successful in 2m15s
2026-01-01 18:10:44 +01:00
ad87dca674 add generated files
Some checks failed
Pull Request Pipeline / lint (pull_request) Failing after 2m47s
Pull Request Pipeline / test (pull_request) Successful in 2m27s
2026-01-01 18:10:24 +01:00
633a21d829 Updated search bar hint texts to use localization for group and player searches
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m38s
Pull Request Pipeline / lint (pull_request) Failing after 2m54s
2026-01-01 18:10:08 +01:00
81f63c1c07 made statistics_view.dart use localization and fix merge error
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m41s
Pull Request Pipeline / lint (pull_request) Successful in 2m42s
2026-01-01 18:09:50 +01:00
fc6c74b377 Merge pull request 'Entfernen von Ausgewählten Spielern, fügt sie nicht wieder zur Auswahl hinzu' (#117) from bug/116-entfernen-von-ausgewählten-spielern-fuegt-sie-nicht-wieder-zur-auswahl-hinzu into development
Reviewed-on: #117
Reviewed-by: Mathis Kirchner <mathis.kirchner.mk@gmail.com>
2026-01-01 16:50:07 +00:00
15d09f381a New created players will be added now at the front too
All checks were successful
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
Pull Request Pipeline / test (pull_request) Successful in 2m8s
2026-01-01 17:47:15 +01:00
f97c341b81 added devtools_options.yaml to .gitignore
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m16s
Pull Request Pipeline / lint (pull_request) Successful in 2m23s
2026-01-01 17:43:24 +01:00
7bf03ec388 added auto-generated files to git
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m26s
Pull Request Pipeline / lint (pull_request) Successful in 2m26s
2026-01-01 17:42:38 +01:00
0bfaba4225 Refactored German localization strings by removing redundant entries
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m3s
Pull Request Pipeline / lint (pull_request) Successful in 2m25s
2026-01-01 17:40:36 +01:00
bbb7914fc5 Updated sorting logic & added comments
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m0s
Pull Request Pipeline / lint (pull_request) Successful in 2m5s
2026-01-01 16:39:57 +01:00
86dbc9afb0 Optimized ruleset selection in CreateMatchView
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m2s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2026-01-01 00:42:21 +01:00
73aea0d0f5 added missings consts
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Failing after 2m8s
2026-01-01 00:39:15 +01:00
ed9e3af768 merged dev into branch and fixed missing comma
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m3s
Pull Request Pipeline / lint (pull_request) Failing after 2m5s
2026-01-01 00:34:55 +01:00
d93ead40b6 Merge remote-tracking branch 'origin/development' into feature/100-lokalisierung-hinzufügen
# Conflicts:
#	lib/presentation/views/main_menu/statistics_view.dart
2026-01-01 00:32:10 +01:00
3374a80c27 Merge pull request 'Bei 0 gespielten Matches keine Stats anzeigen' (#111) from enhancement/109-bei-0-gespielten-matches-keine-stats-anzeigen into development
Reviewed-on: #111
2025-12-31 23:30:26 +00:00
534d19efc3 Implemented localization across the application.
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m5s
Pull Request Pipeline / lint (pull_request) Failing after 2m22s
2026-01-01 00:21:09 +01:00
d9a26a8cf7 Added English and German localization files containing all strings used in app 2026-01-01 00:20:44 +01:00
8e05e9d61b Added l10n.yaml for localization configuration 2026-01-01 00:20:22 +01:00
179ac2fe21 Update localization dependencies and enable code generation 2026-01-01 00:20:16 +01:00
2b78617924 Redo seperate visibility
All checks were successful
Pull Request Pipeline / lint (pull_request) Successful in 2m11s
Pull Request Pipeline / test (pull_request) Successful in 2m11s
2025-12-31 19:11:34 +01:00
175a9cb349 Added hiding statistics tiles if their corresponding data is not available
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m1s
Pull Request Pipeline / lint (pull_request) Successful in 2m4s
2025-12-31 18:36:33 +01:00
18f0626e95 Added empty statistics message 2025-12-31 18:33:09 +01:00
d99a04549a Merge pull request 'Möglichkeit der horizontalen Nutzung deaktivieren' (#110) from feature/108-Möglichkeit-der-horizontalen-Nutzung-deaktivieren into development
Reviewed-on: #110
2025-12-31 17:00:31 +00:00
cc1ecc4c86 Merge branch 'development' into feature/108-Möglichkeit-der-horizontalen-Nutzung-deaktivieren
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m15s
Pull Request Pipeline / lint (pull_request) Successful in 2m22s
2025-12-31 16:41:08 +00:00
16cdf9db3e Restricted app orientation to portrait mode on iOS and Android
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m21s
Pull Request Pipeline / lint (pull_request) Successful in 2m24s
2025-12-31 17:39:20 +01:00
da494ed146 Merge pull request 'Fehlende Umbenennungen' (#106) from refactoring/105-fehlende-umbenennungen into development
Reviewed-on: #106
Reviewed-by: Mathis Kirchner <mathis.kirchner.mk@gmail.com>
2025-12-31 16:27:29 +00:00
af0242c44f Merge branch 'development' into refactoring/105-fehlende-umbenennungen
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Successful in 2m7s
2025-12-31 16:25:19 +00:00
cd63f5cf06 Merge pull request 'Fehlende Info in CreateGroupView' (#107) from bug/73-Fehlende-Info-in-CreateGroupView into development
Reviewed-on: #107
Reviewed-by: Mathis Kirchner <mathis.kirchner.mk@gmail.com>
2025-12-31 16:24:31 +00:00
8c3282b954 Changed color to white
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 1m57s
Pull Request Pipeline / lint (pull_request) Successful in 4m58s
2025-12-31 17:10:47 +01:00
1c0fb9f3ab Merge branch 'development' into bug/73-Fehlende-Info-in-CreateGroupView
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m19s
Pull Request Pipeline / lint (pull_request) Successful in 2m21s
2025-12-31 16:41:26 +01:00
bfca41bd36 Fixed info message placement
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m19s
Pull Request Pipeline / lint (pull_request) Successful in 2m21s
2025-12-31 16:38:09 +01:00
92b8ef0877 Merge branch 'development' into refactoring/105-fehlende-umbenennungen
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m18s
Pull Request Pipeline / lint (pull_request) Successful in 2m18s
2025-12-30 21:22:34 +01:00
5428064c53 Some last changes
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m16s
Pull Request Pipeline / lint (pull_request) Successful in 2m21s
2025-12-30 21:22:07 +01:00
27916456db Merge pull request 'Fehler bei Match-Erstellung' (#104) from bug/102-fehler-bei-match-erstellung into development
Reviewed-on: #104
Reviewed-by: Mathis Kirchner <mathis.kirchner.mk@gmail.com>
2025-12-30 20:17:18 +00:00
58fe38fd72 Updated comment
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Successful in 2m10s
2025-12-30 21:02:03 +01:00
ecd03dfd9d Updated hint text 2025-12-30 21:01:40 +01:00
05c6625bf3 Renamed MatchResultView and match variable 2025-12-30 21:01:07 +01:00
9821af39fe Renamed test files 2025-12-30 21:00:56 +01:00
c1789458e0 Added tests for bug causing behaviour
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Successful in 2m8s
2025-12-30 20:56:39 +01:00
e19f696714 Fixed tests with adding players and groups to database on setup
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Successful in 2m11s
2025-12-30 18:51:57 +01:00
9cb35dc4a1 Updated comments
Some checks failed
Pull Request Pipeline / test (pull_request) Failing after 2m9s
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
2025-12-30 18:45:28 +01:00
b8b65c4ca1 Removed lines that added the group and players to the db again in addMatch()
Some checks failed
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
Pull Request Pipeline / test (pull_request) Failing after 2m19s
2025-12-30 18:23:15 +01:00
356cb1fb43 Updated insert mode to fix problem with replacing existing player match connections 2025-12-30 18:21:39 +01:00
4c8896d2d9 Merge pull request 'Fehlende Aktualisierung in MatchView' (#101) from bug/95-fehlende-aktualisierung-in-matchview into development
Reviewed-on: #101
Reviewed-by: Mathis Kirchner <mathis.kirchner.mk@gmail.com>
2025-12-30 16:49:02 +00:00
31c8598222 Made cleaner version
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2025-12-29 19:28:47 +01:00
884680d329 Merge branch 'development' into bug/95-fehlende-aktualisierung-in-matchview
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m3s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2025-12-29 19:23:11 +01:00
5ae569f2e7 Fixed updating error
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m1s
Pull Request Pipeline / lint (pull_request) Successful in 2m3s
2025-12-29 19:16:25 +01:00
37d6ad81fd Merge pull request 'ChooseGroupView zeigt keine Group entspricht der Suche, obwohl nur Gruppen leer' (#98) from bug/94-choosegroupview-zeigt-keine-group-entspricht-der-suche-obwohl-nur-gruppen-leer into development
Reviewed-on: #98
Reviewed-by: Mathis Kirchner <mathis.kirchner.mk@gmail.com>
2025-12-29 17:47:11 +00:00
cea6c36407 Merge branch 'development' into bug/94-choosegroupview-zeigt-keine-group-entspricht-der-suche-obwohl-nur-gruppen-leer
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m3s
Pull Request Pipeline / lint (pull_request) Successful in 2m5s
2025-12-29 17:45:00 +00:00
1b300faea9 Merge pull request '"Per Player" entfernen' (#99) from enhancement/93-per-player-entfernen into development
Reviewed-on: #99
Reviewed-by: gelbeinhalb <spam@yannick-weigert.de>
Reviewed-by: Mathis Kirchner <mathis.kirchner.mk@gmail.com>
2025-12-29 17:41:50 +00:00
dac5cc8a89 Hab leider nur von Wand bis Tapete gedacht
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m2s
Pull Request Pipeline / lint (pull_request) Successful in 2m5s
2025-12-29 18:37:44 +01:00
bafbde7d03 Merge remote-tracking branch 'origin/bug/94-choosegroupview-zeigt-keine-group-entspricht-der-suche-obwohl-nur-gruppen-leer' into bug/94-choosegroupview-zeigt-keine-group-entspricht-der-suche-obwohl-nur-gruppen-leer 2025-12-29 18:35:26 +01:00
fdea594a1e Merge branch 'development' into bug/94-choosegroupview-zeigt-keine-group-entspricht-der-suche-obwohl-nur-gruppen-leer
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m33s
Pull Request Pipeline / lint (pull_request) Successful in 2m36s
2025-12-29 17:28:50 +00:00
856ce43c49 Updated statistics title
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m32s
Pull Request Pipeline / lint (pull_request) Successful in 2m37s
2025-12-29 18:28:06 +01:00
5c8b93072f Merge branch 'development' into bug/94-choosegroupview-zeigt-keine-group-entspricht-der-suche-obwohl-nur-gruppen-leer 2025-12-29 18:25:30 +01:00
94fdd7026d Merge pull request 'FutureBuilder-/Skeleton-/Futurelogik verbessern' (#90) from enhancement/80-FutureBuilder-Logik-bei-Interaktion-mit-DB-verbessern into development
Reviewed-on: #90
Reviewed-by: gelbeinhalb <spam@yannick-weigert.de>
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2025-12-29 17:21:49 +00:00
966f7caa54 Fixed info message
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m8s
Pull Request Pipeline / lint (pull_request) Successful in 2m13s
2025-12-29 18:19:29 +01:00
88bea48956 Merge remote-tracking branch 'origin/development' into enhancement/80-FutureBuilder-Logik-bei-Interaktion-mit-DB-verbessern
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m13s
Pull Request Pipeline / lint (pull_request) Successful in 2m17s
# Conflicts:
#	lib/presentation/views/main_menu/match_view/match_view.dart
2025-12-29 18:19:03 +01:00
a2e66b9c80 Merge pull request 'Letztes Gametile nicht komplett sichtbar' (#96) from bug/79-Letztes-Gametile-in-der-GamesView-ist-nicht-lesbar into development
Reviewed-on: #96
Reviewed-by: gelbeinhalb <spam@yannick-weigert.de>
2025-12-25 09:55:31 +00:00
d7a006dd87 fixed last gametile not visible
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m8s
Pull Request Pipeline / lint (pull_request) Successful in 2m8s
2025-12-24 23:51:34 +01:00
12856342a8 remove dots after sentences
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m1s
Pull Request Pipeline / lint (pull_request) Successful in 2m4s
2025-12-24 22:53:17 +01:00
b0a5145490 move setState to include match loading and sorting in MatchView 2025-12-24 13:14:31 +01:00
7a80c1a792 adjust heightFactor for empty game state in home view
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m5s
Pull Request Pipeline / lint (pull_request) Successful in 2m7s
2025-12-24 13:08:25 +01:00
c73f37507f put isLoading in existing setState and move mounted check up
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Successful in 2m7s
2025-12-24 13:05:49 +01:00
1e730cebe6 wrap isLoading into mounted and setState
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m8s
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
2025-12-24 13:01:40 +01:00
7eb25221d7 add mounted check before calling setState in match_view 2025-12-24 13:01:16 +01:00
f9722bc762 wrap isLoading = false in a mounted check and setState call 2025-12-24 13:01:05 +01:00
f2917a6813 removed empty line 2025-12-24 13:00:38 +01:00
b29cd6dff4 remove double quotes
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m15s
Pull Request Pipeline / lint (pull_request) Successful in 2m21s
2025-12-24 12:54:05 +01:00
1d92084da6 fix rangeerror when only 1 or less matches exist
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m21s
Pull Request Pipeline / lint (pull_request) Failing after 2m34s
2025-12-24 12:53:37 +01:00
7732c6ceb9 remove futurebuilder from match view and refactor
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m10s
Pull Request Pipeline / lint (pull_request) Successful in 2m10s
2025-12-23 23:17:27 +01:00
a747d91c5d refactor group loading into reusable method loadGroups and call it after adding a group 2025-12-23 23:16:57 +01:00
06a9c0cd84 remove futurebuilder from player selection and refactor 2025-12-23 22:59:01 +01:00
9ad5c4ad6f remove futurebuilder from groups view and refactor 2025-12-23 22:58:49 +01:00
9b3d61e5b0 remove futurebuilder from playerselection and refactor 2025-12-23 22:36:11 +01:00
df0a5207c2 add const
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m5s
Pull Request Pipeline / lint (pull_request) Successful in 2m22s
2025-12-21 20:01:48 +01:00
4f0a1eec6d refactor
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Failing after 2m6s
2025-12-21 19:50:34 +01:00
24b60bb18b added minimumSkeletonDuration constant and changed future logic 2025-12-21 19:46:59 +01:00
c8532adfde changed skeleton duration logic in statistics view and refactored 2025-12-21 15:52:02 +01:00
76186787e7 changed futurebuilder logic in player selection 2025-12-21 15:51:24 +01:00
f05114a99e removed futurebuilder logic in groups_view 2025-12-21 15:50:39 +01:00
d96494f608 Changed futurebuilder logic in groups_view 2025-12-21 15:50:24 +01:00
0eaf3d251b added constant minimumSkeletonDuration 2025-12-21 15:49:58 +01:00
0567fce02b Merge pull request 'Game zu Match umbenennen' (#89) from refactoring/78-game-zu-match-umbenennen into development
Reviewed-on: #89
Reviewed-by: gelbeinhalb <spam@yannick-weigert.de>
2025-12-12 15:34:17 +00:00
74ea540b39 Merge branch 'feature/3-creategameview-erstellen' into refactoring/78-game-zu-match-umbenennen
All checks were successful
Pull Request Pipeline / lint (pull_request) Successful in 2m8s
Pull Request Pipeline / test (pull_request) Successful in 2m9s
2025-12-11 20:13:55 +01:00
d578a7f9bd Missing comment 2025-12-11 20:12:56 +01:00
0e5ad1c3d9 Another missing 2025-12-11 20:12:21 +01:00
c4b249b199 Added missing game instants 2025-12-11 20:11:02 +01:00
99cea1e703 Renamed every instance of "game" to "match" 2025-12-11 20:07:32 +01:00
7b7c41b96c Merge pull request 'CreateGameView erstellen' (#67) from feature/3-creategameview-erstellen into development
Reviewed-on: #67
Reviewed-by: gelbeinhalb <spam@yannick-weigert.de>
Reviewed-by: mathiskir <mathis.kirchner.mk@gmail.com>
2025-12-10 20:43:53 +00:00
d0059b44a8 Moved statement
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m5s
Pull Request Pipeline / lint (pull_request) Successful in 2m8s
2025-12-10 21:41:37 +01:00
3b3d298ff5 Small refactoring
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m1s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2025-12-10 14:04:15 +01:00
e1626225ac Removed future builder 2025-12-10 13:56:03 +01:00
93ced81e7e Fixed filtering problem with object reference 2025-12-10 13:55:31 +01:00
23cdddfbd9 Fixed problem with player selection
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m7s
Pull Request Pipeline / lint (pull_request) Successful in 2m7s
2025-12-10 12:38:39 +01:00
5d2fed74ac Fixed sorting problem
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m1s
Pull Request Pipeline / lint (pull_request) Successful in 2m4s
2025-12-09 23:59:34 +01:00
0d0806dfbb Implemented listener
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m7s
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
2025-12-09 22:25:45 +01:00
27ff599a88 Reverted method
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m2s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2025-12-09 20:52:38 +01:00
c4094a547e Fixed button state problem 2025-12-09 20:52:14 +01:00
701500c7e2 Fixed state problem with games list
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2025-12-09 18:26:05 +01:00
062c2681bf Corrected info message 2025-12-09 18:10:31 +01:00
7cff48ebc0 Added empty message
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m14s
Pull Request Pipeline / lint (pull_request) Successful in 2m14s
2025-12-07 22:23:43 +01:00
708157df54 Implemented leaving players in the player selection and filtering those who are in the group
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m11s
Pull Request Pipeline / lint (pull_request) Successful in 2m12s
2025-12-07 22:15:19 +01:00
f1f3fd7b6e Fixed deselecting game bug 2025-12-07 22:03:28 +01:00
7bc75d60a7 Fixed text overflow
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m33s
Pull Request Pipeline / lint (pull_request) Successful in 2m36s
2025-12-07 19:31:11 +01:00
a1ed17355a Minimum of 2 players required to create a game, unless group is selected 2025-12-07 19:23:38 +01:00
45abc79f95 Removed unneccesary db declaration 2025-12-07 19:17:56 +01:00
c214a26c54 Removed onChanged 2025-12-07 19:17:20 +01:00
6c0cb92e56 Removed unneccesary title in tupe 2025-12-07 19:17:13 +01:00
b4ba4f8d74 Implemented search bar in choose_group_view 2025-12-07 19:12:43 +01:00
f60c11fc08 Added searchbar for choose_group_view 2025-12-07 19:01:19 +01:00
d2d0a82c9b Implemented deselecting game 2025-12-07 18:58:49 +01:00
1044ee9bea Merge branch 'development' into feature/3-creategameview-erstellen
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m10s
Pull Request Pipeline / lint (pull_request) Successful in 2m20s
2025-12-07 15:48:42 +01:00
32e812127d Merge pull request 'Group erstellen nur möglich mit min. 2 Spielern' (#82) from enhancement/75-Group-erstellen-nur-möglich-mit-min.-2-spielern into development
Reviewed-on: #82
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2025-12-07 14:06:37 +00:00
4500d85f78 Merge branch 'development' into enhancement/75-Group-erstellen-nur-möglich-mit-min.-2-spielern
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m13s
Pull Request Pipeline / lint (pull_request) Successful in 2m14s
2025-12-07 14:04:19 +00:00
c8bf03f462 Merge pull request 'Skeleton in GameHistoryView anpassen' (#86) from enhancement/85-skeleton-in-gamehistoryview-anpassen into development
Reviewed-on: #86
Reviewed-by: mathiskir <mathis.kirchner.mk@gmail.com>
2025-12-07 14:04:04 +00:00
7ecccb13c2 Updated skeleton data
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m8s
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
2025-12-07 13:04:30 +01:00
4fc1959704 Merge branch 'development' into feature/3-creategameview-erstellen
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Successful in 2m8s
2025-12-06 23:19:13 +01:00
1e03507f75 Merge pull request 'Fix für nicht funktionierende SearchBar' (#84) from bug/83-Search-in-CreateGameView-und-CreateGroupView-funktioniert-nicht into development
Reviewed-on: #84
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2025-12-06 22:18:20 +00:00
e37a98fdcc hart besoffenen fehler gefixt?
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m5s
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
2025-12-06 21:53:24 +01:00
6ae0471fa2 Implemented final navigation to GameResultView
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m8s
Pull Request Pipeline / lint (pull_request) Successful in 2m19s
2025-12-06 17:42:11 +01:00
a1a995777b Adjusted margin
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Successful in 2m8s
2025-12-06 17:23:40 +01:00
3d12f0c160 Fixed width problem in choose game view 2025-12-06 17:23:20 +01:00
10aad47124 Updated choosing mechanism
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m5s
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
2025-12-06 17:13:33 +01:00
75b62d0854 Replaced temp navigator 2025-12-06 16:58:12 +01:00
527f163346 Merge branch 'development' into feature/3-creategameview-erstellen
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m8s
Pull Request Pipeline / lint (pull_request) Successful in 2m10s
2025-12-06 16:54:30 +01:00
6ae7166d34 Update state when selecting players and require at least two players to create a group
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Successful in 2m10s
2025-12-06 15:18:41 +01:00
dcd8b460c1 Merge pull request 'GameResultView erstellen' (#62) from feature/48-game-result-view-erstellen into development
Reviewed-on: #62
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2025-12-06 14:06:29 +00:00
dbbe04d4cc add braces to if/else statement in game_result_view.dart
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m18s
Pull Request Pipeline / lint (pull_request) Successful in 2m20s
2025-12-06 14:21:17 +01:00
1ed6290628 Refactor winner selection and persistence logic in GameResultView
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m25s
Pull Request Pipeline / lint (pull_request) Failing after 2m25s
2025-12-06 14:20:37 +01:00
91a7273964 madio radio list tile toggleable 2025-12-06 14:12:34 +01:00
b1bb8b919f changed MaterialPageRoute to CupertinoPageRoute for ios animation
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Successful in 2m21s
2025-12-06 13:34:11 +01:00
697767f0de made winner deselectable and added auto save on select
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m8s
Pull Request Pipeline / lint (pull_request) Successful in 2m11s
2025-12-06 13:31:08 +01:00
306a783d67 removed dots after TopCenteredMessage text
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m17s
Pull Request Pipeline / lint (pull_request) Successful in 2m20s
2025-12-06 11:22:34 +01:00
03035138ac refactor game result view variable naming and layout
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m12s
Pull Request Pipeline / lint (pull_request) Successful in 2m12s
2025-12-06 10:00:59 +01:00
7323f52153 add delay and change empty games message
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m11s
Pull Request Pipeline / lint (pull_request) Successful in 2m11s
2025-12-05 20:33:27 +01:00
f5842f9c4a remove print
All checks were successful
Pull Request Pipeline / lint (pull_request) Successful in 2m12s
Pull Request Pipeline / test (pull_request) Successful in 2m14s
2025-12-05 19:44:36 +01:00
e3ac91bf48 remove todo
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m9s
Pull Request Pipeline / lint (pull_request) Successful in 2m11s
2025-12-05 19:41:01 +01:00
dba448b9c1 added const 2025-12-05 19:39:35 +01:00
d8551b3a27 add db functionality 2025-12-05 19:35:14 +01:00
8f2c7493d0 re-set gameListFuture to reload the games after changing the winner 2025-12-05 19:35:04 +01:00
f7f97fcdcb made tapping on game tile redirect to GameResultView 2025-12-05 19:26:47 +01:00
9ac6b6e04c added ontap feature & argument 2025-12-05 19:25:52 +01:00
e77896c1d4 removed settings icon leading to game result view 2025-12-05 19:25:31 +01:00
dd2024e96e Merge branch 'development' into feature/48-game-result-view-erstellen
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Successful in 2m7s
2025-12-05 17:55:01 +00:00
cd9780871f Merge pull request 'Fehlende Methoden für Games Datenbank inplementieren' (#76) from feature/74-fehlende-methoden-für-games-datenbank-inplementieren into development
Reviewed-on: #76
Reviewed-by: mathiskir <mathis.kirchner.mk@gmail.com>
2025-12-05 17:54:13 +00:00
3169eebd14 Import formatting
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m16s
Pull Request Pipeline / lint (pull_request) Successful in 2m18s
2025-12-05 18:24:06 +01:00
ec902c6196 Removed print 2025-12-05 18:23:58 +01:00
b719a6662b Merge branch 'development' into feature/74-fehlende-methoden-für-games-datenbank-inplementieren
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m19s
Pull Request Pipeline / lint (pull_request) Failing after 2m22s
# Conflicts:
#	lib/presentation/views/main_menu/game_history_view.dart
2025-12-05 18:22:25 +01:00
09b407eba8 Merge branch 'development' into feature/48-game-result-view-erstellen
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
2025-12-02 19:48:36 +00:00
877c2921d9 Merge pull request 'GameHistoryView anpassen' (#20) from feature/2-gamehistoryview-anpassen into development
Reviewed-on: #20
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2025-11-30 15:59:25 +00:00
gelbeinhalb
5ce4964c32 deleted double_row_info_tile
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m2s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2025-11-29 20:04:49 +01:00
b4ccb567b5 Added conditional description
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Successful in 2m4s
2025-11-28 23:15:08 +01:00
bcd7bf751b Added todo & example data 2025-11-28 23:14:29 +01:00
4dbc106e38 Added searchbar 2025-11-28 23:14:13 +01:00
gelbeinhalb
fb28de5772 add create game button
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Successful in 2m8s
2025-11-28 14:44:24 +01:00
236a737fd1 Implemented choose game view
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m3s
Pull Request Pipeline / lint (pull_request) Successful in 2m7s
2025-11-28 14:41:50 +01:00
gelbeinhalb
f713bd6fb7 use custom app skeleton 2025-11-28 14:35:20 +01:00
94b113eb95 Renamed widget
All checks were successful
Pull Request Pipeline / lint (pull_request) Successful in 2m8s
Pull Request Pipeline / test (pull_request) Successful in 2m8s
2025-11-28 14:07:42 +01:00
71b2f30d29 removed comment
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m23s
Pull Request Pipeline / lint (pull_request) Successful in 2m31s
2025-11-28 14:00:36 +01:00
d2d6852f31 removed comment
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m29s
Pull Request Pipeline / lint (pull_request) Successful in 2m51s
2025-11-28 14:00:26 +01:00
126dc7ed97 Added exception 2025-11-28 14:00:04 +01:00
40a3c1b82e Removed comment 2025-11-28 13:56:24 +01:00
gelbeinhalb
da722c5277 Merge remote-tracking branch 'origin/development' into feature/2-gamehistoryview-anpassen
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m14s
Pull Request Pipeline / lint (pull_request) Successful in 2m17s
2025-11-28 12:15:14 +01:00
gelbeinhalb
516c2afd1e remove colon behind players
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m16s
Pull Request Pipeline / lint (pull_request) Successful in 2m22s
2025-11-28 12:14:22 +01:00
gelbeinhalb
9ee9da2ac8 Made space at the bottom of the list smaller
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m2s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2025-11-27 22:59:09 +01:00
gelbeinhalb
aa208bb2ef use standardized TopCenteredMessage 2025-11-27 22:56:22 +01:00
gelbeinhalb
a29123c964 fix error messages
All checks were successful
Pull Request Pipeline / lint (pull_request) Successful in 2m15s
Pull Request Pipeline / test (pull_request) Successful in 2m14s
2025-11-27 17:25:58 +01:00
gelbeinhalb
8c005d6e5e fix possible render overflow
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m9s
Pull Request Pipeline / lint (pull_request) Successful in 2m10s
2025-11-27 17:06:32 +01:00
gelbeinhalb
cc50e497c9 merge duplicate if statements for group and winner sections 2025-11-27 17:04:08 +01:00
gelbeinhalb
ae348499d4 moved functionality methods to the bottom of the file 2025-11-27 17:00:13 +01:00
gelbeinhalb
b443230285 fixed loading too fast
Some checks failed
Pull Request Pipeline / lint (pull_request) Failing after 2m10s
Pull Request Pipeline / test (pull_request) Successful in 5m6s
2025-11-27 16:58:02 +01:00
gelbeinhalb
099e587d45 remove useless skeleton data
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Failing after 2m17s
2025-11-27 16:45:47 +01:00
dc0e536221 Implemented updateGameName() and tests for it
All checks were successful
Pull Request Pipeline / lint (pull_request) Successful in 2m11s
Pull Request Pipeline / test (pull_request) Successful in 3m30s
2025-11-26 14:44:41 +01:00
2a34243e69 Renamed methods for better distinction 2025-11-26 14:42:17 +01:00
499415e0c5 Added updatePlayersFromGame(), added docs & tests 2025-11-26 14:39:38 +01:00
397c5c1550 Added updateGroupOfGame(), added docc & tests 2025-11-26 14:17:11 +01:00
738f242eee Implemented methods and test for winner 2025-11-26 13:48:53 +01:00
745aaef978 Implemented ChooseTile
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m2s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2025-11-26 13:12:15 +01:00
b5234c765c Changed create game button size
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Successful in 2m8s
2025-11-26 12:40:06 +01:00
919c9f57ac Fixed button state 2025-11-26 12:35:34 +01:00
27424694ce Removed unnecessary prints 2025-11-26 12:31:33 +01:00
84338f8f66 Changed title 2025-11-26 12:28:11 +01:00
733df2dcb5 Changed highlight color 2025-11-26 12:27:07 +01:00
9ba3dd7909 added missing consts
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m7s
Pull Request Pipeline / lint (pull_request) Successful in 2m7s
2025-11-25 23:22:02 +01:00
2838376434 Implemented player selection
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m5s
Pull Request Pipeline / lint (pull_request) Successful in 2m12s
2025-11-25 22:38:54 +01:00
86ec4de5c0 add textoverflow behaviour
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m5s
Pull Request Pipeline / lint (pull_request) Failing after 2m8s
2025-11-25 22:03:38 +01:00
479e9a2575 add spacing between title and list and rename appbar title to game name 2025-11-25 22:01:49 +01:00
d97871d15b fix lint
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m0s
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
2025-11-25 17:29:21 +01:00
00fd6880e9 add todo comment
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m14s
Pull Request Pipeline / lint (pull_request) Failing after 2m17s
2025-11-25 17:24:35 +01:00
649330f358 Merge remote-tracking branch 'origin/feature/48-game-result-view-erstellen' into feature/48-game-result-view-erstellen
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m18s
Pull Request Pipeline / lint (pull_request) Failing after 2m23s
2025-11-25 17:23:19 +01:00
07d81d687b Implement CustomRadioListTile and update GameResultView to select a winner currently without saving to the db 2025-11-25 17:23:03 +01:00
b291673899 Merge branch 'development' into feature/48-game-result-view-erstellen
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Failing after 2m9s
2025-11-25 10:28:28 +00:00
5fbf2ccb45 Implemented app skeleton
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m3s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2025-11-24 22:21:27 +01:00
e489d16c51 Removed imports 2025-11-24 22:20:53 +01:00
7cfffadb86 Corrected import 2025-11-24 22:20:44 +01:00
ae529effd2 Merge branch 'development' into feature/3-creategameview-erstellen
# Conflicts:
#	lib/presentation/views/main_menu/create_group_view.dart
2025-11-24 22:19:32 +01:00
4c3b2152eb Merge pull request 'PlayerSelection Widget implementiert' (#72) from feature/65-spieler-suche-in-eigenes-widget-umwandeln into development
All checks were successful
Pull Request Pipeline / lint (pull_request) Successful in 2m27s
Pull Request Pipeline / test (pull_request) Successful in 2m38s
Reviewed-on: #72
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2025-11-24 21:10:54 +00:00
51e3c04e72 Refactor PlayerSelection to use AppSkeleton widget
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m2s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2025-11-24 22:08:42 +01:00
2b9f038b0d Merge remote-tracking branch 'origin/development' into feature/65-spieler-suche-in-eigenes-widget-umwandeln
# Conflicts:
#	lib/presentation/views/main_menu/create_group_view.dart
2025-11-24 22:01:26 +01:00
0653700f9c Added comments to explain player filtering and selection logic in PlayerSelection widget
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m1s
Pull Request Pipeline / lint (pull_request) Successful in 2m4s
2025-11-24 21:56:57 +01:00
7be80e6f91 Translate player selection UI text to English
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m1s
Pull Request Pipeline / lint (pull_request) Successful in 2m2s
2025-11-24 21:44:41 +01:00
a4b934388d Merge pull request 'Skeletonizer auslagern' (#71) from enhancement/69-skeletonizer-auslagern into development
Reviewed-on: #71
Reviewed-by: mathiskir <mathis.kirchner.mk@gmail.com>
2025-11-24 20:35:54 +00:00
f8c0dbba5a Remove unused TextEditingController from PlayerSelection widget
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m13s
Pull Request Pipeline / lint (pull_request) Successful in 2m18s
2025-11-24 21:33:53 +01:00
ebb531d825 initialize _searchBarController internally instead of using widget controller
Some checks failed
Pull Request Pipeline / lint (pull_request) Failing after 2m24s
Pull Request Pipeline / test (pull_request) Successful in 2m24s
2025-11-24 21:33:28 +01:00
fc9779153d Remove unused _searchBarController from CreateGroupView 2025-11-24 21:33:19 +01:00
a2522cef13 rename searchBarController to controller in PlayerSelection widget
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m2s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2025-11-24 21:26:55 +01:00
442e1d64a3 remove uneccessary groupNameController
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m0s
Pull Request Pipeline / lint (pull_request) Successful in 2m17s
2025-11-24 21:24:51 +01:00
54b54796e8 remove print
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m0s
Pull Request Pipeline / lint (pull_request) Successful in 2m4s
2025-11-24 21:19:05 +01:00
686463720a refactor for new name and remove hide in material import 2025-11-24 21:17:27 +01:00
6a77028171 rename to PlayerSelection 2025-11-24 21:17:01 +01:00
f1bd9c18e0 Made selectedPlayers local to SelectPlayerWidget because its not needed in CreateGroupView 2025-11-24 21:15:18 +01:00
6c9b742bdf Refactor CreateGroupView to use SelectPlayerWidget 2025-11-24 20:59:23 +01:00
744a402602 put player selection from creategroupview into own widget 2025-11-24 20:58:56 +01:00
2d9148788e Refactored skeleton widgets to own
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Successful in 2m19s
2025-11-24 20:05:18 +01:00
18f635e6ef Implemented custom skeleton widget 2025-11-24 20:05:07 +01:00
9efbc12909 moved input widgets to new folder
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m1s
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
2025-11-24 16:23:29 +01:00
7c7676abee Implemented CustomTextInputField 2025-11-24 16:17:15 +01:00
1faa74f026 Removed comment 2025-11-24 15:17:55 +01:00
3afae89234 Added Skeleton Loading 2025-11-24 15:17:46 +01:00
093c527591 Implemented TabView 2025-11-24 15:17:29 +01:00
2ba710ca2d Replaced unique box decorations with standardBoxDecoration
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m2s
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
2025-11-24 13:53:28 +01:00
9054b163ce Added BoxDecorations to Custom Theme 2025-11-24 13:50:23 +01:00
e182c815a1 Implemented ruleset list tile with highlighting 2025-11-24 13:50:02 +01:00
c284d10943 Refactoring 2025-11-24 13:49:25 +01:00
72e48ada94 Added seletion highlighting for selected group 2025-11-24 13:31:42 +01:00
Yannick
4591a6857d change skeleton names
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m0s
Pull Request Pipeline / lint (pull_request) Failing after 2m6s
2025-11-24 11:39:56 +01:00
Yannick
44279bc148 Merge remote-tracking branch 'origin/development' into feature/2-gamehistoryview-anpassen
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m15s
Pull Request Pipeline / lint (pull_request) Failing after 2m15s
2025-11-24 11:34:59 +01:00
Yannick
32c7d45809 made game_history_tile prettier :)
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m13s
Pull Request Pipeline / lint (pull_request) Failing after 2m17s
2025-11-24 11:34:22 +01:00
Yannick
4341c2509e fix bug where only last 2 games were shown 2025-11-24 11:07:40 +01:00
a3fa499662 Merge pull request 'Gelbes Aufblinken der Recent Games auf der Homepage behoben & Anpassung des Recent-Games-Containers vorgenommen.' (#64) from bug/63-übergang-auf-home-seite-blitz-kurz-gelb-auf into development
Reviewed-on: #64
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2025-11-23 21:51:04 +00:00
f25737cdc5 Merge branch 'development' into bug/63-übergang-auf-home-seite-blitz-kurz-gelb-auf
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m9s
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
2025-11-23 21:48:48 +00:00
0b500b5248 Merge pull request 'Bugfix bei Spieleranzeige und Vereinfachung der Keine-Player-Logik' (#66) from bug/60-CreateGroupView-erstellter-Spieler-erscheint-nicht-in-alle-Spieler into development
Reviewed-on: #66
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2025-11-23 21:41:08 +00:00
e71cb11295 Implemented View for choosing group and ruleset
All checks were successful
Pull Request Pipeline / lint (pull_request) Successful in 2m13s
Pull Request Pipeline / test (pull_request) Successful in 2m15s
2025-11-23 22:36:51 +01:00
b102ec4c1c Implemented first structure of CreateGameView 2025-11-23 22:36:35 +01:00
974d6e9b56 refactor empty state logic in CreateGroupView
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m22s
Pull Request Pipeline / lint (pull_request) Successful in 2m24s
The diff introduces boolean variables `doneLoading` and `snapshotDataEmpty` to simplify the conditional check for displaying the empty state message. It specifically fixes the logic to correctly show the "No players found" message when both the snapshot and the local `allPlayers` list are empty, removing the dependency on `selectedPlayers.isEmpty`.
2025-11-23 22:14:13 +01:00
Yannick
290948e50d add intl for date formatting
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m21s
Pull Request Pipeline / lint (pull_request) Failing after 2m28s
2025-11-23 22:05:25 +01:00
Yannick
bbd200e245 use Skeletonizer for Layout 2025-11-23 22:02:16 +01:00
694cac7f26 Fix bug where the skeleton was edited while it was visible and
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
match the “no games available” container size to the size used when games are available.
2025-11-23 21:16:13 +01:00
bd616c510a update GameResultView to accept and use a given Game instance 2025-11-23 20:22:26 +01:00
424a258df1 Update GameResultView with dummy Game data in CustomNavigationBar 2025-11-23 20:22:03 +01:00
6dc74ca82e Implement basic logic and UI for selecting game winners in GameResultView 2025-11-23 20:18:26 +01:00
Yannick
ac6af803fd Merge remote-tracking branch 'origin/development' into feature/2-gamehistoryview-anpassen 2025-11-23 20:07:10 +01:00
Yannick
f21d0ba4e8 move game_history_tile.dart 2025-11-23 20:04:56 +01:00
8307488f28 Merge pull request 'Provisorisches App Icon implementieren' (#59) from setup/57-provisorisches-app-icon-implementiere into development
Reviewed-on: #59
2025-11-23 18:45:44 +00:00
937f1e3ac8 made settingsbutton redirect to game result view
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m5s
Pull Request Pipeline / lint (pull_request) Failing after 2m14s
2025-11-23 19:42:31 +01:00
46d1c25bb5 create GameResultView with basic structure and styling 2025-11-23 19:41:57 +01:00
cdba6e264a Merge branch 'development' into setup/57-provisorisches-app-icon-implementiere
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m31s
Pull Request Pipeline / lint (pull_request) Successful in 2m33s
2025-11-23 19:26:05 +01:00
88fa886ea2 Changed launching background on ios
All checks were successful
Pull Request Pipeline / lint (pull_request) Successful in 2m39s
Pull Request Pipeline / test (pull_request) Successful in 2m38s
2025-11-23 19:25:08 +01:00
cc2f87396f Changed Launcher Background to app bg
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m14s
Pull Request Pipeline / lint (pull_request) Successful in 2m15s
2025-11-23 19:21:19 +01:00
692a3ef3a4 Merge pull request 'HomeView Mock-Daten entfernen' (#51) from enhancement/46-homeview-mockdaten-entfernen into development
Reviewed-on: #51
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2025-11-23 18:19:54 +00:00
22d95b0015 Merge remote-tracking branch 'origin/development' into enhancement/46-homeview-mockdaten-entfernen
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m9s
Pull Request Pipeline / lint (pull_request) Successful in 2m11s
# Conflicts:
#	lib/presentation/views/main_menu/home_view.dart
2025-11-23 19:04:02 +01:00
1a84d2572a Merge branch 'development' into setup/57-provisorisches-app-icon-implementiere
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m30s
Pull Request Pipeline / lint (pull_request) Successful in 2m38s
2025-11-23 18:57:26 +01:00
ca55b99d03 Changed launcher background color
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m45s
Pull Request Pipeline / lint (pull_request) Successful in 2m45s
2025-11-23 18:42:59 +01:00
651f210ea8 Added ios icon 2025-11-23 18:28:10 +01:00
0153df6195 Merge pull request 'Skeleton Delay für group- und group create view' (#58) from enhancement/54-delay-für-groups-view-skeleton into development
Reviewed-on: #58
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2025-11-23 17:10:37 +00:00
e4abf53f66 fix linter errors
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m27s
Pull Request Pipeline / lint (pull_request) Successful in 2m31s
2025-11-23 18:09:45 +01:00
2616f7c113 Refactor FutureBuilder logic in HomeView to handle empty game lists and improve code formatting
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m11s
Pull Request Pipeline / lint (pull_request) Failing after 2m12s
2025-11-23 18:08:03 +01:00
7881e61a2e Updated android icon 2025-11-23 17:57:20 +01:00
73c5586874 Added icons for android 2025-11-23 17:54:33 +01:00
963edaf1d1 Update game status text and player count label in HomeView 2025-11-23 17:51:55 +01:00
604a541392 set delay in all future builders to 250ms
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m5s
Pull Request Pipeline / lint (pull_request) Successful in 2m7s
2025-11-23 17:09:52 +01:00
26fadf5093 add artificial delay to loadPlayerList for skeleton loading
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m8s
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
2025-11-23 15:22:59 +01:00
9e8bab1a60 add artificial delay to group list loading 2025-11-23 15:21:40 +01:00
fc51b30491 Merge pull request '1 wird immer als 1.00 angezeigt #55' (#56) from bug/55-1-wird-falsch-angezeigt into development
Reviewed-on: #56
Reviewed-by: mathiskir <mathis.kirchner.mk@gmail.com>
2025-11-23 13:58:26 +00:00
def37aa640 Refactor Recent Games tile in HomeView
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m7s
Pull Request Pipeline / lint (pull_request) Successful in 2m7s
- Move FutureBuilder inside InfoTile content
- Replace hardcoded winner and game type strings with actual game data
- Limit displayed recent games to 2 items and handle cases with fewer games
- Update player text generation to show player count instead of names
- Remove TopCenteredMessage usage and replace with simple text for empty/error states
- Update skeleton data to use Player object for winner
2025-11-23 14:56:53 +01:00
8ae85c925d Fixed double
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
2025-11-23 14:29:23 +01:00
b744b04648 Merge remote-tracking branch 'origin/development' into enhancement/46-homeview-mockdaten-entfernen 2025-11-23 14:02:55 +01:00
17e882986d Merge pull request 'StatisticsView erstellen' (#30) from feature/6-statisticsview-erstellen into development
Reviewed-on: #30
Reviewed-by: mathiskir <mathis.kirchner.mk@gmail.com>
2025-11-23 12:59:40 +00:00
7cda25a380 Changed item count back to normal
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m19s
Pull Request Pipeline / lint (pull_request) Successful in 2m23s
2025-11-23 12:34:42 +01:00
e9b041e43a Changed double depiction
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m20s
Pull Request Pipeline / lint (pull_request) Successful in 2m23s
2025-11-23 12:33:13 +01:00
c38c731b41 Merge branch 'development' into feature/6-statisticsview-erstellen
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m25s
Pull Request Pipeline / lint (pull_request) Successful in 2m25s
# Conflicts:
#	lib/presentation/views/main_menu/statistics_view.dart
2025-11-23 12:19:03 +01:00
d411f58134 Changed icon for second statistics tile
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m21s
Pull Request Pipeline / lint (pull_request) Successful in 2m22s
2025-11-23 12:18:05 +01:00
fee5c57207 Added comments for return value -1 2025-11-23 12:13:30 +01:00
de60c942ea Merge pull request 'Winner als Player-Objekte' (#52) from feature/50-winner-soll-player-objekt-sein into development
Reviewed-on: #52
Reviewed-by: mathiskir <mathis.kirchner.mk@gmail.com>
2025-11-23 10:48:45 +00:00
acc5b0a3e9 Merge branch 'development' into feature/6-statisticsview-erstellen
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m33s
Pull Request Pipeline / lint (pull_request) Successful in 2m33s
2025-11-23 00:36:33 +01:00
24babe06d2 Merge branch 'development' into feature/50-winner-soll-player-objekt-sein
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m33s
Pull Request Pipeline / lint (pull_request) Successful in 2m34s
2025-11-23 00:36:08 +01:00
50dd05ecc5 Merge pull request 'Erstelle Spieler direkt zu ausgewählten Spielern, Gruppen Sortierung nach Timestamp + Bugfixes' (#49) from feature/47-spieler-zur-gruppe-und-gruppen-sortierung into development
Reviewed-on: #49
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2025-11-22 23:34:47 +00:00
4ff131770e Adjust tests
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2025-11-23 00:22:53 +01:00
82b344a145 Changed winner access in statistics view
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m9s
Pull Request Pipeline / lint (pull_request) Successful in 2m10s
2025-11-23 00:17:48 +01:00
338f4294dc Updated json schema 2025-11-23 00:17:31 +01:00
cfed05595c Updated methods in gameDao 2025-11-23 00:17:27 +01:00
fa841e328e Altered game class 2025-11-23 00:17:11 +01:00
f658a88849 Implemented displaying real recent games in home view
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m13s
Pull Request Pipeline / lint (pull_request) Failing after 2m13s
2025-11-22 23:52:00 +01:00
feb5fa0615 Docs, small changes
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m13s
Pull Request Pipeline / lint (pull_request) Successful in 2m15s
2025-11-22 23:30:24 +01:00
fba35521cb changed skeletonizer transition duration back to normal 2025-11-22 23:23:02 +01:00
e60961730f Added new metric & changed layout builder of Skeletonizer 2025-11-22 23:20:58 +01:00
59c041699d Changed values attribute & maxBarWidth 2025-11-22 23:20:31 +01:00
c170aa1775 sort groups by creation date in GroupsView
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m12s
Pull Request Pipeline / lint (pull_request) Successful in 2m12s
2025-11-22 22:55:19 +01:00
692b412fe2 Fix black bars on the screens bottom and top by not wrapping scaffold in safearea, but scaffolds body children 2025-11-22 22:52:09 +01:00
cc04e05557 Adjust bottom padding in GroupsView list based on media query padding 2025-11-22 22:49:28 +01:00
546a3e3717 implemented feature to automatically add newly created player to selected players 2025-11-22 22:49:17 +01:00
b2036e4e68 Implemented first version of statistics view
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Successful in 2m5s
2025-11-22 22:10:16 +01:00
310b9aa43b Implemented StatisticsWidget tile 2025-11-22 22:10:02 +01:00
e464ddb466 Merge pull request 'Navbar Position fix' (#21) from enhancement/18-navbar-alignment into development
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m8s
Pull Request Pipeline / lint (pull_request) Successful in 2m8s
Reviewed-on: #21
Reviewed-by: mathiskir <mathis.kirchner.mk@gmail.com>
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2025-11-22 17:06:04 +00:00
c3deaa3974 Merge branch 'development' into enhancement/18-navbar-alignment
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m9s
Pull Request Pipeline / lint (pull_request) Successful in 2m12s
2025-11-22 17:03:48 +00:00
fd13fe6e90 made CustomWidthButton's position adaptive to bottom padding of safearea
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2025-11-22 17:58:33 +01:00
5062196463 Adjust safeareas minimum padding for custom navigation bar 2025-11-22 17:57:58 +01:00
6af1df5fbc Merge pull request 'JSON Import für Testdaten & Funktion zum Löschen aller Daten' (#33) from feature/31-json-import-fuer-testdaten into development
Reviewed-on: #33
Reviewed-by: gelbeinhalb <spam@yannick-weigert.de>
2025-11-22 16:47:15 +00:00
df3215ef76 Made bottom padding adaptive to screen
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m8s
Pull Request Pipeline / lint (pull_request) Successful in 2m8s
2025-11-22 17:40:24 +01:00
28ed22ce73 wrap navbar in SafeArea and replaced Material with Container 2025-11-22 17:40:00 +01:00
0593297fc3 Merge branch 'development' into feature/31-json-import-fuer-testdaten
All checks were successful
Pull Request Pipeline / lint (pull_request) Successful in 2m16s
Pull Request Pipeline / test (pull_request) Successful in 2m16s
2025-11-22 16:44:09 +01:00
b668f6b9ae fix black top/bottom bar when wrapping scaffold in safearea
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m10s
Pull Request Pipeline / lint (pull_request) Failing after 2m19s
2025-11-22 16:31:15 +01:00
78b511b207 Merge pull request 'getAllGames returnt nicht alle Attribute von der game Klasse' (#45) from bug/37-getallgames-returnt-nicht-alle-attribute-von-der-game-klasse into development
Reviewed-on: #45
Reviewed-by: mathiskir <mathis.kirchner.mk@gmail.com>
2025-11-22 15:22:11 +00:00
63d9ed400d Adjust padding in CustomNavigationBar
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Failing after 2m10s
- Add vertical minimum padding to SafeArea
- Remove bottom padding in bottomNavigationBar
- replaced left/right padding in bottomNavigationBar with EdgeInsets.symmetric
- removed bottom padding from bottomNavigationBar
2025-11-22 16:18:37 +01:00
d809d80506 Merge remote-tracking branch 'origin/development' into enhancement/18-navbar-alignment 2025-11-22 15:41:33 +01:00
30645f06f8 Renamed variable
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m3s
Pull Request Pipeline / lint (pull_request) Successful in 2m5s
2025-11-22 14:21:55 +01:00
9346f61d14 Renamed variable 2025-11-22 14:21:28 +01:00
bef812502c Renamed variable and added null checks 2025-11-22 14:20:51 +01:00
24f18f5c65 Removed false comparison 2025-11-22 14:13:15 +01:00
62eea08614 Renamed variable 2025-11-22 14:12:41 +01:00
893eb91143 Schema corrected
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m10s
Pull Request Pipeline / lint (pull_request) Successful in 2m11s
2025-11-22 01:12:39 +01:00
2ebd4274f0 Moved method validateJsonSchema()
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m5s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2025-11-22 00:47:44 +01:00
70307016b3 Fixed addGames method 2025-11-22 00:47:32 +01:00
1b3334f3e0 Fixed addGroups method 2025-11-22 00:47:24 +01:00
Yannick
6a985b0b1e Merge branch 'development' into feature/2-gamehistoryview-anpassen
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m7s
Pull Request Pipeline / lint (pull_request) Failing after 2m8s
# Conflicts:
#	lib/presentation/views/main_menu/game_history_view.dart
2025-11-21 15:45:51 +01:00
Yannick
95f0861a79 add basic came history tile 2025-11-21 15:44:27 +01:00
7cd53aa695 Merge branch 'bug/37-getallgames-returnt-nicht-alle-attribute-von-der-game-klasse' into feature/31-json-import-fuer-testdaten
Some checks failed
Pull Request Pipeline / test (pull_request) Failing after 2m21s
Pull Request Pipeline / lint (pull_request) Successful in 2m21s
# Conflicts:
#	test/db_tests/player_test.dart
2025-11-21 14:26:18 +01:00
ab250e2df4 Typo
All checks were successful
Pull Request Pipeline / lint (pull_request) Successful in 2m25s
Pull Request Pipeline / test (pull_request) Successful in 2m25s
2025-11-21 14:24:57 +01:00
dbb52cfc48 Added missing awaits
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Successful in 2m7s
2025-11-21 14:20:42 +01:00
c56663d15e Added missing await
Some checks failed
Pull Request Pipeline / test (pull_request) Failing after 2m4s
Pull Request Pipeline / lint (pull_request) Successful in 2m5s
2025-11-21 14:17:38 +01:00
51722eb7fd Added batch insert methods to tests
Some checks failed
Pull Request Pipeline / test (pull_request) Failing after 2m9s
Pull Request Pipeline / lint (pull_request) Successful in 2m9s
2025-11-21 14:01:45 +01:00
78d530ddd5 Merge branch 'bug/37-getallgames-returnt-nicht-alle-attribute-von-der-game-klasse' into feature/31-json-import-fuer-testdaten
# Conflicts:
#	lib/data/dao/player_group_dao.dart
#	test/db_tests/game_test.dart
#	test/db_tests/group_test.dart
#	test/db_tests/player_test.dart
2025-11-21 14:00:10 +01:00
8c05385203 Renamed variables to be consistent
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m5s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2025-11-21 13:47:27 +01:00
d948f2f13d Added iteration for multiple items test
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m5s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2025-11-21 13:42:27 +01:00
e15f5d163d Added missing methods
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Successful in 2m7s
2025-11-21 13:12:36 +01:00
32f3f68da9 Annotation for missing test & method
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m1s
Pull Request Pipeline / lint (pull_request) Successful in 2m4s
2025-11-21 12:46:18 +01:00
229750ffcf Fixed test 2025-11-21 12:46:04 +01:00
fe9239ee02 Added missing test 2025-11-21 12:45:48 +01:00
961c6bb679 Refactored tests in own files
Some checks failed
Pull Request Pipeline / test (pull_request) Failing after 2m5s
Pull Request Pipeline / lint (pull_request) Successful in 2m5s
2025-11-21 01:05:35 +01:00
b21ca54672 Refactoring 2025-11-21 00:10:29 +01:00
6055eb63a8 Refactoring 2025-11-21 00:07:34 +01:00
31589855f2 Added methods of todos 2025-11-21 00:07:29 +01:00
8e63a01705 Added methods for multiple inserts to tests
Some checks failed
Pull Request Pipeline / test (pull_request) Failing after 2m6s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2025-11-20 23:49:57 +01:00
e512cbbf95 Merge branch 'bug/37-getallgames-returnt-nicht-alle-attribute-von-der-game-klasse' into feature/31-json-import-fuer-testdaten 2025-11-20 23:45:18 +01:00
89b3f1ff69 Overhauled tests
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m8s
Pull Request Pipeline / lint (pull_request) Successful in 2m8s
2025-11-20 23:40:46 +01:00
72067863c2 Updated insert modes 2025-11-20 23:14:44 +01:00
29a3e77fc4 Merge branch 'bug/37-getallgames-returnt-nicht-alle-attribute-von-der-game-klasse' into feature/31-json-import-fuer-testdaten
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2025-11-20 22:41:14 +01:00
a61818dd77 Fixed error in getAllGames method 2025-11-20 22:40:56 +01:00
e364e15d0a Merge pull request 'Spieler erstellen in CreateGroupView' (#43) from feature/42-spieler-erstellen-in-create-group-view-implementieren into development
Reviewed-on: #43
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2025-11-20 21:18:21 +00:00
195ebf569a Added icon as parameter for custom search bar
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m4s
Pull Request Pipeline / lint (pull_request) Successful in 2m5s
2025-11-20 22:17:20 +01:00
eb7b247cae Fixed error adding player with empty name 2025-11-20 22:11:23 +01:00
01fede2951 Added Visibility Widget 2025-11-20 22:09:08 +01:00
b67f321276 Added name parameters and function doc 2025-11-20 22:05:44 +01:00
d16beed490 felix mach jetzt
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m3s
Pull Request Pipeline / lint (pull_request) Successful in 2m4s
2025-11-20 21:54:43 +01:00
0111774308 Trim whitespace from group and player names in CreateGroupView
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m7s
Pull Request Pipeline / lint (pull_request) Successful in 2m7s
2025-11-20 21:26:59 +01:00
8ff3c01435 added missing consts & mounted check
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m0s
Pull Request Pipeline / lint (pull_request) Successful in 2m4s
2025-11-20 16:59:49 +01:00
bce4cdcb2d Enable player creation via search bar in CreateGroupView
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m0s
Pull Request Pipeline / lint (pull_request) Failing after 2m5s
2025-11-20 16:53:38 +01:00
fa0e9a5dfd add trailing button functionality to CustomSearchBar 2025-11-20 16:53:14 +01:00
ec9e34305a Merge branch 'development' into enhancement/18-navbar-alignment
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m5s
Pull Request Pipeline / lint (pull_request) Successful in 2m7s
2025-11-20 10:50:10 +01:00
45650133a7 Corrected schema again
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m3s
Pull Request Pipeline / lint (pull_request) Successful in 2m14s
2025-11-19 21:51:13 +01:00
f40a9ad09b Updated schema
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m1s
Pull Request Pipeline / lint (pull_request) Successful in 2m5s
2025-11-19 21:42:07 +01:00
822bc03c83 Added dialog 2025-11-19 21:41:30 +01:00
a8d4e640cf Tabs update themselves after settings view 2025-11-19 21:39:01 +01:00
cf71b40718 changed export file name 2025-11-19 21:19:54 +01:00
f7c1d6e975 Added missing await
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m1s
Pull Request Pipeline / lint (pull_request) Successful in 2m6s
2025-11-19 21:13:29 +01:00
17dabb773d Merge branch 'development' into feature/31-json-import-fuer-testdaten
Some checks failed
Pull Request Pipeline / test (pull_request) Failing after 2m4s
Pull Request Pipeline / lint (pull_request) Successful in 2m13s
2025-11-19 20:35:34 +01:00
e14984d4a9 Merge pull request 'Actions aufsetzen' (#38) from setup/17-actions-aufsetzen into development
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 1m59s
Pull Request Pipeline / lint (pull_request) Successful in 2m1s
Reviewed-on: #38
Reviewed-by: mathiskir <mathis.kirchner.mk@gmail.com>
2025-11-19 19:35:07 +00:00
682c1d269d Merge branch 'development' into feature/31-json-import-fuer-testdaten 2025-11-19 20:27:21 +01:00
d264b3fa1b Merge branch 'development' into setup/17-actions-aufsetzen
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 1m59s
Pull Request Pipeline / lint (pull_request) Successful in 2m1s
2025-11-19 20:26:39 +01:00
b684ebd4f6 Renamed workflow according to file name 2025-11-19 20:25:37 +01:00
2cae66a8ae Merge pull request 'Timestamp zu allen Objekten hinzufügen' (#36) from feature/29-timestamp-zu-allen-objekten-hinzufügen into development
Reviewed-on: #36
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2025-11-19 19:23:31 +00:00
0967abe10f Merge branch 'development' into feature/29-timestamp-zu-allen-objekten-hinzufügen 2025-11-19 20:23:04 +01:00
061a927324 Merge branch 'development' into feature/31-json-import-fuer-testdaten 2025-11-19 20:22:19 +01:00
412cfff9f5 Added methods for inserting list of players, groups, games 2025-11-19 20:21:55 +01:00
f7073a83a4 Added insert mode 2025-11-19 20:21:30 +01:00
9434282ed1 Added createdAt attribute in dto classes and json schema 2025-11-19 20:20:21 +01:00
d145b18891 Merge pull request 'Button ist transparent' (#41) from bug/40-button-ist-transparent into development
Reviewed-on: #41
Reviewed-by: mathiskir <mathis.kirchner.mk@gmail.com>
2025-11-19 18:35:41 +00:00
3e3def0bde Merge remote-tracking branch 'origin/feature/29-timestamp-zu-allen-objekten-hinzufügen' into feature/31-json-import-fuer-testdaten
# Conflicts:
#	lib/data/dao/game_dao.dart
#	lib/data/db/database.g.dart
#	lib/data/db/tables/game_table.dart
#	lib/data/dto/game.dart
#	pubspec.yaml
2025-11-19 19:30:56 +01:00
3408930524 Merge remote-tracking branch 'origin/development' into setup/17-actions-aufsetzen
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m3s
Pull Request Pipeline / lint (pull_request) Successful in 2m3s
2025-11-19 19:27:02 +01:00
87b1a7d57f Moved ImportStatus & ExportStatus to enums.dart 2025-11-19 19:26:35 +01:00
cf834e636e Merge remote-tracking branch 'origin/development' into feature/31-json-import-fuer-testdaten
# Conflicts:
#	lib/presentation/views/main_menu/home_view.dart
2025-11-19 19:22:34 +01:00
8e2befaf3d Fixed button color problem 2025-11-19 19:19:04 +01:00
186d8cf5c9 Merge branch 'development' into feature/29-timestamp-zu-allen-objekten-hinzufügen 2025-11-19 17:34:07 +00:00
6f42b36587 Merge pull request 'CreateGroupView erstellt' (#28) from feature/5-creategroupview-erstellen into development
Reviewed-on: #28
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2025-11-19 17:32:44 +00:00
248d652e06 Made onPressed not required 2025-11-19 18:32:25 +01:00
e71e65b197 Corrected button color behaviour and added tertiary button 2025-11-19 18:27:27 +01:00
3f79a7b898 sourcing enums out to enums.dart 2025-11-19 18:26:51 +01:00
1232cb8f0d Fix GestureDetector child ordering in TextIconListTile 2025-11-19 16:50:02 +01:00
018332d8e6 Refactor widget directory structure by organizing tiles and buttons
- Move `GameTile` and `DoubleRowInfoTile` to `presentation/widgets/tiles/`
- Move `CustomWidthButton` and `QuickCreateButton` to `presentation/widgets/buttons/`
- Update import paths in `HomeView`, `GroupsView`, `GameHistoryView`, and `CreateGroupView`
2025-11-19 16:48:43 +01:00
201fd70685 Update TextIconListTile padding and replace IconButton with GestureDetector 2025-11-19 16:44:46 +01:00
9365313c92 button not working 2025-11-19 16:39:32 +01:00
54e1756e79 moved create_group_view from subfolder to root 2025-11-19 16:39:05 +01:00
3b6a914022 removed uneccessary withClock 2025-11-19 15:52:04 +01:00
98b02adc85 Formatted files so that pipeline doesnt fail
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 2m0s
Pull Request Pipeline / lint (pull_request) Successful in 2m3s
2025-11-19 15:43:49 +01:00
b82261317c move CreateGroupView to main_menu directory 2025-11-19 15:09:40 +01:00
c76e193b4d created all objects in setup() funktion to avoid redundant withClock 2025-11-19 15:02:32 +01:00
0ac8c21052 Formatted files so that pipeline doesnt fail
All checks were successful
Pull Request Pipeline / test (pull_request) Successful in 1m58s
Pull Request Pipeline / lint (pull_request) Successful in 2m1s
2025-11-19 11:32:22 +01:00
74fffa95e2 Added push workflow (not active)
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 1m58s
Pull Request Pipeline / lint (pull_request) Failing after 2m1s
2025-11-19 11:28:00 +01:00
ca4bf03bab Finalized pull request workflow 2025-11-19 11:27:48 +01:00
aade42c0a6 Tried sth
Some checks failed
Pull Request Pipeline / lint (pull_request) Has been skipped
Pull Request Pipeline / test (pull_request) Has been skipped
Pull Request Pipeline / format (pull_request) Failing after 1m54s
2025-11-19 11:21:43 +01:00
0659d202b3 Remove if clause
Some checks failed
Pull Request Pipeline / lint (pull_request) Has been skipped
Pull Request Pipeline / test (pull_request) Has been skipped
Pull Request Pipeline / format (pull_request) Failing after 2m42s
2025-11-19 11:18:23 +01:00
81cdeb7ed6 Skipped other runs for testing
All checks were successful
Pull Request Pipeline / lint (pull_request) Has been skipped
Pull Request Pipeline / test (pull_request) Has been skipped
Pull Request Pipeline / format (pull_request) Successful in 2m5s
2025-11-19 11:15:30 +01:00
89d7bb54a1 Removed false
Some checks failed
Pull Request Pipeline / format (pull_request) Failing after 1m59s
Pull Request Pipeline / test (pull_request) Successful in 2m6s
Pull Request Pipeline / lint (pull_request) Failing after 2m12s
2025-11-19 11:12:46 +01:00
5d8047b3ba Updated directorys
Some checks failed
Pull Request Pipeline / format (pull_request) Has been skipped
Pull Request Pipeline / test (pull_request) Has been cancelled
Pull Request Pipeline / lint (pull_request) Has been cancelled
2025-11-19 11:12:02 +01:00
dd8af42a47 corrected workflow
Some checks failed
Pull Request Pipeline / format (pull_request) Failing after 2m9s
Pull Request Pipeline / test (pull_request) Successful in 2m10s
Pull Request Pipeline / lint (pull_request) Failing after 2m12s
2025-11-19 11:08:30 +01:00
346dddcf62 testing formatting 2025-11-19 11:08:01 +01:00
9f4fc3a3b0 Merge remote-tracking branch 'origin/setup/17-actions-aufsetzen' into setup/17-actions-aufsetzen
# Conflicts:
#	.gitea/workflows/pull_request.yaml
2025-11-19 11:07:25 +01:00
594ea947c2 Tested sth 2025-11-19 11:06:40 +01:00
e5268ebc12 Tested sth 2025-11-19 11:06:37 +01:00
1732878c7f Tested sth 2025-11-19 11:03:10 +01:00
f136400c7e Final changes?
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 1m56s
Pull Request Pipeline / lint (pull_request) Failing after 2m1s
2025-11-19 11:01:33 +01:00
c89243f886 Tried sth
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 1m59s
Pull Request Pipeline / lint (pull_request) Failing after 2m2s
2025-11-19 10:57:53 +01:00
a3b45053e7 Finalized workflow
Some checks failed
Pull Request Pipeline / lint (pull_request) Failing after 2m5s
Pull Request Pipeline / test (pull_request) Successful in 2m6s
2025-11-19 10:54:58 +01:00
91b68eac3e Implemented test workflow
Some checks failed
Pull Request Pipeline / test (pull_request) Successful in 2m2s
Pull Request Pipeline / lint (pull_request) Failing after 2m7s
2025-11-19 10:50:56 +01:00
6ae1ce9bc7 Updated analyzing
Some checks failed
Pull Request Pipeline / lint (pull_request) Failing after 2m1s
Pull Request Pipeline / test (pull_request) Has been skipped
2025-11-19 10:47:14 +01:00
7ac5986588 Updated whole workflow
Some checks failed
Pull Request Pipeline / lint (pull_request) Failing after 3m52s
Pull Request Pipeline / test (pull_request) Has been skipped
2025-11-19 10:41:12 +01:00
601b7d0a4f Changed flutter installation
Some checks failed
Pull Request Pipeline / lint (pull_request) Failing after 2m10s
Pull Request Pipeline / test (pull_request) Has been skipped
2025-11-19 10:36:48 +01:00
e852a4d539 Added git safe directory
Some checks failed
Pull Request Pipeline / lint (pull_request) Failing after 3m47s
Pull Request Pipeline / test (pull_request) Has been skipped
2025-11-19 10:26:34 +01:00
e108bb41f6 Corrected installation
Some checks failed
Pull Request Pipeline / lint (pull_request) Failing after 1m33s
Pull Request Pipeline / test (pull_request) Has been skipped
2025-11-19 10:22:55 +01:00
17c14dd230 Added container
Some checks failed
Pull Request Pipeline / lint (pull_request) Failing after 1m32s
Pull Request Pipeline / test (pull_request) Has been skipped
2025-11-19 10:19:45 +01:00
7123d36cd8 Updated flutter installation way
Some checks failed
Pull Request Pipeline / lint (pull_request) Failing after 1m32s
Pull Request Pipeline / test (pull_request) Has been skipped
2025-11-19 10:15:12 +01:00
7cc72015d3 Upgraded to flutter 3.35.6
Some checks failed
Pull Request Pipeline / lint (pull_request) Failing after 10s
Pull Request Pipeline / test (pull_request) Has been skipped
2025-11-19 10:11:22 +01:00
10e56a7241 Downgraded flutter version
Some checks failed
Pull Request Pipeline / lint (pull_request) Failing after 1m17s
Pull Request Pipeline / test (pull_request) Has been skipped
2025-11-19 10:09:15 +01:00
6638c2deee Removed cache clearing
Some checks failed
Pull Request Pipeline / lint (pull_request) Failing after 10s
Pull Request Pipeline / test (pull_request) Has been skipped
2025-11-19 10:08:04 +01:00
974f06b6b8 Back again
Some checks failed
Pull Request Pipeline / test (pull_request) Has been cancelled
Pull Request Pipeline / lint (pull_request) Has been cancelled
2025-11-19 10:06:46 +01:00
63d2117a6a Tried sth
Some checks failed
Pull Request Pipeline / lint (pull_request) Failing after 6s
Pull Request Pipeline / test (pull_request) Has been skipped
2025-11-19 10:05:55 +01:00
6ae39717fd Cleaned flutter cache
Some checks failed
Pull Request Pipeline / test (pull_request) Has been cancelled
Pull Request Pipeline / lint (pull_request) Has been cancelled
2025-11-19 10:02:39 +01:00
003835472d Added flutter version again
Some checks failed
Pull Request Pipeline / lint (pull_request) Failing after 9s
Pull Request Pipeline / test (pull_request) Has been skipped
2025-11-19 10:00:09 +01:00
8d91eb3780 Added update
Some checks failed
Pull Request Pipeline / lint (pull_request) Failing after 50s
Pull Request Pipeline / test (pull_request) Has been skipped
2025-11-19 09:58:03 +01:00
ddc8d93592 Removed sudo
Some checks failed
Pull Request Pipeline / lint (pull_request) Failing after 47s
Pull Request Pipeline / test (pull_request) Has been skipped
2025-11-19 09:56:05 +01:00
eeec92181a Added jq installation
Some checks failed
Pull Request Pipeline / lint (pull_request) Failing after 47s
Pull Request Pipeline / test (pull_request) Has been skipped
2025-11-19 09:53:54 +01:00
a8962e68b6 Added first workflow
Some checks failed
Pull Request Pipeline / lint (pull_request) Failing after 1m9s
Pull Request Pipeline / test (pull_request) Has been skipped
2025-11-19 09:51:37 +01:00
322c51a764 Added documentation and feedback in snackbar 2025-11-19 09:44:48 +01:00
Yannick
69e13e877e add game_history_tile 2025-11-19 08:58:47 +01:00
Yannick
f388c442d2 Merge branch 'development' into feature/2-gamehistoryview-anpassen
# Conflicts:
#	lib/presentation/views/main_menu/game_history_view.dart
2025-11-19 08:48:00 +01:00
82e28b7509 Refactored whole export/import methods in DataTransferService 2025-11-19 00:32:16 +01:00
8150b42dba add clock dependency to pubspec.yaml 2025-11-19 00:27:47 +01:00
75c6f4e01c verify createdAt timestamps in database tests using mocked clock 2025-11-19 00:27:40 +01:00
19c99eef9c use clock.now() instead of DateTime.now() for DTO creation timestamps 2025-11-19 00:27:08 +01:00
f2a749cb0f First version of settings view 2025-11-19 00:24:08 +01:00
5dcd0826bd Adjusted attributes to table definition 2025-11-19 00:23:53 +01:00
f6ebda7984 Changed table column because of importing issues 2025-11-19 00:22:35 +01:00
69c95ca672 Added custom statement for cascade deleting 2025-11-19 00:22:13 +01:00
42ce69f4d3 Added schema.json 2025-11-18 23:59:28 +01:00
08fcaa35ee Added methods for deleting all entities 2025-11-18 23:59:18 +01:00
2ee8edcf9b add createdAt column to game, group and player tables and DAOs 2025-11-18 23:47:45 +01:00
fd86f5193f Fixed toJson methods 2025-11-18 23:46:32 +01:00
8cc898cad6 regenerated database.g.dart 2025-11-18 23:38:43 +01:00
67c8a7e181 added createdAt timestamp to Group, Game, and Player DTOs 2025-11-18 23:21:46 +01:00
2da2e28cb6 Added json schema 2025-11-18 23:20:26 +01:00
d86de09042 Added fromJson, toJson 2025-11-18 23:16:57 +01:00
07d623d963 Merge remote-tracking branch 'refs/remotes/origin/development' into feature/31-json-import-fuer-testdaten 2025-11-18 22:47:52 +01:00
a8a81c2151 Fixed gesture detector area 2025-11-18 22:33:46 +01:00
d341634885 Disable icon for members in group tile 2025-11-18 21:56:31 +01:00
d3a63bd299 renamed IconListTile to TextIconListTile and replaced the icon parameter with iconEnabled in both TextIconListTile and TextIconTile 2025-11-18 21:56:20 +01:00
e0c8398873 remove custom colors from Create Group button in GroupsView 2025-11-18 21:43:38 +01:00
d65dd3d983 Refactor CustomWidthButton to use ButtonStyle enum and CustomTheme
- Replaced `borderColor` and `infillColor` parameters with a `buttonStyle` parameter.
- Introduced `ButtonStyle` enum (primary/secondary) to control styling.
- Updated `CustomWidthButton` to derive colors from `CustomTheme` based on the selected `ButtonStyle`.
2025-11-18 21:42:40 +01:00
51a8c4ea58 Replace MaterialStateProperty with WidgetStateProperty in CustomSearchBar 2025-11-18 21:42:17 +01:00
c67f688a77 Refactor CreateGroupView: remove UUID generation, update tiles & fix async gaps 2025-11-18 21:42:03 +01:00
1d9945c525 Merge branch 'refs/heads/development' into feature/5-creategroupview-erstellen 2025-11-18 21:25:58 +01:00
0202d09812 Merge pull request 'UUID-Generierung für Objekte' (#35) from feature/34-uuid-generierung-fuer-objekte into development
Reviewed-on: #35
2025-11-18 19:45:49 +00:00
73d8e7522c Added fifth player 2025-11-18 20:44:55 +01:00
80290efa0b rename FullWidthButton to CustomWidthButton 2025-11-18 20:37:41 +01:00
f4ed122220 Removed print 2025-11-18 20:15:10 +01:00
2f260d7cbc Add uuid dependency 2025-11-18 20:14:18 +01:00
7781284289 changed to use standardized tiles and fixed search bug 2025-11-18 20:10:48 +01:00
c0ff2bf677 Removed unnecessary id declarations in tests 2025-11-18 20:10:29 +01:00
8f9289617f changed group tile to use standardized text icon tile 2025-11-18 20:10:26 +01:00
1882d0007b created widgets for search bar list tile, selected tile and text input field in create groups view 2025-11-18 20:09:57 +01:00
282841ecf1 Implemented uuid for all dtos 2025-11-18 20:07:53 +01:00
05c41707ca Refactor: Remove sample player generation code 2025-11-18 17:34:09 +01:00
a5e508dbda Refresh group list after adding a new group 2025-11-18 17:29:24 +01:00
412d1fd334 fixed search bugs where duplicates where created or search results were wrong 2025-11-18 17:08:07 +01:00
c31d757615 fixed renderoverflow for long player & group names in create group view and group view 2025-11-18 17:00:09 +01:00
178aaa9643 Added function headers 2025-11-17 23:25:12 +01:00
2076e45fd5 Created new layout for settings view 2025-11-17 23:23:52 +01:00
62acc87e0e Moved game tile in tiles folder 2025-11-17 23:23:41 +01:00
3ca081419b Implemented new SettingsListTile 2025-11-17 23:23:04 +01:00
3e89bfd641 added info message for when all players are selected 2025-11-17 21:34:51 +01:00
c3a2ac77b0 fixed color change in appbar when scrolling 2025-11-17 21:19:17 +01:00
6b2fb18ec0 fixed groups not getting added & added feature to remove player from all players when selected 2025-11-17 20:20:56 +01:00
7a85b5c1ac Merge remote-tracking branch 'origin/feature/5-creategroupview-erstellen' into feature/5-creategroupview-erstellen 2025-11-17 19:26:42 +01:00
f8b6c00d5d Fixed return 2025-11-17 19:26:36 +01:00
a7f6a53b9c removed double @override 2025-11-17 19:00:38 +01:00
35f2f8754a added functionality to create group 2025-11-17 18:24:30 +01:00
47bb090e72 added option to choose disabledBackgroundColor in FullWidthButton 2025-11-17 18:23:07 +01:00
b2a3d7ce7f Merge remote-tracking branch 'origin/development' into feature/5-creategroupview-erstellen 2025-11-17 15:38:33 +01:00
fde5344244 Merge pull request 'Skeleton für HomeView implementieren' (#27) from enhancement/26-skeleton-fuer-homeview-implementieren into development
Reviewed-on: #27
Reviewed-by: mathiskir <mathis.kirchner.mk@gmail.com>
2025-11-17 12:58:28 +00:00
2fc7eab1ac Corrected game tile skeleton 2025-11-17 13:19:05 +01:00
e4de8fdb25 added missing attributes for FullWidthButton in groups view 2025-11-17 13:11:47 +01:00
a54495f915 implemented basic CreateGroupView without functionality 2025-11-17 13:10:33 +01:00
b5e7fe23ab changed fullwidthbutton to include size, borderColor and infillColor attributes 2025-11-17 13:10:08 +01:00
c195c5e2bb Merge branch 'development' into enhancement/26-skeleton-fuer-homeview-implementieren 2025-11-16 22:07:34 +01:00
729cd5eff1 Merge pull request 'Datenbankkorrekturen' (#25) from enhancement/24-datenbankkorrekturen into development
Reviewed-on: #25
Reviewed-by: mathiskir <mathis.kirchner.mk@gmail.com>
2025-11-16 20:57:40 +00:00
630836d40c typo 2025-11-16 21:53:04 +01:00
f06f333a8e Merge branch 'development' into enhancement/24-datenbankkorrekturen 2025-11-16 21:52:38 +01:00
06933a67ac Merge pull request 'Group View erstellt' (#22) from feature/4-groupview-erstellen into development
Reviewed-on: #22
Reviewed-by: Felix Kirchner <felix.kirchner.fk@gmail.com>
2025-11-16 20:50:24 +00:00
a9dd3216cc Implemented skeleton 2025-11-16 20:51:28 +01:00
10a45ac1f0 removed unneccessary double quotes 2025-11-16 20:11:10 +01:00
a1d57fc424 removed sample data for group view 2025-11-16 20:04:59 +01:00
9ffb7d6ca3 changed skeleton to only show when loading 2025-11-16 19:53:32 +01:00
4befc85c9f added missing const 2025-11-16 19:52:31 +01:00
accc189949 decreased number of tiles in skeleton 2025-11-16 19:50:54 +01:00
c1e032208c added icons, titles and changed font size 2025-11-16 19:39:48 +01:00
258f610e28 added icons & titles to top contered messages 2025-11-16 19:39:34 +01:00
deab074885 changed font sizes & tile width 2025-11-16 19:38:26 +01:00
38466c6056 added title and icon to gamehistoryview 2025-11-16 19:38:08 +01:00
8d8d4319d2 change Mediaquery.of to .sizeOf 2025-11-16 19:37:51 +01:00
d3de0fda49 Updates getAllGroups test 2025-11-16 19:12:49 +01:00
e709edbf7a Added getAllPlayers test 2025-11-16 19:12:38 +01:00
74402f2e04 Added fallbacks for players when same player already exists 2025-11-16 19:02:20 +01:00
5c09dfb47d Added fallbacks for groups when same group already exists 2025-11-16 19:01:58 +01:00
02735b5b1d Added missing test 2025-11-16 18:58:01 +01:00
a6f40456d8 added missing const 2025-11-16 18:44:56 +01:00
d931e85e9f changed member tile color 2025-11-16 18:36:54 +01:00
a707990356 added new color: onBoxColor 2025-11-16 18:36:38 +01:00
3bd522df6e change colors to fit home page 2025-11-16 18:29:27 +01:00
2dd4f52336 removed sample groups from groups view 2025-11-16 16:42:18 +01:00
2dad822d79 add sample groups with sample members at app startup 2025-11-16 16:34:51 +01:00
640830d8ab fixed getAllGroups not returning members 2025-11-16 16:26:28 +01:00
168d7748a9 added todo for getAllGroups tests 2025-11-16 16:26:08 +01:00
b475237b9e ignored text for players in skeleton loading 2025-11-16 16:25:50 +01:00
2a7d409df0 Merge remote-tracking branch 'origin/development' into feature/4-groupview-erstellen 2025-11-16 15:55:23 +01:00
7c34e51779 fixed black bar behind nav bar by removing safearea 2025-11-15 22:33:00 +01:00
ac6f3d0f92 added missing const's 2025-11-15 22:10:51 +01:00
511124e323 reduced mock data loading time 2025-11-15 21:57:31 +01:00
d07bc6e8bb increased skeleton item count & added daos as import 2025-11-15 21:43:03 +01:00
352fdc13f1 added skeletonizer package requirement 2025-11-15 21:25:12 +01:00
d36348c59c added skeleton loading 2025-11-15 21:24:52 +01:00
d08c79fc26 implemented groups view with create group button 2025-11-15 20:22:09 +01:00
36aa4722a3 wrapped custom_navigation_bar in safearea 2025-11-15 17:11:48 +01:00
67bbb15845 Merge pull request 'Datenbankstruktur für Spiele' (#16) from feature/13-datenbankstruktur-fuer-spiele into development
Reviewed-on: #16
Reviewed-by: mathiskir <mathis.kirchner.mk@gmail.com>
2025-11-15 15:56:40 +00:00
1081fb8be7 rearrange imports and fix wrong syntax in widget call 2025-11-15 16:08:47 +01:00
34bf6740ad Corrected GroupGameTable attributes 2025-11-14 22:33:22 +01:00
7be86b3d9e Changed method name 2025-11-14 22:31:30 +01:00
cbd5e1d0ba Added documentation 2025-11-14 22:30:56 +01:00
2ee4d8e6fa implemented basic layout & functionality for add group button & group tiles 2025-11-14 21:53:33 +01:00
Yannick
1536e2b2af move navbar up 2025-11-14 17:31:50 +01:00
Yannick
0f13de30c4 Merge branch 'feature/2-gamehistoryview-anpassen' of https://git.yannick-weigert.de/liquid-development/game-tracker into feature/2-gamehistoryview-anpassen 2025-11-14 17:20:38 +01:00
Yannick
3f0adb4c05 use GameTile to display game history 2025-11-14 17:20:27 +01:00
2179331455 Removed test code 2025-11-14 09:01:19 +01:00
9229f1f0a5 Added counting methods + testing those 2025-11-12 20:09:17 +01:00
39b2068121 Removed unused var 2025-11-12 20:02:18 +01:00
93a4ccaee0 Added missing methods and implemented tests 2025-11-12 20:02:01 +01:00
3f5a840675 Added toString methods 2025-11-12 20:01:44 +01:00
67d5f7e891 Updated order 2025-11-12 20:01:31 +01:00
ac99217b72 Added reference on winner 2025-11-12 13:12:26 +01:00
ca40ae668d Updated methods with named parameters 2025-11-12 13:11:48 +01:00
d07943add9 Added methods for inserting games and groups into the db 2025-11-12 12:04:33 +01:00
b6700bafd9 Added on delete cascade 2025-11-12 12:04:10 +01:00
a922f24150 Added basic structure for game implementation 2025-11-12 11:41:06 +01:00
25c7b37df3 updated userId to playerId 2025-11-12 10:57:46 +01:00
b83fe03f35 Renamed app 2025-11-12 10:54:05 +01:00
cb8ff4314b Merge branch 'development' into feature/13-datenbankstruktur-fuer-spiele 2025-11-12 10:51:58 +01:00
d11b8a806f Merge pull request 'HomeView erstellen' (#15) from feature/1-homeview-erstellen into development
Reviewed-on: #15
Reviewed-by: gelbeinhalb <spam@yannick-weigert.de>
2025-11-12 09:20:18 +00:00
1abfb1bd19 Merge branch 'development' into feature/1-homeview-erstellen 2025-11-11 21:17:52 +01:00
40f9ff6413 Updated padding 2025-11-11 21:16:35 +01:00
39c72c38cf Merge branch 'feature/1-homeview-erstellen' into development 2025-11-11 21:10:31 +01:00
dd754eb569 Implemented retrieving game and group count from the db 2025-11-11 21:03:10 +01:00
4f8ba002d3 Overhauled layout building 2025-11-11 15:34:31 +01:00
6cbc64c042 Simplified game tile 2025-11-11 15:34:16 +01:00
e88211245c Implemented first version of home view 2025-11-09 23:33:29 +01:00
f1974cf71a Merge pull request 'Navbar Anpassen' (#9) from enhancement/8-tabbar-angleichen into development
Reviewed-on: #9
2025-11-09 19:59:56 +00:00
a811e0933e Merge pull request 'pull from development' (#11) from development into enhancement/8-tabbar-angleichen
Reviewed-on: #11
2025-11-09 19:59:39 +00:00
Yannick
1b090a43a0 a bit cleaner solution 2025-11-09 20:49:14 +01:00
3916cca2ca Implemented QuickInfoTile 2025-11-09 19:10:11 +01:00
5b75a325ea Merge pull request 'Datenbank refactoren' (#10) from setup/7-datenbank-refactoren into development
Reviewed-on: #10
Reviewed-by: gelbeinhalb <spam@yannick-weigert.de>
2025-11-09 17:36:25 +00:00
Yannick
92817bc4db move navbar widget to its own file 2025-11-08 18:05:19 +01:00
Yannick
34df9f007b add navbar_item.dart 2025-11-08 17:49:02 +01:00
Yannick
1698f61c2b remove useless comments 2025-11-08 17:45:04 +01:00
Yannick
17d304eb5d add bigger hitboxes 2025-11-08 17:19:00 +01:00
b03979b0c6 Completed daos, added basic GameTable & GameDao 2025-11-08 17:09:02 +01:00
Yannick
5bbb5c1888 add floating and rounded navbar 2025-11-08 16:14:52 +01:00
Yannick
d5315a8f00 change spacing of icons 2025-11-08 15:53:28 +01:00
Yannick
5baeda8b32 change history text to games 2025-11-08 15:41:56 +01:00
Yannick
0895f6df0a add text and change icons 2025-11-08 15:41:20 +01:00
4503574443 Implemented basic structure 2025-11-08 15:37:30 +01:00
Yannick
9db8c80d63 removed floating button 2025-11-08 15:29:39 +01:00
0e027f258a Merge branch 'main' into development 2025-11-08 13:59:07 +01:00
a795732da6 Updated theme 2025-11-08 13:49:08 +01:00
Sneeex
7000429856 Merge pull request #12 from LiquidDevelopmentDE/chore/remove-unused-import
remove unused home view import
2025-06-26 08:22:04 +02:00
Sneeex
6898ed51a3 remove unused home view import 2025-06-25 23:46:54 +02:00
Sneeex
da505db1c8 Merge pull request #10 from LiquidDevelopmentDE/feature/5-spielverlauf-implementieren
Spielverlauf-View implementierung
2025-06-25 23:28:39 +02:00
ed275b0f7c fixed import of custom nav bar 2025-06-25 23:24:36 +02:00
Sneeex
0902db0014 Merge branch 'development' into feature/5-spielverlauf-implementieren 2025-06-25 23:22:42 +02:00
41e9eb2c91 added const to MyApp in Providers child 2025-06-25 23:21:39 +02:00
00cedf8647 renamed lambda var in updateGroupname from u to g 2025-06-25 23:21:39 +02:00
b4e91b1211 changed return type of getGroupById and getUserById to match expected result 2025-06-25 23:21:39 +02:00
d771f78810 renamed class names to avoid conflicts 2025-06-25 23:21:39 +02:00
Sneeex
6371d7de68 Update lib/data/methods/group.dart
renamed var in deleteGroup to g instead of u

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-06-25 23:21:39 +02:00
a32df2420a generated database code 2025-06-25 23:21:39 +02:00
2b60909c43 added methods for interacting with User, Group and UserGroup in database 2025-06-25 23:21:39 +02:00
998c34e555 created tables for Group, User and UserGrouo 2025-06-25 23:21:39 +02:00
b2d686b230 added provider for state management & exposed db using provider 2025-06-25 23:21:39 +02:00
00ad4ad16d added provider requirement for state management 2025-06-25 23:20:23 +02:00
d3633c4b00 added dependencies for drift db 2025-06-25 23:20:22 +02:00
797f844a37 Merge pull request #9 from LiquidDevelopmentDE/feature/2-setup-der-datenbank
Datenbank implementierung
2025-06-25 17:46:22 +02:00
a4c7dcda5c fixed imports and method calls due to renaming 2025-06-25 17:08:13 +02:00
55857bd92c rebuilt tile to be reusable and added TextOverflow behaviour 2025-06-25 17:06:20 +02:00
b41821df47 format with dart format 2025-06-25 16:39:51 +02:00
0c39f4836e renamed game_history_empty_builder to top_centered_message 2025-06-25 16:36:39 +02:00
56116a74fc fixed type of suggestedGameData map 2025-06-25 14:52:27 +02:00
Sneeex
879a81567a fixed typo
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-06-25 14:50:57 +02:00
Sneeex
fc832d35db added type annotation for message in GameHistoryEmptyBuilder
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-06-25 14:50:41 +02:00
Sneeex
46404e3ebf removed unnecessary import
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-06-25 14:50:24 +02:00
Sneeex
80e47589ca added type annotation for currentgame in GameHistoryListTile
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-06-25 14:49:50 +02:00
8e2863d70a implemented list tile widget for game history view 2025-06-25 14:31:52 +02:00
c644a06173 implemented empty builder widget for game history view 2025-06-25 14:31:52 +02:00
0c2ec4167e implemented game history view with searchbar 2025-06-25 14:31:52 +02:00
502515002d added changing appbar title for each tab 2025-06-25 14:31:52 +02:00
27f501646b fix appbar color change on scroll 2025-06-25 14:31:52 +02:00
348b812f9c Theme changes & settings navigation 2025-06-25 14:31:52 +02:00
c78a3ed171 Implemented custom navigation bar 2025-06-25 14:31:52 +02:00
36a42a7b8d Added mocked views 2025-06-25 14:31:52 +02:00
12bb2da31c Updated pubspec.yaml 2025-06-25 14:31:52 +02:00
5d505858ab Added ios platform 2025-06-25 14:31:52 +02:00
b3c9990685 added const to MyApp in Providers child 2025-06-24 20:40:19 +02:00
0c57a83dfc renamed lambda var in updateGroupname from u to g 2025-06-24 20:38:29 +02:00
cd508190a3 changed return type of getGroupById and getUserById to match expected result 2025-06-24 20:35:30 +02:00
be08b286a4 renamed class names to avoid conflicts 2025-06-24 20:31:06 +02:00
Sneeex
e42064da2c Update lib/data/methods/group.dart
renamed var in deleteGroup to g instead of u

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-06-24 20:26:34 +02:00
c7f07e0ce7 generated database code 2025-06-24 20:17:06 +02:00
e990c1138b added methods for interacting with User, Group and UserGroup in database 2025-06-24 20:16:50 +02:00
7b7fbd47a5 created tables for Group, User and UserGrouo 2025-06-24 20:15:06 +02:00
78ea7f644e added provider for state management & exposed db using provider 2025-06-24 20:12:46 +02:00
5c33437519 added provider requirement for state management 2025-06-23 22:29:55 +02:00
0aa8e1a2a1 added dependencies for drift db 2025-06-23 18:41:54 +02:00
134 changed files with 13879 additions and 135 deletions

View File

@@ -0,0 +1,57 @@
name: Pull Request Pipeline
on:
pull_request:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install jq
run: |
apt-get update
apt-get install -y jq
- name: Install Flutter (wget)
run: |
wget https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.38.2-stable.tar.xz
tar xf flutter_linux_3.38.2-stable.tar.xz
# Set Git safe directory for Flutter path
git config --global --add safe.directory "$(pwd)/flutter"
# Set Flutter path
echo "$(pwd)/flutter/bin" >> $GITHUB_PATH
- name: Get dependencies
run: flutter pub get
- name: Analyze Formatting
run: flutter analyze lib test
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies
run: |
apt-get update
apt-get install -y jq
- name: Install Flutter (wget)
run: |
wget https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.38.2-stable.tar.xz
tar xf flutter_linux_3.38.2-stable.tar.xz
# Set Git safe directory for Flutter path
git config --global --add safe.directory "$(pwd)/flutter"
# Set Flutter path
echo "$(pwd)/flutter/bin" >> $GITHUB_PATH
- name: Get dependencies
run: flutter pub get
- name: Run tests
run: flutter test

View File

@@ -0,0 +1,50 @@
name: Push Pipeline
on:
push:
branches:
- "development"
- "main"
jobs:
format:
runs-on: ubuntu-latest
if: false # Needs bot user
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies
run: |
apt-get update
apt-get install -y jq
- name: Install Flutter (wget)
run: |
wget https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.38.2-stable.tar.xz
tar xf flutter_linux_3.38.2-stable.tar.xz
# Set Git safe directory for Flutter path
git config --global --add safe.directory "$(pwd)/flutter"
# Set Flutter path
echo "$(pwd)/flutter/bin" >> $GITHUB_PATH
- name: Get & upgrade dependencies
run: |
flutter pub get
flutter pub upgrade --major-versions
- name: Auto-format
run: |
dart format lib
dart fix --apply lib
# Needs credentials, push access and the right files need to be staged
- name: Commit Changes
run: |
git config --global user.name "Gitea Actions"
git config --global user.email "actions@gitea.com"
git status
git add lib/
git status
git commit -m "Actions: Auto-formatting [skip ci]"
git push

1
.gitignore vendored
View File

@@ -195,3 +195,4 @@ app.*.map.json
/android/app/debug
/android/app/profile
/android/app/release
/devtools_options.yaml

View File

@@ -15,19 +15,7 @@ migration:
- platform: root
create_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8
base_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8
- platform: android
create_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8
base_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8
- platform: linux
create_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8
base_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8
- platform: macos
create_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8
base_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8
- platform: web
create_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8
base_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8
- platform: windows
- platform: ios
create_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8
base_revision: b25305a8832cfc6ba632a7f87ad455e319dccce8

View File

@@ -6,6 +6,7 @@
<activity
android:name=".MainActivity"
android:exported="true"
android:screenOrientation="portrait"
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme"

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<item android:drawable="@color/launch_background" />
<!-- You can insert your own image assets here -->
<!-- <item>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 828 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 508 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 704 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="app_icon_background">#E6F1E4</color>
<color name="launch_background">#0B0B0B</color>
</resources>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Referenz unbedingt als @color/launch_background (nicht @colors/...) -->
<color name="ic_launcher_background">@color/app_icon_background</color>
</resources>

View File

@@ -4,7 +4,7 @@
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
<item name="android:windowBackground">@color/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your

104
assets/schema.json Normal file
View File

@@ -0,0 +1,104 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"players": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"createdAt": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"id",
"createdAt",
"name"
]
}
},
"groups": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"createdAt": {
"type": "string"
},
"memberIds": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"id",
"name",
"createdAt",
"memberIds"
]
}
},
"matches": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"createdAt": {
"type": "string"
},
"groupId": {
"anyOf": [
{"type": "string"},
{"type": "null"}
]
},
"playerIds": {
"type": "array",
"items": {
"type": "string"
}
},
"winnerId": {
"anyOf": [
{"type": "string"},
{"type": "null"}
]
}
},
"required": [
"id",
"name",
"createdAt",
"groupId",
"playerIds"
]
}
}
},
"required": [
"players",
"groups",
"matches"
]
}

34
ios/.gitignore vendored Normal file
View File

@@ -0,0 +1,34 @@
**/dgph
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/ephemeral/
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>13.0</string>
</dict>
</plist>

View File

@@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

View File

@@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

43
ios/Podfile Normal file
View File

@@ -0,0 +1,43 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '13.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do
inherit! :search_paths
end
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end

View File

@@ -0,0 +1,731 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
8AD879B4BA24BC1EB84E1092 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8543AAE6520EA0C0B3AF8FEE /* Pods_RunnerTests.framework */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
DDD6907F99188C9B97C6B11F /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D622CF241440C10C19C0D397 /* Pods_Runner.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
proxyType = 1;
remoteGlobalIDString = 97C146ED1CF9000F007C117D;
remoteInfo = Runner;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
13301BC306FBFE16F253F2B9 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
32DDFE3349B038E1CA758D7B /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
8543AAE6520EA0C0B3AF8FEE /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
96CDE41BAA7259C918DB326B /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
B194217AD06D15D90AAF9056 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
B68CF4A64F0B5E45B43D6900 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
D622CF241440C10C19C0D397 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
E754D1191B3E54E52B6DCC49 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
6F6FEDCE9772FEF7A6255134 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
8AD879B4BA24BC1EB84E1092 /* Pods_RunnerTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DDD6907F99188C9B97C6B11F /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
331C8082294A63A400263BE5 /* RunnerTests */ = {
isa = PBXGroup;
children = (
331C807B294A618700263BE5 /* RunnerTests.swift */,
);
path = RunnerTests;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
331C8082294A63A400263BE5 /* RunnerTests */,
ABF0E17C36D6999806C09130 /* Pods */,
F14326E3F17437DD2E32AB7B /* Frameworks */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
331C8081294A63A400263BE5 /* RunnerTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
);
path = Runner;
sourceTree = "<group>";
};
ABF0E17C36D6999806C09130 /* Pods */ = {
isa = PBXGroup;
children = (
B194217AD06D15D90AAF9056 /* Pods-Runner.debug.xcconfig */,
32DDFE3349B038E1CA758D7B /* Pods-Runner.release.xcconfig */,
13301BC306FBFE16F253F2B9 /* Pods-Runner.profile.xcconfig */,
96CDE41BAA7259C918DB326B /* Pods-RunnerTests.debug.xcconfig */,
B68CF4A64F0B5E45B43D6900 /* Pods-RunnerTests.release.xcconfig */,
E754D1191B3E54E52B6DCC49 /* Pods-RunnerTests.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
F14326E3F17437DD2E32AB7B /* Frameworks */ = {
isa = PBXGroup;
children = (
D622CF241440C10C19C0D397 /* Pods_Runner.framework */,
8543AAE6520EA0C0B3AF8FEE /* Pods_RunnerTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
331C8080294A63A400263BE5 /* RunnerTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
F7D5E29C2C77E2E8925BBB8A /* [CP] Check Pods Manifest.lock */,
331C807D294A63A400263BE5 /* Sources */,
331C807F294A63A400263BE5 /* Resources */,
6F6FEDCE9772FEF7A6255134 /* Frameworks */,
);
buildRules = (
);
dependencies = (
331C8086294A63A400263BE5 /* PBXTargetDependency */,
);
name = RunnerTests;
productName = RunnerTests;
productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
8947D8DE27F8CB7D5A5F265C /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
0CC58B149CD3F41CF94E1C52 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
331C8080294A63A400263BE5 = {
CreatedOnToolsVersion = 14.0;
TestTargetID = 97C146ED1CF9000F007C117D;
};
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
331C8080294A63A400263BE5 /* RunnerTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
331C807F294A63A400263BE5 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
0CC58B149CD3F41CF94E1C52 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
8947D8DE27F8CB7D5A5F265C /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
F7D5E29C2C77E2E8925BBB8A /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
331C807D294A63A400263BE5 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
331C8086294A63A400263BE5 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 97C146ED1CF9000F007C117D /* Runner */;
targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = RJB4MM6RVS;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.gameTracker;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
331C8088294A63A400263BE5 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 96CDE41BAA7259C918DB326B /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.example.gameTracker.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Debug;
};
331C8089294A63A400263BE5 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = B68CF4A64F0B5E45B43D6900 /* Pods-RunnerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.example.gameTracker.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Release;
};
331C808A294A63A400263BE5 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = E754D1191B3E54E52B6DCC49 /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.example.gameTracker.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = RJB4MM6RVS;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.gameTracker;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = RJB4MM6RVS;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.gameTracker;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
331C8088294A63A400263BE5 /* Debug */,
331C8089294A63A400263BE5 /* Release */,
331C808A294A63A400263BE5 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

View File

@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "331C8080294A63A400263BE5"
BuildableName = "RunnerTests.xctest"
BlueprintName = "RunnerTests"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
enableGPUValidationMode = "1"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

View File

@@ -0,0 +1,13 @@
import Flutter
import UIKit
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}

View File

@@ -0,0 +1,14 @@
{
"images" : [
{
"filename" : "icon_x1024.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,20 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.043",
"green" : "0.043",
"red" : "0.043"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "icon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="24412" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="24405"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="LauncherIcon" translatesAutoresizingMaskIntoConstraints="NO" id="ygV-Op-Bu5">
<rect key="frame" x="46" y="334" width="301" height="184"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
</subviews>
<color key="backgroundColor" name="LauncherBackgroundColor"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="80.152671755725194" y="264.08450704225356"/>
</scene>
</scenes>
<color key="tintColor" red="0.90196078431372551" green="0.94509803921568625" blue="0.89411764705882346" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<resources>
<image name="LauncherIcon" width="1000" height="1000"/>
<namedColor name="LauncherBackgroundColor">
<color red="0.90196078431372551" green="0.94509803921568625" blue="0.89411764705882346" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
</resources>
</document>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="24412" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="24405"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="141" y="131"/>
</scene>
</scenes>
</document>

47
ios/Runner/Info.plist Normal file
View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Game Tracker</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>game_tracker</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1 @@
#import "GeneratedPluginRegistrant.h"

View File

@@ -0,0 +1,12 @@
import Flutter
import UIKit
import XCTest
class RunnerTests: XCTestCase {
func testExample() {
// If you add code to the Runner application, consider adding tests here.
// See https://developer.apple.com/documentation/xctest for more information about using XCTest.
}
}

5
l10n.yaml Normal file
View File

@@ -0,0 +1,5 @@
arb-dir: lib/l10n/arb
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
output-dir: lib/l10n/generated
nullable-getter: false

View File

@@ -0,0 +1,19 @@
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
Route<T> adaptivePageRoute<T>({
required Widget Function(BuildContext) builder,
bool fullscreenDialog = false,
}) {
if (Platform.isIOS) {
return CupertinoPageRoute<T>(
builder: builder,
fullscreenDialog: fullscreenDialog,
);
}
return MaterialPageRoute<T>(
builder: builder,
fullscreenDialog: fullscreenDialog,
);
}

6
lib/core/constants.dart Normal file
View File

@@ -0,0 +1,6 @@
class Constants {
Constants._(); // Private constructor to prevent instantiation
/// Minimum duration of all app skeletons
static Duration minimumSkeletonDuration = const Duration(milliseconds: 250);
}

View File

@@ -0,0 +1,61 @@
import 'package:flutter/material.dart';
class CustomTheme {
CustomTheme._(); // Private constructor to prevent instantiation
// ==================== Colors ====================
static Color primaryColor = const Color(0xFF7505E4);
static Color secondaryColor = const Color(0xFFAFA2FF);
static Color backgroundColor = const Color(0xFF0B0B0B);
static Color boxColor = const Color(0xFF101010);
static Color onBoxColor = const Color(0xFF181818);
static Color boxBorder = const Color(0xFF272727);
static const Color textColor = Colors.white;
static Color navBarItemSelectedColor = primaryColor.withValues(green: 0.4);
static Color navBarItemUnselectedColor = Colors.white.withValues(alpha: 0.6);
// ==================== Border Radius ====================
static const double standardBorderRadius = 12.0;
static BorderRadius get standardBorderRadiusAll =>
BorderRadius.circular(standardBorderRadius);
// ==================== Padding & Margins ====================
static const EdgeInsets standardMargin = EdgeInsets.symmetric(
horizontal: 12,
vertical: 10,
);
static const EdgeInsets tileMargin = EdgeInsets.symmetric(
horizontal: 12,
vertical: 5,
);
// ==================== Decorations ====================
static BoxDecoration standardBoxDecoration = BoxDecoration(
color: boxColor,
border: Border.all(color: boxBorder),
borderRadius: standardBorderRadiusAll,
);
static BoxDecoration highlightedBoxDecoration = BoxDecoration(
color: boxColor,
border: Border.all(color: primaryColor),
borderRadius: standardBorderRadiusAll,
boxShadow: [BoxShadow(color: primaryColor.withAlpha(120), blurRadius: 12)],
);
// ==================== App Bar Theme ====================
static AppBarTheme appBarTheme = AppBarTheme(
backgroundColor: backgroundColor,
foregroundColor: textColor,
elevation: 0,
scrolledUnderElevation: 0,
centerTitle: true,
titleTextStyle: const TextStyle(
color: textColor,
fontSize: 20,
fontWeight: FontWeight.bold,
overflow: TextOverflow.ellipsis,
),
iconTheme: const IconThemeData(color: textColor),
);
}

52
lib/core/enums.dart Normal file
View File

@@ -0,0 +1,52 @@
import 'package:flutter/material.dart';
import 'package:game_tracker/l10n/generated/app_localizations.dart';
/// Button types used for styling the [CustomWidthButton]
/// - [ButtonType.primary]: Primary button style.
/// - [ButtonType.secondary]: Secondary button style.
/// - [ButtonType.tertiary]: Tertiary button style.
enum ButtonType { primary, secondary, tertiary }
/// Result types for import operations in the [SettingsView]
/// - [ImportResult.success]: The import operation was successful.
/// - [ImportResult.canceled]: The import operation was canceled by the user.
/// - [ImportResult.fileReadError]: There was an error reading the selected file.
/// - [ImportResult.invalidSchema]: The JSON schema of the imported data is invalid.
/// - [ImportResult.formatException]: A format exception occurred during import.
/// - [ImportResult.unknownException]: An exception occurred during import.
enum ImportResult {
success,
canceled,
fileReadError,
invalidSchema,
formatException,
unknownException,
}
/// Result types for export operations in the [SettingsView]
/// - [ExportResult.success]: The export operation was successful.
/// - [ExportResult.canceled]: The export operation was canceled by the user.
/// - [ExportResult.unknownException]: An exception occurred during export.
enum ExportResult { success, canceled, unknownException }
/// Different rulesets available for matches
/// - [Ruleset.singleWinner]: The match is won by a single player
/// - [Ruleset.singleLoser]: The match is lost by a single player
/// - [Ruleset.mostPoints]: The player with the most points wins.
/// - [Ruleset.leastPoints]: The player with the fewest points wins.
enum Ruleset { singleWinner, singleLoser, mostPoints, leastPoints }
/// Translates a [Ruleset] enum value to its corresponding localized string.
String translateRulesetToString(Ruleset ruleset, BuildContext context) {
final loc = AppLocalizations.of(context);
switch (ruleset) {
case Ruleset.singleWinner:
return loc.single_winner;
case Ruleset.singleLoser:
return loc.single_loser;
case Ruleset.mostPoints:
return loc.most_points;
case Ruleset.leastPoints:
return loc.least_points;
}
}

214
lib/data/dao/group_dao.dart Normal file
View File

@@ -0,0 +1,214 @@
import 'package:drift/drift.dart';
import 'package:game_tracker/data/db/database.dart';
import 'package:game_tracker/data/db/tables/group_table.dart';
import 'package:game_tracker/data/db/tables/player_group_table.dart';
import 'package:game_tracker/data/dto/group.dart';
import 'package:game_tracker/data/dto/player.dart';
part 'group_dao.g.dart';
@DriftAccessor(tables: [GroupTable, PlayerGroupTable])
class GroupDao extends DatabaseAccessor<AppDatabase> with _$GroupDaoMixin {
GroupDao(super.db);
/// Retrieves all groups from the database.
Future<List<Group>> getAllGroups() async {
final query = select(groupTable);
final result = await query.get();
return Future.wait(
result.map((groupData) async {
final members = await db.playerGroupDao.getPlayersOfGroup(
groupId: groupData.id,
);
return Group(
id: groupData.id,
name: groupData.name,
members: members,
createdAt: groupData.createdAt,
);
}),
);
}
/// Retrieves a [Group] by its [groupId], including its members.
Future<Group> getGroupById({required String groupId}) async {
final query = select(groupTable)..where((g) => g.id.equals(groupId));
final result = await query.getSingle();
List<Player> members = await db.playerGroupDao.getPlayersOfGroup(
groupId: groupId,
);
return Group(
id: result.id,
name: result.name,
members: members,
createdAt: result.createdAt,
);
}
/// Adds a new group with the given [id] and [name] to the database.
/// This method also adds the group's members to the [PlayerGroupTable].
Future<bool> addGroup({required Group group}) async {
if (!await groupExists(groupId: group.id)) {
await db.transaction(() async {
await into(groupTable).insert(
GroupTableCompanion.insert(
id: group.id,
name: group.name,
createdAt: group.createdAt,
),
mode: InsertMode.insertOrReplace,
);
await Future.wait(
group.members.map((player) => db.playerDao.addPlayer(player: player)),
);
await db.batch(
(b) => b.insertAll(
db.playerGroupTable,
group.members
.map(
(member) => PlayerGroupTableCompanion.insert(
playerId: member.id,
groupId: group.id,
),
)
.toList(),
mode: InsertMode.insertOrReplace,
),
);
});
return true;
}
return false;
}
/// Adds multiple groups to the database.
/// Also adds the group's members to the [PlayerGroupTable].
Future<void> addGroupsAsList({required List<Group> groups}) async {
if (groups.isEmpty) return;
await db.transaction(() async {
// Deduplicate groups by id - keep first occurrence
final Map<String, Group> uniqueGroups = {};
for (final g in groups) {
uniqueGroups.putIfAbsent(g.id, () => g);
}
// Insert unique groups in batch
// Using insertOrIgnore to avoid triggering cascade deletes on
// player_group associations when groups already exist
await db.batch(
(b) => b.insertAll(
groupTable,
uniqueGroups.values
.map(
(group) => GroupTableCompanion.insert(
id: group.id,
name: group.name,
createdAt: group.createdAt,
),
)
.toList(),
mode: InsertMode.insertOrIgnore,
),
);
// Collect unique players from all groups
final uniquePlayers = <String, Player>{};
for (final g in uniqueGroups.values) {
for (final m in g.members) {
uniquePlayers[m.id] = m;
}
}
if (uniquePlayers.isNotEmpty) {
// Using insertOrIgnore to avoid triggering cascade deletes on
// player_group associations when players already exist
await db.batch(
(b) => b.insertAll(
db.playerTable,
uniquePlayers.values
.map(
(p) => PlayerTableCompanion.insert(
id: p.id,
name: p.name,
createdAt: p.createdAt,
),
)
.toList(),
mode: InsertMode.insertOrIgnore,
),
);
}
// Prepare all player-group associations in one list (unique pairs)
final Set<String> seenPairs = {};
final List<PlayerGroupTableCompanion> pgRows = [];
for (final g in uniqueGroups.values) {
for (final m in g.members) {
final key = '${m.id}|${g.id}';
if (!seenPairs.contains(key)) {
seenPairs.add(key);
pgRows.add(
PlayerGroupTableCompanion.insert(playerId: m.id, groupId: g.id),
);
}
}
}
if (pgRows.isNotEmpty) {
await db.batch((b) {
for (final pg in pgRows) {
b.insert(db.playerGroupTable, pg, mode: InsertMode.insertOrReplace);
}
});
}
});
}
/// Deletes the group with the given [id] from the database.
/// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> deleteGroup({required String groupId}) async {
final query = (delete(groupTable)..where((g) => g.id.equals(groupId)));
final rowsAffected = await query.go();
return rowsAffected > 0;
}
/// Updates the name of the group with the given [id] to [newName].
/// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> updateGroupname({
required String groupId,
required String newName,
}) async {
final rowsAffected =
await (update(groupTable)..where((g) => g.id.equals(groupId))).write(
GroupTableCompanion(name: Value(newName)),
);
return rowsAffected > 0;
}
/// Retrieves the number of groups in the database.
Future<int> getGroupCount() async {
final count =
await (selectOnly(groupTable)..addColumns([groupTable.id.count()]))
.map((row) => row.read(groupTable.id.count()))
.getSingle();
return count ?? 0;
}
/// Checks if a group with the given [groupId] exists in the database.
/// Returns `true` if the group exists, `false` otherwise.
Future<bool> groupExists({required String groupId}) async {
final query = select(groupTable)..where((g) => g.id.equals(groupId));
final result = await query.getSingleOrNull();
return result != null;
}
/// Deletes all groups from the database.
/// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> deleteAllGroups() async {
final query = delete(groupTable);
final rowsAffected = await query.go();
return rowsAffected > 0;
}
}

View File

@@ -0,0 +1,11 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'group_dao.dart';
// ignore_for_file: type=lint
mixin _$GroupDaoMixin on DatabaseAccessor<AppDatabase> {
$GroupTableTable get groupTable => attachedDatabase.groupTable;
$PlayerTableTable get playerTable => attachedDatabase.playerTable;
$PlayerGroupTableTable get playerGroupTable =>
attachedDatabase.playerGroupTable;
}

View File

@@ -0,0 +1,98 @@
import 'package:drift/drift.dart';
import 'package:game_tracker/data/db/database.dart';
import 'package:game_tracker/data/db/tables/group_match_table.dart';
import 'package:game_tracker/data/dto/group.dart';
part 'group_match_dao.g.dart';
@DriftAccessor(tables: [GroupMatchTable])
class GroupMatchDao extends DatabaseAccessor<AppDatabase>
with _$GroupMatchDaoMixin {
GroupMatchDao(super.db);
/// Associates a group with a match by inserting a record into the
/// [GroupMatchTable].
Future<void> addGroupToMatch({
required String matchId,
required String groupId,
}) async {
if (await matchHasGroup(matchId: matchId)) {
throw Exception('Match already has a group');
}
await into(groupMatchTable).insert(
GroupMatchTableCompanion.insert(groupId: groupId, matchId: matchId),
mode: InsertMode.insertOrIgnore,
);
}
/// Retrieves the [Group] associated with the given [matchId].
/// Returns `null` if no group is found.
Future<Group?> getGroupOfMatch({required String matchId}) async {
final result = await (select(
groupMatchTable,
)..where((g) => g.matchId.equals(matchId))).getSingleOrNull();
if (result == null) {
return null;
}
final group = await db.groupDao.getGroupById(groupId: result.groupId);
return group;
}
/// Checks if there is a group associated with the given [matchId].
/// Returns `true` if there is a group, otherwise `false`.
Future<bool> matchHasGroup({required String matchId}) async {
final count =
await (selectOnly(groupMatchTable)
..where(groupMatchTable.matchId.equals(matchId))
..addColumns([groupMatchTable.groupId.count()]))
.map((row) => row.read(groupMatchTable.groupId.count()))
.getSingle();
return (count ?? 0) > 0;
}
/// Checks if a specific group is associated with a specific match.
/// Returns `true` if the group is in the match, otherwise `false`.
Future<bool> isGroupInMatch({
required String matchId,
required String groupId,
}) async {
final count =
await (selectOnly(groupMatchTable)
..where(
groupMatchTable.matchId.equals(matchId) &
groupMatchTable.groupId.equals(groupId),
)
..addColumns([groupMatchTable.groupId.count()]))
.map((row) => row.read(groupMatchTable.groupId.count()))
.getSingle();
return (count ?? 0) > 0;
}
/// Removes the association of a group from a match based on [groupId] and
/// [matchId].
/// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> removeGroupFromMatch({
required String matchId,
required String groupId,
}) async {
final query = delete(groupMatchTable)
..where((g) => g.matchId.equals(matchId) & g.groupId.equals(groupId));
final rowsAffected = await query.go();
return rowsAffected > 0;
}
/// Updates the group associated with a match to [newGroupId] based on
/// [matchId].
/// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> updateGroupOfMatch({
required String matchId,
required String newGroupId,
}) async {
final updatedRows =
await (update(groupMatchTable)..where((g) => g.matchId.equals(matchId)))
.write(GroupMatchTableCompanion(groupId: Value(newGroupId)));
return updatedRows > 0;
}
}

View File

@@ -0,0 +1,10 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'group_match_dao.dart';
// ignore_for_file: type=lint
mixin _$GroupMatchDaoMixin on DatabaseAccessor<AppDatabase> {
$GroupTableTable get groupTable => attachedDatabase.groupTable;
$MatchTableTable get matchTable => attachedDatabase.matchTable;
$GroupMatchTableTable get groupMatchTable => attachedDatabase.groupMatchTable;
}

326
lib/data/dao/match_dao.dart Normal file
View File

@@ -0,0 +1,326 @@
import 'package:drift/drift.dart';
import 'package:game_tracker/data/db/database.dart';
import 'package:game_tracker/data/db/tables/match_table.dart';
import 'package:game_tracker/data/dto/group.dart';
import 'package:game_tracker/data/dto/match.dart';
import 'package:game_tracker/data/dto/player.dart';
part 'match_dao.g.dart';
@DriftAccessor(tables: [MatchTable])
class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
MatchDao(super.db);
/// Retrieves all matches from the database.
Future<List<Match>> getAllMatches() async {
final query = select(matchTable);
final result = await query.get();
return Future.wait(
result.map((row) async {
final group = await db.groupMatchDao.getGroupOfMatch(matchId: row.id);
final players = await db.playerMatchDao.getPlayersOfMatch(
matchId: row.id,
);
final winner = row.winnerId != null
? await db.playerDao.getPlayerById(playerId: row.winnerId!)
: null;
return Match(
id: row.id,
name: row.name,
group: group,
players: players,
createdAt: row.createdAt,
winner: winner,
);
}),
);
}
/// Retrieves a [Match] by its [matchId].
Future<Match> getMatchById({required String matchId}) async {
final query = select(matchTable)..where((g) => g.id.equals(matchId));
final result = await query.getSingle();
List<Player>? players;
if (await db.playerMatchDao.matchHasPlayers(matchId: matchId)) {
players = await db.playerMatchDao.getPlayersOfMatch(matchId: matchId);
}
Group? group;
if (await db.groupMatchDao.matchHasGroup(matchId: matchId)) {
group = await db.groupMatchDao.getGroupOfMatch(matchId: matchId);
}
Player? winner;
if (result.winnerId != null) {
winner = await db.playerDao.getPlayerById(playerId: result.winnerId!);
}
return Match(
id: result.id,
name: result.name,
players: players,
group: group,
winner: winner,
createdAt: result.createdAt,
);
}
/// Adds a new [Match] to the database. Also adds players and group
/// associations. This method assumes that the players and groups added to
/// this match are already present in the database.
Future<void> addMatch({required Match match}) async {
await db.transaction(() async {
await into(matchTable).insert(
MatchTableCompanion.insert(
id: match.id,
name: match.name,
winnerId: Value(match.winner?.id),
createdAt: match.createdAt,
),
mode: InsertMode.insertOrReplace,
);
if (match.players != null) {
for (final p in match.players ?? []) {
await db.playerMatchDao.addPlayerToMatch(
matchId: match.id,
playerId: p.id,
);
}
}
if (match.group != null) {
await db.groupMatchDao.addGroupToMatch(
matchId: match.id,
groupId: match.group!.id,
);
}
});
}
/// Adds multiple [Match]s to the database in a batch operation.
/// Also adds associated players and groups if they exist.
/// If the [matches] list is empty, the method returns immediately.
/// This Method should only be used to import matches from a different device.
Future<void> addMatchAsList({required List<Match> matches}) async {
if (matches.isEmpty) return;
await db.transaction(() async {
// Add all matches in batch
await db.batch(
(b) => b.insertAll(
matchTable,
matches
.map(
(match) => MatchTableCompanion.insert(
id: match.id,
name: match.name,
createdAt: match.createdAt,
winnerId: Value(match.winner?.id),
),
)
.toList(),
mode: InsertMode.insertOrReplace,
),
);
// Add all groups of the matches in batch
// Using insertOrIgnore to avoid overwriting existing groups (which would
// trigger cascade deletes on player_group associations)
await db.batch(
(b) => b.insertAll(
db.groupTable,
matches
.where((match) => match.group != null)
.map(
(matches) => GroupTableCompanion.insert(
id: matches.group!.id,
name: matches.group!.name,
createdAt: matches.group!.createdAt,
),
)
.toList(),
mode: InsertMode.insertOrIgnore,
),
);
// Add all players of the matches in batch (unique)
final uniquePlayers = <String, Player>{};
for (final match in matches) {
if (match.players != null) {
for (final p in match.players!) {
uniquePlayers[p.id] = p;
}
}
// Also include members of groups
if (match.group != null) {
for (final m in match.group!.members) {
uniquePlayers[m.id] = m;
}
}
}
if (uniquePlayers.isNotEmpty) {
// Using insertOrIgnore to avoid triggering cascade deletes on
// player_group/player_match associations when players already exist
await db.batch(
(b) => b.insertAll(
db.playerTable,
uniquePlayers.values
.map(
(p) => PlayerTableCompanion.insert(
id: p.id,
name: p.name,
createdAt: p.createdAt,
),
)
.toList(),
mode: InsertMode.insertOrIgnore,
),
);
}
// Add all player-match associations in batch
await db.batch((b) {
for (final match in matches) {
if (match.players != null) {
for (final p in match.players ?? []) {
b.insert(
db.playerMatchTable,
PlayerMatchTableCompanion.insert(
matchId: match.id,
playerId: p.id,
),
mode: InsertMode.insertOrIgnore,
);
}
}
}
});
// Add all player-group associations in batch
await db.batch((b) {
for (final match in matches) {
if (match.group != null) {
for (final m in match.group!.members) {
b.insert(
db.playerGroupTable,
PlayerGroupTableCompanion.insert(
playerId: m.id,
groupId: match.group!.id,
),
mode: InsertMode.insertOrIgnore,
);
}
}
}
});
// Add all group-match associations in batch
await db.batch((b) {
for (final match in matches) {
if (match.group != null) {
b.insert(
db.groupMatchTable,
GroupMatchTableCompanion.insert(
matchId: match.id,
groupId: match.group!.id,
),
mode: InsertMode.insertOrIgnore,
);
}
}
});
});
}
/// Deletes the match with the given [matchId] from the database.
/// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> deleteMatch({required String matchId}) async {
final query = delete(matchTable)..where((g) => g.id.equals(matchId));
final rowsAffected = await query.go();
return rowsAffected > 0;
}
/// Retrieves the number of matches in the database.
Future<int> getMatchCount() async {
final count =
await (selectOnly(matchTable)..addColumns([matchTable.id.count()]))
.map((row) => row.read(matchTable.id.count()))
.getSingle();
return count ?? 0;
}
/// Checks if a match with the given [matchId] exists in the database.
/// Returns `true` if the match exists, otherwise `false`.
Future<bool> matchExists({required String matchId}) async {
final query = select(matchTable)..where((g) => g.id.equals(matchId));
final result = await query.getSingleOrNull();
return result != null;
}
/// Deletes all matches from the database.
/// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> deleteAllMatches() async {
final query = delete(matchTable);
final rowsAffected = await query.go();
return rowsAffected > 0;
}
/// Sets the winner of the match with the given [matchId] to the player with
/// the given [winnerId].
/// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> setWinner({
required String matchId,
required String winnerId,
}) async {
final query = update(matchTable)..where((g) => g.id.equals(matchId));
final rowsAffected = await query.write(
MatchTableCompanion(winnerId: Value(winnerId)),
);
return rowsAffected > 0;
}
/// Retrieves the winner of the match with the given [matchId].
/// Returns the [Player] who won the match, or `null` if no winner is set.
Future<Player?> getWinner({required String matchId}) async {
final query = select(matchTable)..where((g) => g.id.equals(matchId));
final result = await query.getSingleOrNull();
if (result == null || result.winnerId == null) {
return null;
}
final winner = await db.playerDao.getPlayerById(playerId: result.winnerId!);
return winner;
}
/// Removes the winner of the match with the given [matchId].
/// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> removeWinner({required String matchId}) async {
final query = update(matchTable)..where((g) => g.id.equals(matchId));
final rowsAffected = await query.write(
const MatchTableCompanion(winnerId: Value(null)),
);
return rowsAffected > 0;
}
/// Checks if the match with the given [matchId] has a winner set.
/// Returns `true` if a winner is set, otherwise `false`.
Future<bool> hasWinner({required String matchId}) async {
final query = select(matchTable)
..where((g) => g.id.equals(matchId) & g.winnerId.isNotNull());
final result = await query.getSingleOrNull();
return result != null;
}
/// Changes the title of the match with the given [matchId] to [newName].
/// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> updateMatchName({
required String matchId,
required String newName,
}) async {
final query = update(matchTable)..where((g) => g.id.equals(matchId));
final rowsAffected = await query.write(
MatchTableCompanion(name: Value(newName)),
);
return rowsAffected > 0;
}
}

View File

@@ -0,0 +1,8 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'match_dao.dart';
// ignore_for_file: type=lint
mixin _$MatchDaoMixin on DatabaseAccessor<AppDatabase> {
$MatchTableTable get matchTable => attachedDatabase.matchTable;
}

View File

@@ -0,0 +1,119 @@
import 'package:drift/drift.dart';
import 'package:game_tracker/data/db/database.dart';
import 'package:game_tracker/data/db/tables/player_table.dart';
import 'package:game_tracker/data/dto/player.dart';
part 'player_dao.g.dart';
@DriftAccessor(tables: [PlayerTable])
class PlayerDao extends DatabaseAccessor<AppDatabase> with _$PlayerDaoMixin {
PlayerDao(super.db);
/// Retrieves all players from the database.
Future<List<Player>> getAllPlayers() async {
final query = select(playerTable);
final result = await query.get();
return result
.map(
(row) => Player(id: row.id, name: row.name, createdAt: row.createdAt),
)
.toList();
}
/// Retrieves a [Player] by their [id].
Future<Player> getPlayerById({required String playerId}) async {
final query = select(playerTable)..where((p) => p.id.equals(playerId));
final result = await query.getSingle();
return Player(
id: result.id,
name: result.name,
createdAt: result.createdAt,
);
}
/// Adds a new [player] to the database.
/// If a player with the same ID already exists, updates their name to
/// the new one.
Future<bool> addPlayer({required Player player}) async {
if (!await playerExists(playerId: player.id)) {
await into(playerTable).insert(
PlayerTableCompanion.insert(
id: player.id,
name: player.name,
createdAt: player.createdAt,
),
mode: InsertMode.insertOrReplace,
);
return true;
}
return false;
}
/// Adds multiple [players] to the database in a batch operation.
/// Uses insertOrIgnore to avoid triggering cascade deletes on
/// player_group associations when players already exist.
Future<bool> addPlayersAsList({required List<Player> players}) async {
if (players.isEmpty) return false;
await db.batch(
(b) => b.insertAll(
playerTable,
players
.map(
(player) => PlayerTableCompanion.insert(
id: player.id,
name: player.name,
createdAt: player.createdAt,
),
)
.toList(),
mode: InsertMode.insertOrIgnore,
),
);
return true;
}
/// Deletes the player with the given [id] from the database.
/// Returns `true` if the player was deleted, `false` if the player did not exist.
Future<bool> deletePlayer({required String playerId}) async {
final query = delete(playerTable)..where((p) => p.id.equals(playerId));
final rowsAffected = await query.go();
return rowsAffected > 0;
}
/// Checks if a player with the given [id] exists in the database.
/// Returns `true` if the player exists, `false` otherwise.
Future<bool> playerExists({required String playerId}) async {
final query = select(playerTable)..where((p) => p.id.equals(playerId));
final result = await query.getSingleOrNull();
return result != null;
}
/// Updates the name of the player with the given [playerId] to [newName].
Future<void> updatePlayername({
required String playerId,
required String newName,
}) async {
await (update(playerTable)..where((p) => p.id.equals(playerId))).write(
PlayerTableCompanion(name: Value(newName)),
);
}
/// Retrieves the total count of players in the database.
Future<int> getPlayerCount() async {
final count =
await (selectOnly(playerTable)..addColumns([playerTable.id.count()]))
.map((row) => row.read(playerTable.id.count()))
.getSingle();
return count ?? 0;
}
/// Deletes all players from the database.
/// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> deleteAllPlayers() async {
final query = delete(playerTable);
final rowsAffected = await query.go();
return rowsAffected > 0;
}
}

View File

@@ -0,0 +1,8 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'player_dao.dart';
// ignore_for_file: type=lint
mixin _$PlayerDaoMixin on DatabaseAccessor<AppDatabase> {
$PlayerTableTable get playerTable => attachedDatabase.playerTable;
}

View File

@@ -0,0 +1,79 @@
import 'package:drift/drift.dart';
import 'package:game_tracker/data/db/database.dart';
import 'package:game_tracker/data/db/tables/player_group_table.dart';
import 'package:game_tracker/data/db/tables/player_table.dart';
import 'package:game_tracker/data/dto/player.dart';
part 'player_group_dao.g.dart';
@DriftAccessor(tables: [PlayerGroupTable, PlayerTable])
class PlayerGroupDao extends DatabaseAccessor<AppDatabase>
with _$PlayerGroupDaoMixin {
PlayerGroupDao(super.db);
/// No need for a groupHasPlayers method since the members attribute is
/// not nullable
/// Adds a [player] to a group with the given [groupId].
/// If the player is already in the group, no action is taken.
/// If the player does not exist in the player table, they are added.
/// Returns `true` if the player was added, otherwise `false`.
Future<bool> addPlayerToGroup({
required Player player,
required String groupId,
}) async {
if (await isPlayerInGroup(playerId: player.id, groupId: groupId)) {
return false;
}
if (!await db.playerDao.playerExists(playerId: player.id)) {
db.playerDao.addPlayer(player: player);
}
await into(playerGroupTable).insert(
PlayerGroupTableCompanion.insert(playerId: player.id, groupId: groupId),
);
return true;
}
/// Retrieves all players belonging to a specific group by [groupId].
Future<List<Player>> getPlayersOfGroup({required String groupId}) async {
final query = select(playerGroupTable)
..where((pG) => pG.groupId.equals(groupId));
final result = await query.get();
List<Player> groupMembers = List.empty(growable: true);
for (var entry in result) {
final player = await db.playerDao.getPlayerById(playerId: entry.playerId);
groupMembers.add(player);
}
return groupMembers;
}
/// Removes a player from a group based on [playerId] and [groupId].
/// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> removePlayerFromGroup({
required String playerId,
required String groupId,
}) async {
final query = delete(playerGroupTable)
..where((p) => p.playerId.equals(playerId) & p.groupId.equals(groupId));
final rowsAffected = await query.go();
return rowsAffected > 0;
}
/// Checks if a player with [playerId] is in the group with [groupId].
/// Returns `true` if the player is in the group, otherwise `false`.
Future<bool> isPlayerInGroup({
required String playerId,
required String groupId,
}) async {
final query = select(playerGroupTable)
..where((p) => p.playerId.equals(playerId) & p.groupId.equals(groupId));
final result = await query.getSingleOrNull();
return result != null;
}
}

View File

@@ -0,0 +1,11 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'player_group_dao.dart';
// ignore_for_file: type=lint
mixin _$PlayerGroupDaoMixin on DatabaseAccessor<AppDatabase> {
$PlayerTableTable get playerTable => attachedDatabase.playerTable;
$GroupTableTable get groupTable => attachedDatabase.groupTable;
$PlayerGroupTableTable get playerGroupTable =>
attachedDatabase.playerGroupTable;
}

View File

@@ -0,0 +1,130 @@
import 'package:drift/drift.dart';
import 'package:game_tracker/data/db/database.dart';
import 'package:game_tracker/data/db/tables/player_match_table.dart';
import 'package:game_tracker/data/dto/player.dart';
part 'player_match_dao.g.dart';
@DriftAccessor(tables: [PlayerMatchTable])
class PlayerMatchDao extends DatabaseAccessor<AppDatabase>
with _$PlayerMatchDaoMixin {
PlayerMatchDao(super.db);
/// Associates a player with a match by inserting a record into the
/// [PlayerMatchTable].
Future<void> addPlayerToMatch({
required String matchId,
required String playerId,
}) async {
await into(playerMatchTable).insert(
PlayerMatchTableCompanion.insert(playerId: playerId, matchId: matchId),
mode: InsertMode.insertOrIgnore,
);
}
/// Retrieves a list of [Player]s associated with the given [matchId].
/// Returns null if no players are found.
Future<List<Player>?> getPlayersOfMatch({required String matchId}) async {
final result = await (select(
playerMatchTable,
)..where((p) => p.matchId.equals(matchId))).get();
if (result.isEmpty) return null;
final futures = result.map(
(row) => db.playerDao.getPlayerById(playerId: row.playerId),
);
final players = await Future.wait(futures);
return players;
}
/// Checks if there are any players associated with the given [matchId].
/// Returns `true` if there are players, otherwise `false`.
Future<bool> matchHasPlayers({required String matchId}) async {
final count =
await (selectOnly(playerMatchTable)
..where(playerMatchTable.matchId.equals(matchId))
..addColumns([playerMatchTable.playerId.count()]))
.map((row) => row.read(playerMatchTable.playerId.count()))
.getSingle();
return (count ?? 0) > 0;
}
/// Checks if a specific player is associated with a specific match.
/// Returns `true` if the player is in the match, otherwise `false`.
Future<bool> isPlayerInMatch({
required String matchId,
required String playerId,
}) async {
final count =
await (selectOnly(playerMatchTable)
..where(playerMatchTable.matchId.equals(matchId))
..where(playerMatchTable.playerId.equals(playerId))
..addColumns([playerMatchTable.playerId.count()]))
.map((row) => row.read(playerMatchTable.playerId.count()))
.getSingle();
return (count ?? 0) > 0;
}
/// Removes the association of a player with a match by deleting the record
/// from the [PlayerMatchTable].
/// Returns `true` if more than 0 rows were affected, otherwise `false`.
Future<bool> removePlayerFromMatch({
required String matchId,
required String playerId,
}) async {
final query = delete(playerMatchTable)
..where((pg) => pg.matchId.equals(matchId))
..where((pg) => pg.playerId.equals(playerId));
final rowsAffected = await query.go();
return rowsAffected > 0;
}
/// Updates the players associated with a match based on the provided
/// [newPlayer] list. It adds new players and removes players that are no
/// longer associated with the match.
Future<void> updatePlayersFromMatch({
required String matchId,
required List<Player> newPlayer,
}) async {
final currentPlayers = await getPlayersOfMatch(matchId: matchId);
// Create sets of player IDs for easy comparison
final currentPlayerIds = currentPlayers?.map((p) => p.id).toSet() ?? {};
final newPlayerIdsSet = newPlayer.map((p) => p.id).toSet();
// Determine players to add and remove
final playersToAdd = newPlayerIdsSet.difference(currentPlayerIds);
final playersToRemove = currentPlayerIds.difference(newPlayerIdsSet);
db.transaction(() async {
// Remove old players
if (playersToRemove.isNotEmpty) {
await (delete(playerMatchTable)..where(
(pg) =>
pg.matchId.equals(matchId) &
pg.playerId.isIn(playersToRemove.toList()),
))
.go();
}
// Add new players
if (playersToAdd.isNotEmpty) {
final inserts = playersToAdd
.map(
(id) => PlayerMatchTableCompanion.insert(
playerId: id,
matchId: matchId,
),
)
.toList();
await Future.wait(
inserts.map(
(c) => into(
playerMatchTable,
).insert(c, mode: InsertMode.insertOrIgnore),
),
);
}
});
}
}

View File

@@ -0,0 +1,11 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'player_match_dao.dart';
// ignore_for_file: type=lint
mixin _$PlayerMatchDaoMixin on DatabaseAccessor<AppDatabase> {
$PlayerTableTable get playerTable => attachedDatabase.playerTable;
$MatchTableTable get matchTable => attachedDatabase.matchTable;
$PlayerMatchTableTable get playerMatchTable =>
attachedDatabase.playerMatchTable;
}

60
lib/data/db/database.dart Normal file
View File

@@ -0,0 +1,60 @@
import 'package:drift/drift.dart';
import 'package:drift_flutter/drift_flutter.dart';
import 'package:game_tracker/data/dao/group_dao.dart';
import 'package:game_tracker/data/dao/group_match_dao.dart';
import 'package:game_tracker/data/dao/match_dao.dart';
import 'package:game_tracker/data/dao/player_dao.dart';
import 'package:game_tracker/data/dao/player_group_dao.dart';
import 'package:game_tracker/data/dao/player_match_dao.dart';
import 'package:game_tracker/data/db/tables/group_match_table.dart';
import 'package:game_tracker/data/db/tables/group_table.dart';
import 'package:game_tracker/data/db/tables/match_table.dart';
import 'package:game_tracker/data/db/tables/player_group_table.dart';
import 'package:game_tracker/data/db/tables/player_match_table.dart';
import 'package:game_tracker/data/db/tables/player_table.dart';
import 'package:path_provider/path_provider.dart';
part 'database.g.dart';
@DriftDatabase(
tables: [
PlayerTable,
GroupTable,
MatchTable,
PlayerGroupTable,
PlayerMatchTable,
GroupMatchTable,
],
daos: [
PlayerDao,
GroupDao,
MatchDao,
PlayerGroupDao,
PlayerMatchDao,
GroupMatchDao,
],
)
class AppDatabase extends _$AppDatabase {
AppDatabase([QueryExecutor? executor]) : super(executor ?? _openConnection());
@override
int get schemaVersion => 1;
@override
MigrationStrategy get migration {
return MigrationStrategy(
beforeOpen: (details) async {
await customStatement('PRAGMA foreign_keys = ON');
},
);
}
static QueryExecutor _openConnection() {
return driftDatabase(
name: 'gametracker_db',
native: const DriftNativeOptions(
databaseDirectory: getApplicationSupportDirectory,
),
);
}
}

3844
lib/data/db/database.g.dart Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,13 @@
import 'package:drift/drift.dart';
import 'package:game_tracker/data/db/tables/group_table.dart';
import 'package:game_tracker/data/db/tables/match_table.dart';
class GroupMatchTable extends Table {
TextColumn get groupId =>
text().references(GroupTable, #id, onDelete: KeyAction.cascade)();
TextColumn get matchId =>
text().references(MatchTable, #id, onDelete: KeyAction.cascade)();
@override
Set<Column<Object>> get primaryKey => {groupId, matchId};
}

View File

@@ -0,0 +1,10 @@
import 'package:drift/drift.dart';
class GroupTable extends Table {
TextColumn get id => text()();
TextColumn get name => text()();
DateTimeColumn get createdAt => dateTime()();
@override
Set<Column<Object>> get primaryKey => {id};
}

View File

@@ -0,0 +1,11 @@
import 'package:drift/drift.dart';
class MatchTable extends Table {
TextColumn get id => text()();
TextColumn get name => text()();
late final winnerId = text().nullable()();
DateTimeColumn get createdAt => dateTime()();
@override
Set<Column<Object>> get primaryKey => {id};
}

View File

@@ -0,0 +1,13 @@
import 'package:drift/drift.dart';
import 'package:game_tracker/data/db/tables/group_table.dart';
import 'package:game_tracker/data/db/tables/player_table.dart';
class PlayerGroupTable extends Table {
TextColumn get playerId =>
text().references(PlayerTable, #id, onDelete: KeyAction.cascade)();
TextColumn get groupId =>
text().references(GroupTable, #id, onDelete: KeyAction.cascade)();
@override
Set<Column<Object>> get primaryKey => {playerId, groupId};
}

View File

@@ -0,0 +1,13 @@
import 'package:drift/drift.dart';
import 'package:game_tracker/data/db/tables/match_table.dart';
import 'package:game_tracker/data/db/tables/player_table.dart';
class PlayerMatchTable extends Table {
TextColumn get playerId =>
text().references(PlayerTable, #id, onDelete: KeyAction.cascade)();
TextColumn get matchId =>
text().references(MatchTable, #id, onDelete: KeyAction.cascade)();
@override
Set<Column<Object>> get primaryKey => {playerId, matchId};
}

View File

@@ -0,0 +1,10 @@
import 'package:drift/drift.dart';
class PlayerTable extends Table {
TextColumn get id => text()();
TextColumn get name => text()();
DateTimeColumn get createdAt => dateTime()();
@override
Set<Column<Object>> get primaryKey => {id};
}

40
lib/data/dto/group.dart Normal file
View File

@@ -0,0 +1,40 @@
import 'package:clock/clock.dart';
import 'package:game_tracker/data/dto/player.dart';
import 'package:uuid/uuid.dart';
class Group {
final String id;
final DateTime createdAt;
final String name;
final List<Player> members;
Group({
String? id,
DateTime? createdAt,
required this.name,
required this.members,
}) : id = id ?? const Uuid().v4(),
createdAt = createdAt ?? clock.now();
@override
String toString() {
return 'Group{id: $id, name: $name,members: $members}';
}
/// Creates a Group instance from a JSON object.
Group.fromJson(Map<String, dynamic> json)
: id = json['id'],
createdAt = DateTime.parse(json['createdAt']),
name = json['name'],
members = (json['members'] as List)
.map((memberJson) => Player.fromJson(memberJson))
.toList();
/// Converts the Group instance to a JSON object.
Map<String, dynamic> toJson() => {
'id': id,
'createdAt': createdAt.toIso8601String(),
'name': name,
'members': members.map((member) => member.toJson()).toList(),
};
}

51
lib/data/dto/match.dart Normal file
View File

@@ -0,0 +1,51 @@
import 'package:clock/clock.dart';
import 'package:game_tracker/data/dto/group.dart';
import 'package:game_tracker/data/dto/player.dart';
import 'package:uuid/uuid.dart';
class Match {
final String id;
final DateTime createdAt;
final String name;
final List<Player>? players;
final Group? group;
Player? winner;
Match({
String? id,
DateTime? createdAt,
required this.name,
this.players,
this.group,
this.winner,
}) : id = id ?? const Uuid().v4(),
createdAt = createdAt ?? clock.now();
@override
String toString() {
return 'Match{\n\tid: $id,\n\tname: $name,\n\tplayers: $players,\n\tgroup: $group,\n\twinner: $winner\n}';
}
/// Creates a Match instance from a JSON object.
Match.fromJson(Map<String, dynamic> json)
: id = json['id'],
name = json['name'],
createdAt = DateTime.parse(json['createdAt']),
players = json['players'] != null
? (json['players'] as List)
.map((playerJson) => Player.fromJson(playerJson))
.toList()
: null,
group = json['group'] != null ? Group.fromJson(json['group']) : null,
winner = json['winner'] != null ? Player.fromJson(json['winner']) : null;
/// Converts the Match instance to a JSON object.
Map<String, dynamic> toJson() => {
'id': id,
'createdAt': createdAt.toIso8601String(),
'name': name,
'players': players?.map((player) => player.toJson()).toList(),
'group': group?.toJson(),
'winner': winner?.toJson(),
};
}

30
lib/data/dto/player.dart Normal file
View File

@@ -0,0 +1,30 @@
import 'package:clock/clock.dart';
import 'package:uuid/uuid.dart';
class Player {
final String id;
final DateTime createdAt;
final String name;
Player({String? id, DateTime? createdAt, required this.name})
: id = id ?? const Uuid().v4(),
createdAt = createdAt ?? clock.now();
@override
String toString() {
return 'Player{id: $id,name: $name}';
}
/// Creates a Player instance from a JSON object.
Player.fromJson(Map<String, dynamic> json)
: id = json['id'],
createdAt = DateTime.parse(json['createdAt']),
name = json['name'];
/// Converts the Player instance to a JSON object.
Map<String, dynamic> toJson() => {
'id': id,
'createdAt': createdAt.toIso8601String(),
'name': name,
};
}

83
lib/l10n/arb/app_de.arb Normal file
View File

@@ -0,0 +1,83 @@
{
"@@locale": "de",
"all_players": "Alle Spieler:innen",
"all_players_selected": "Alle Spieler:innen ausgewählt",
"amount_of_matches": "Anzahl der Spiele",
"cancel": "Abbrechen",
"choose_game": "Spielvorlage wählen",
"choose_group": "Gruppe wählen",
"choose_ruleset": "Regelwerk wählen",
"could_not_add_player": "Spieler:in {playerName} konnte nicht hinzugefügt werden",
"create_group": "Gruppe erstellen",
"create_match": "Spiel erstellen",
"create_new_group": "Neue Gruppe erstellen",
"create_new_match": "Neues Spiel erstellen",
"data_successfully_deleted": "Daten erfolgreich gelöscht",
"data_successfully_exported": "Daten erfolgreich exportiert",
"data_successfully_imported": "Daten erfolgreich importiert",
"days_ago": "vor {count} Tagen",
"delete": "Löschen",
"delete_all_data": "Alle Daten löschen",
"error_creating_group": "Fehler beim Erstellen der Gruppe, bitte erneut versuchen",
"error_reading_file": "Fehler beim Lesen der Datei",
"export_canceled": "Export abgebrochen",
"export_data": "Daten exportieren",
"format_exception": "Formatfehler (siehe Konsole)",
"game": "Spielvorlage",
"game_name": "Spielvorlagenname",
"group": "Gruppe",
"group_name": "Gruppenname",
"groups": "Gruppen",
"home": "Startseite",
"import_canceled": "Import abgebrochen",
"import_data": "Daten importieren",
"info": "Info",
"invalid_schema": "Ungültiges Schema",
"least_points": "Niedrigste Punkte",
"match_in_progress": "Spiel läuft...",
"match_name": "Spieltitel",
"matches": "Spiele",
"menu": "Menü",
"most_points": "Höchste Punkte",
"no_data_available": "Keine Daten verfügbar",
"no_groups_created_yet": "Noch keine Gruppen erstellt",
"no_matches_created_yet": "Noch keine Spiele erstellt",
"no_players_created_yet": "Noch keine Spieler:in erstellt",
"no_players_found_with_that_name": "Keine Spieler:in mit diesem Namen gefunden",
"no_players_selected": "Keine Spieler:innen ausgewählt",
"no_recent_matches_available": "Keine letzten Spiele verfügbar",
"no_second_match_available": "Kein zweites Spiel verfügbar",
"no_statistics_available": "Keine Statistiken verfügbar",
"none": "Kein",
"none_group": "Keine",
"not_available": "Nicht verfügbar",
"player_name": "Spieler:innenname",
"players": "Spieler:innen",
"players_count": "{count} Spieler",
"quick_create": "Schnellzugriff",
"recent_matches": "Letzte Spiele",
"ruleset": "Regelwerk",
"ruleset_least_points": "Umgekehrte Wertung: Der/die Spieler:in mit den wenigsten Punkten gewinnt.",
"ruleset_most_points": "Traditionelles Regelwerk: Der/die Spieler:in mit den meisten Punkten gewinnt.",
"ruleset_single_loser": "Genau ein:e Verlierer:in wird bestimmt; der letzte Platz erhält die Strafe oder Konsequenz.",
"ruleset_single_winner": "Genau ein:e Gewinner:in wird gewählt; Unentschieden werden durch einen vordefinierten Tie-Breaker aufgelöst.",
"search_for_groups": "Nach Gruppen suchen",
"search_for_players": "Nach Spieler:innen suchen",
"select_winner": "Gewinner:in wählen:",
"selected_players": "Ausgewählte Spieler:innen",
"settings": "Einstellungen",
"single_loser": "Ein:e Verlierer:in",
"single_winner": "Ein:e Gewinner:in",
"statistics": "Statistiken",
"stats": "Statistiken",
"successfully_added_player": "Spieler:in {playerName} erfolgreich hinzugefügt",
"there_is_no_group_matching_your_search": "Es gibt keine Gruppe, die deiner Suche entspricht",
"this_cannot_be_undone": "Dies kann nicht rückgängig gemacht werden",
"today_at": "Heute um",
"undo": "Rückgängig",
"unknown_exception": "Unbekannter Fehler (siehe Konsole)",
"winner": "Gewinner:in",
"winrate": "Siegquote",
"wins": "Siege",
"yesterday_at": "Gestern um"
}

343
lib/l10n/arb/app_en.arb Normal file
View File

@@ -0,0 +1,343 @@
{
"@@locale": "en",
"@all_players": {
"description": "Label for all players list"
},
"@all_players_selected": {
"description": "Message when all players are added to selection"
},
"@amount_of_matches": {
"description": "Label for amount of matches statistic"
},
"@app_name": {
"description": "The name of the App"
},
"@cancel": {
"description": "Cancel button text"
},
"@choose_game": {
"description": "Label for choosing a game"
},
"@choose_group": {
"description": "Label for choosing a group"
},
"@choose_ruleset": {
"description": "Label for choosing a ruleset"
},
"@could_not_add_player": {
"description": "Error message when adding a player fails"
},
"@create_group": {
"description": "Button text to create a group"
},
"@create_match": {
"description": "Button text to create a match"
},
"@create_new_group": {
"description": "Button text to create a new group"
},
"@create_new_match": {
"description": "Button text to create a new match"
},
"@data_successfully_deleted": {
"description": "Success message after deleting data"
},
"@data_successfully_exported": {
"description": "Success message after exporting data"
},
"@data_successfully_imported": {
"description": "Success message after importing data"
},
"@days_ago": {
"description": "Date format for days ago",
"placeholders": {
"count": {
"type": "int"
}
}
},
"@delete": {
"description": "Delete button text"
},
"@delete_all_data": {
"description": "Confirmation dialog for deleting all data"
},
"@error_creating_group": {
"description": "Error message when group creation fails"
},
"@error_reading_file": {
"description": "Error message when file cannot be read"
},
"@export_canceled": {
"description": "Message when export is canceled"
},
"@export_data": {
"description": "Export data menu item"
},
"@format_exception": {
"description": "Error message for format exceptions"
},
"@game": {
"description": "Game label"
},
"@game_name": {
"description": "Placeholder for game name search"
},
"@group": {
"description": "Group label"
},
"@group_name": {
"description": "Placeholder for group name input"
},
"@groups": {
"description": "Label for groups"
},
"@home": {
"description": "Home tab label"
},
"@import_canceled": {
"description": "Message when import is canceled"
},
"@import_data": {
"description": "Import data menu item"
},
"@info": {
"description": "Info label"
},
"@invalid_schema": {
"description": "Error message for invalid schema"
},
"@least_points": {
"description": "Title for least points ruleset"
},
"@match_in_progress": {
"description": "Message when match is in progress"
},
"@match_name": {
"description": "Placeholder for match name input"
},
"@matches": {
"description": "Label for matches"
},
"@menu": {
"description": "Menu label"
},
"@most_points": {
"description": "Title for most points ruleset"
},
"@no_data_available": {
"description": "Message when no data in the statistic tiles is given"
},
"@no_groups_created_yet": {
"description": "Message when no groups exist"
},
"@no_matches_created_yet": {
"description": "Message when no matches exist"
},
"@no_players_created_yet": {
"description": "Message when no players exist"
},
"@no_players_found_with_that_name": {
"description": "Message when search returns no results"
},
"@no_players_selected": {
"description": "Message when no players are selected"
},
"@no_recent_matches_available": {
"description": "Message when no recent matches exist"
},
"@no_second_match_available": {
"description": "Message when no second match exists"
},
"@no_statistics_available": {
"description": "Message when no statistics are available, because no matches were played yet"
},
"@none": {
"description": "None option label"
},
"@none_group": {
"description": "None group option label"
},
"@not_available": {
"description": "Abbreviation for not available"
},
"@player_name": {
"description": "Placeholder for player name input"
},
"@players": {
"description": "Players label"
},
"@players_count": {
"description": "Shows the number of players",
"placeholders": {
"count": {
"type": "int"
}
}
},
"@quick_create": {
"description": "Title for quick create section"
},
"@recent_matches": {
"description": "Title for recent matches section"
},
"@ruleset": {
"description": "Ruleset label"
},
"@ruleset_least_points": {
"description": "Description for least points ruleset"
},
"@ruleset_most_points": {
"description": "Description for most points ruleset"
},
"@ruleset_single_loser": {
"description": "Description for single loser ruleset"
},
"@ruleset_single_winner": {
"description": "Description for single winner ruleset"
},
"@search_for_groups": {
"description": "Hint text for group search input field"
},
"@search_for_players": {
"description": "Hint text for player search input field"
},
"@select_winner": {
"description": "Label to select the winner"
},
"@selected_players": {
"description": "Shows the number of selected players"
},
"@settings": {
"description": "Settings label"
},
"@single_loser": {
"description": "Title for single loser ruleset"
},
"@single_winner": {
"description": "Title for single winner ruleset"
},
"@statistics": {
"description": "Statistics tab label"
},
"@stats": {
"description": "Stats tab label (short)"
},
"@successfully_added_player": {
"description": "Success message when adding a player",
"placeholders": {
"playerName": {
"type": "String",
"example": "John"
}
}
},
"@there_is_no_group_matching_your_search": {
"description": "Message when search returns no groups"
},
"@this_cannot_be_undone": {
"description": "Warning message for irreversible actions"
},
"@today_at": {
"description": "Date format for today"
},
"@undo": {
"description": "Undo button text"
},
"@unknown_exception": {
"description": "Error message for unknown exceptions"
},
"@winner": {
"description": "Winner label"
},
"@winrate": {
"description": "Label for winrate statistic"
},
"@wins": {
"description": "Label for wins statistic"
},
"@yesterday_at": {
"description": "Date format for yesterday"
},
"all_players": "All players",
"all_players_selected": "All players selected",
"amount_of_matches": "Amount of Matches",
"app_name": "Game Tracker",
"cancel": "Cancel",
"choose_game": "Choose Game",
"choose_group": "Choose Group",
"choose_ruleset": "Choose Ruleset",
"could_not_add_player": "Could not add player",
"create_group": "Create Group",
"create_match": "Create match",
"create_new_group": "Create new group",
"create_new_match": "Create new match",
"data_successfully_deleted": "Data successfully deleted",
"data_successfully_exported": "Data successfully exported",
"data_successfully_imported": "Data successfully imported",
"days_ago": "{count} days ago",
"delete": "Delete",
"delete_all_data": "Delete all data",
"error_creating_group": "Error while creating group, please try again",
"error_reading_file": "Error reading file",
"export_canceled": "Export canceled",
"export_data": "Export data",
"format_exception": "Format Exception (see console)",
"game": "Game",
"game_name": "Game Name",
"group": "Group",
"group_name": "Group name",
"groups": "Groups",
"home": "Home",
"import_canceled": "Import canceled",
"import_data": "Import data",
"info": "Info",
"invalid_schema": "Invalid Schema",
"least_points": "Least Points",
"match_in_progress": "Match in progress...",
"match_name": "Match name",
"matches": "Matches",
"menu": "Menu",
"most_points": "Most Points",
"no_data_available": "No data available",
"no_groups_created_yet": "No groups created yet",
"no_matches_created_yet": "No matches created yet",
"no_players_created_yet": "No players created yet",
"no_players_found_with_that_name": "No players found with that name",
"no_players_selected": "No players selected",
"no_recent_matches_available": "No recent matches available",
"no_second_match_available": "No second match available",
"no_statistics_available": "No statistics available",
"none": "None",
"none_group": "None",
"not_available": "Not available",
"player_name": "Player name",
"players": "Players",
"players_count": "{count} Players",
"quick_create": "Quick Create",
"recent_matches": "Recent Matches",
"ruleset": "Ruleset",
"ruleset_least_points": "Inverse scoring: the player with the fewest points wins.",
"ruleset_most_points": "Traditional ruleset: the player with the most points wins.",
"ruleset_single_loser": "Exactly one loser is determined; last place receives the penalty or consequence.",
"ruleset_single_winner": "Exactly one winner is chosen; ties are resolved by a predefined tiebreaker.",
"search_for_groups": "Search for groups",
"search_for_players": "Search for players",
"select_winner": "Select Winner:",
"selected_players": "Selected players",
"settings": "Settings",
"single_loser": "Single Loser",
"single_winner": "Single Winner",
"statistics": "Statistics",
"stats": "Stats",
"successfully_added_player": "Successfully added player {playerName}",
"there_is_no_group_matching_your_search": "There is no group matching your search",
"this_cannot_be_undone": "This can't be undone",
"today_at": "Today at",
"undo": "Undo",
"unknown_exception": "Unknown Exception (see console)",
"winner": "Winner",
"winrate": "Winrate",
"wins": "Wins",
"yesterday_at": "Yesterday at"
}

View File

@@ -0,0 +1,620 @@
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart' as intl;
import 'app_localizations_de.dart';
import 'app_localizations_en.dart';
// ignore_for_file: type=lint
/// Callers can lookup localized strings with an instance of AppLocalizations
/// returned by `AppLocalizations.of(context)`.
///
/// Applications need to include `AppLocalizations.delegate()` in their app's
/// `localizationDelegates` list, and the locales they support in the app's
/// `supportedLocales` list. For example:
///
/// ```dart
/// import 'generated/app_localizations.dart';
///
/// return MaterialApp(
/// localizationsDelegates: AppLocalizations.localizationsDelegates,
/// supportedLocales: AppLocalizations.supportedLocales,
/// home: MyApplicationHome(),
/// );
/// ```
///
/// ## Update pubspec.yaml
///
/// Please make sure to update your pubspec.yaml to include the following
/// packages:
///
/// ```yaml
/// dependencies:
/// # Internationalization support.
/// flutter_localizations:
/// sdk: flutter
/// intl: any # Use the pinned version from flutter_localizations
///
/// # Rest of dependencies
/// ```
///
/// ## iOS Applications
///
/// iOS applications define key application metadata, including supported
/// locales, in an Info.plist file that is built into the application bundle.
/// To configure the locales supported by your app, youll need to edit this
/// file.
///
/// First, open your projects ios/Runner.xcworkspace Xcode workspace file.
/// Then, in the Project Navigator, open the Info.plist file under the Runner
/// projects Runner folder.
///
/// Next, select the Information Property List item, select Add Item from the
/// Editor menu, then select Localizations from the pop-up menu.
///
/// Select and expand the newly-created Localizations item then, for each
/// locale your application supports, add a new item and select the locale
/// you wish to add from the pop-up menu in the Value field. This list should
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
/// property.
abstract class AppLocalizations {
AppLocalizations(String locale)
: localeName = intl.Intl.canonicalizedLocale(locale.toString());
final String localeName;
static AppLocalizations of(BuildContext context) {
return Localizations.of<AppLocalizations>(context, AppLocalizations)!;
}
static const LocalizationsDelegate<AppLocalizations> delegate =
_AppLocalizationsDelegate();
/// A list of this localizations delegate along with the default localizations
/// delegates.
///
/// Returns a list of localizations delegates containing this delegate along with
/// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
/// and GlobalWidgetsLocalizations.delegate.
///
/// Additional delegates can be added by appending to this list in
/// MaterialApp. This list does not have to be used at all if a custom list
/// of delegates is preferred or required.
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =
<LocalizationsDelegate<dynamic>>[
delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
];
/// A list of this localizations delegate's supported locales.
static const List<Locale> supportedLocales = <Locale>[
Locale('de'),
Locale('en'),
];
/// Label for all players list
///
/// In en, this message translates to:
/// **'All players'**
String get all_players;
/// Message when all players are added to selection
///
/// In en, this message translates to:
/// **'All players selected'**
String get all_players_selected;
/// Label for amount of matches statistic
///
/// In en, this message translates to:
/// **'Amount of Matches'**
String get amount_of_matches;
/// The name of the App
///
/// In en, this message translates to:
/// **'Game Tracker'**
String get app_name;
/// Cancel button text
///
/// In en, this message translates to:
/// **'Cancel'**
String get cancel;
/// Label for choosing a game
///
/// In en, this message translates to:
/// **'Choose Game'**
String get choose_game;
/// Label for choosing a group
///
/// In en, this message translates to:
/// **'Choose Group'**
String get choose_group;
/// Label for choosing a ruleset
///
/// In en, this message translates to:
/// **'Choose Ruleset'**
String get choose_ruleset;
/// Error message when adding a player fails
///
/// In en, this message translates to:
/// **'Could not add player'**
String could_not_add_player(Object playerName);
/// Button text to create a group
///
/// In en, this message translates to:
/// **'Create Group'**
String get create_group;
/// Button text to create a match
///
/// In en, this message translates to:
/// **'Create match'**
String get create_match;
/// Button text to create a new group
///
/// In en, this message translates to:
/// **'Create new group'**
String get create_new_group;
/// Button text to create a new match
///
/// In en, this message translates to:
/// **'Create new match'**
String get create_new_match;
/// Success message after deleting data
///
/// In en, this message translates to:
/// **'Data successfully deleted'**
String get data_successfully_deleted;
/// Success message after exporting data
///
/// In en, this message translates to:
/// **'Data successfully exported'**
String get data_successfully_exported;
/// Success message after importing data
///
/// In en, this message translates to:
/// **'Data successfully imported'**
String get data_successfully_imported;
/// Date format for days ago
///
/// In en, this message translates to:
/// **'{count} days ago'**
String days_ago(int count);
/// Delete button text
///
/// In en, this message translates to:
/// **'Delete'**
String get delete;
/// Confirmation dialog for deleting all data
///
/// In en, this message translates to:
/// **'Delete all data'**
String get delete_all_data;
/// Error message when group creation fails
///
/// In en, this message translates to:
/// **'Error while creating group, please try again'**
String get error_creating_group;
/// Error message when file cannot be read
///
/// In en, this message translates to:
/// **'Error reading file'**
String get error_reading_file;
/// Message when export is canceled
///
/// In en, this message translates to:
/// **'Export canceled'**
String get export_canceled;
/// Export data menu item
///
/// In en, this message translates to:
/// **'Export data'**
String get export_data;
/// Error message for format exceptions
///
/// In en, this message translates to:
/// **'Format Exception (see console)'**
String get format_exception;
/// Game label
///
/// In en, this message translates to:
/// **'Game'**
String get game;
/// Placeholder for game name search
///
/// In en, this message translates to:
/// **'Game Name'**
String get game_name;
/// Group label
///
/// In en, this message translates to:
/// **'Group'**
String get group;
/// Placeholder for group name input
///
/// In en, this message translates to:
/// **'Group name'**
String get group_name;
/// Label for groups
///
/// In en, this message translates to:
/// **'Groups'**
String get groups;
/// Home tab label
///
/// In en, this message translates to:
/// **'Home'**
String get home;
/// Message when import is canceled
///
/// In en, this message translates to:
/// **'Import canceled'**
String get import_canceled;
/// Import data menu item
///
/// In en, this message translates to:
/// **'Import data'**
String get import_data;
/// Info label
///
/// In en, this message translates to:
/// **'Info'**
String get info;
/// Error message for invalid schema
///
/// In en, this message translates to:
/// **'Invalid Schema'**
String get invalid_schema;
/// Title for least points ruleset
///
/// In en, this message translates to:
/// **'Least Points'**
String get least_points;
/// Message when match is in progress
///
/// In en, this message translates to:
/// **'Match in progress...'**
String get match_in_progress;
/// Placeholder for match name input
///
/// In en, this message translates to:
/// **'Match name'**
String get match_name;
/// Label for matches
///
/// In en, this message translates to:
/// **'Matches'**
String get matches;
/// Menu label
///
/// In en, this message translates to:
/// **'Menu'**
String get menu;
/// Title for most points ruleset
///
/// In en, this message translates to:
/// **'Most Points'**
String get most_points;
/// Message when no data in the statistic tiles is given
///
/// In en, this message translates to:
/// **'No data available'**
String get no_data_available;
/// Message when no groups exist
///
/// In en, this message translates to:
/// **'No groups created yet'**
String get no_groups_created_yet;
/// Message when no matches exist
///
/// In en, this message translates to:
/// **'No matches created yet'**
String get no_matches_created_yet;
/// Message when no players exist
///
/// In en, this message translates to:
/// **'No players created yet'**
String get no_players_created_yet;
/// Message when search returns no results
///
/// In en, this message translates to:
/// **'No players found with that name'**
String get no_players_found_with_that_name;
/// Message when no players are selected
///
/// In en, this message translates to:
/// **'No players selected'**
String get no_players_selected;
/// Message when no recent matches exist
///
/// In en, this message translates to:
/// **'No recent matches available'**
String get no_recent_matches_available;
/// Message when no second match exists
///
/// In en, this message translates to:
/// **'No second match available'**
String get no_second_match_available;
/// Message when no statistics are available, because no matches were played yet
///
/// In en, this message translates to:
/// **'No statistics available'**
String get no_statistics_available;
/// None option label
///
/// In en, this message translates to:
/// **'None'**
String get none;
/// None group option label
///
/// In en, this message translates to:
/// **'None'**
String get none_group;
/// Abbreviation for not available
///
/// In en, this message translates to:
/// **'Not available'**
String get not_available;
/// Placeholder for player name input
///
/// In en, this message translates to:
/// **'Player name'**
String get player_name;
/// Players label
///
/// In en, this message translates to:
/// **'Players'**
String get players;
/// Shows the number of players
///
/// In en, this message translates to:
/// **'{count} Players'**
String players_count(int count);
/// Title for quick create section
///
/// In en, this message translates to:
/// **'Quick Create'**
String get quick_create;
/// Title for recent matches section
///
/// In en, this message translates to:
/// **'Recent Matches'**
String get recent_matches;
/// Ruleset label
///
/// In en, this message translates to:
/// **'Ruleset'**
String get ruleset;
/// Description for least points ruleset
///
/// In en, this message translates to:
/// **'Inverse scoring: the player with the fewest points wins.'**
String get ruleset_least_points;
/// Description for most points ruleset
///
/// In en, this message translates to:
/// **'Traditional ruleset: the player with the most points wins.'**
String get ruleset_most_points;
/// Description for single loser ruleset
///
/// In en, this message translates to:
/// **'Exactly one loser is determined; last place receives the penalty or consequence.'**
String get ruleset_single_loser;
/// Description for single winner ruleset
///
/// In en, this message translates to:
/// **'Exactly one winner is chosen; ties are resolved by a predefined tiebreaker.'**
String get ruleset_single_winner;
/// Hint text for group search input field
///
/// In en, this message translates to:
/// **'Search for groups'**
String get search_for_groups;
/// Hint text for player search input field
///
/// In en, this message translates to:
/// **'Search for players'**
String get search_for_players;
/// Label to select the winner
///
/// In en, this message translates to:
/// **'Select Winner:'**
String get select_winner;
/// Shows the number of selected players
///
/// In en, this message translates to:
/// **'Selected players'**
String get selected_players;
/// Settings label
///
/// In en, this message translates to:
/// **'Settings'**
String get settings;
/// Title for single loser ruleset
///
/// In en, this message translates to:
/// **'Single Loser'**
String get single_loser;
/// Title for single winner ruleset
///
/// In en, this message translates to:
/// **'Single Winner'**
String get single_winner;
/// Statistics tab label
///
/// In en, this message translates to:
/// **'Statistics'**
String get statistics;
/// Stats tab label (short)
///
/// In en, this message translates to:
/// **'Stats'**
String get stats;
/// Success message when adding a player
///
/// In en, this message translates to:
/// **'Successfully added player {playerName}'**
String successfully_added_player(String playerName);
/// Message when search returns no groups
///
/// In en, this message translates to:
/// **'There is no group matching your search'**
String get there_is_no_group_matching_your_search;
/// Warning message for irreversible actions
///
/// In en, this message translates to:
/// **'This can\'t be undone'**
String get this_cannot_be_undone;
/// Date format for today
///
/// In en, this message translates to:
/// **'Today at'**
String get today_at;
/// Undo button text
///
/// In en, this message translates to:
/// **'Undo'**
String get undo;
/// Error message for unknown exceptions
///
/// In en, this message translates to:
/// **'Unknown Exception (see console)'**
String get unknown_exception;
/// Winner label
///
/// In en, this message translates to:
/// **'Winner'**
String get winner;
/// Label for winrate statistic
///
/// In en, this message translates to:
/// **'Winrate'**
String get winrate;
/// Label for wins statistic
///
/// In en, this message translates to:
/// **'Wins'**
String get wins;
/// Date format for yesterday
///
/// In en, this message translates to:
/// **'Yesterday at'**
String get yesterday_at;
}
class _AppLocalizationsDelegate
extends LocalizationsDelegate<AppLocalizations> {
const _AppLocalizationsDelegate();
@override
Future<AppLocalizations> load(Locale locale) {
return SynchronousFuture<AppLocalizations>(lookupAppLocalizations(locale));
}
@override
bool isSupported(Locale locale) =>
<String>['de', 'en'].contains(locale.languageCode);
@override
bool shouldReload(_AppLocalizationsDelegate old) => false;
}
AppLocalizations lookupAppLocalizations(Locale locale) {
// Lookup logic when only language code is specified.
switch (locale.languageCode) {
case 'de':
return AppLocalizationsDe();
case 'en':
return AppLocalizationsEn();
}
throw FlutterError(
'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
'an issue with the localizations generation tool. Please file an issue '
'on GitHub with a reproducible sample app and the gen-l10n configuration '
'that was used.',
);
}

View File

@@ -0,0 +1,269 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for German (`de`).
class AppLocalizationsDe extends AppLocalizations {
AppLocalizationsDe([String locale = 'de']) : super(locale);
@override
String get all_players => 'Alle Spieler:innen';
@override
String get all_players_selected => 'Alle Spieler:innen ausgewählt';
@override
String get amount_of_matches => 'Anzahl der Spiele';
@override
String get app_name => 'Game Tracker';
@override
String get cancel => 'Abbrechen';
@override
String get choose_game => 'Spielvorlage wählen';
@override
String get choose_group => 'Gruppe wählen';
@override
String get choose_ruleset => 'Regelwerk wählen';
@override
String could_not_add_player(Object playerName) {
return 'Spieler:in $playerName konnte nicht hinzugefügt werden';
}
@override
String get create_group => 'Gruppe erstellen';
@override
String get create_match => 'Spiel erstellen';
@override
String get create_new_group => 'Neue Gruppe erstellen';
@override
String get create_new_match => 'Neues Spiel erstellen';
@override
String get data_successfully_deleted => 'Daten erfolgreich gelöscht';
@override
String get data_successfully_exported => 'Daten erfolgreich exportiert';
@override
String get data_successfully_imported => 'Daten erfolgreich importiert';
@override
String days_ago(int count) {
return 'vor $count Tagen';
}
@override
String get delete => 'Löschen';
@override
String get delete_all_data => 'Alle Daten löschen';
@override
String get error_creating_group =>
'Fehler beim Erstellen der Gruppe, bitte erneut versuchen';
@override
String get error_reading_file => 'Fehler beim Lesen der Datei';
@override
String get export_canceled => 'Export abgebrochen';
@override
String get export_data => 'Daten exportieren';
@override
String get format_exception => 'Formatfehler (siehe Konsole)';
@override
String get game => 'Spielvorlage';
@override
String get game_name => 'Spielvorlagenname';
@override
String get group => 'Gruppe';
@override
String get group_name => 'Gruppenname';
@override
String get groups => 'Gruppen';
@override
String get home => 'Startseite';
@override
String get import_canceled => 'Import abgebrochen';
@override
String get import_data => 'Daten importieren';
@override
String get info => 'Info';
@override
String get invalid_schema => 'Ungültiges Schema';
@override
String get least_points => 'Niedrigste Punkte';
@override
String get match_in_progress => 'Spiel läuft...';
@override
String get match_name => 'Spieltitel';
@override
String get matches => 'Spiele';
@override
String get menu => 'Menü';
@override
String get most_points => 'Höchste Punkte';
@override
String get no_data_available => 'Keine Daten verfügbar';
@override
String get no_groups_created_yet => 'Noch keine Gruppen erstellt';
@override
String get no_matches_created_yet => 'Noch keine Spiele erstellt';
@override
String get no_players_created_yet => 'Noch keine Spieler:in erstellt';
@override
String get no_players_found_with_that_name =>
'Keine Spieler:in mit diesem Namen gefunden';
@override
String get no_players_selected => 'Keine Spieler:innen ausgewählt';
@override
String get no_recent_matches_available => 'Keine letzten Spiele verfügbar';
@override
String get no_second_match_available => 'Kein zweites Spiel verfügbar';
@override
String get no_statistics_available => 'Keine Statistiken verfügbar';
@override
String get none => 'Kein';
@override
String get none_group => 'Keine';
@override
String get not_available => 'Nicht verfügbar';
@override
String get player_name => 'Spieler:innenname';
@override
String get players => 'Spieler:innen';
@override
String players_count(int count) {
return '$count Spieler';
}
@override
String get quick_create => 'Schnellzugriff';
@override
String get recent_matches => 'Letzte Spiele';
@override
String get ruleset => 'Regelwerk';
@override
String get ruleset_least_points =>
'Umgekehrte Wertung: Der/die Spieler:in mit den wenigsten Punkten gewinnt.';
@override
String get ruleset_most_points =>
'Traditionelles Regelwerk: Der/die Spieler:in mit den meisten Punkten gewinnt.';
@override
String get ruleset_single_loser =>
'Genau ein:e Verlierer:in wird bestimmt; der letzte Platz erhält die Strafe oder Konsequenz.';
@override
String get ruleset_single_winner =>
'Genau ein:e Gewinner:in wird gewählt; Unentschieden werden durch einen vordefinierten Tie-Breaker aufgelöst.';
@override
String get search_for_groups => 'Nach Gruppen suchen';
@override
String get search_for_players => 'Nach Spieler:innen suchen';
@override
String get select_winner => 'Gewinner:in wählen:';
@override
String get selected_players => 'Ausgewählte Spieler:innen';
@override
String get settings => 'Einstellungen';
@override
String get single_loser => 'Ein:e Verlierer:in';
@override
String get single_winner => 'Ein:e Gewinner:in';
@override
String get statistics => 'Statistiken';
@override
String get stats => 'Statistiken';
@override
String successfully_added_player(String playerName) {
return 'Spieler:in $playerName erfolgreich hinzugefügt';
}
@override
String get there_is_no_group_matching_your_search =>
'Es gibt keine Gruppe, die deiner Suche entspricht';
@override
String get this_cannot_be_undone =>
'Dies kann nicht rückgängig gemacht werden';
@override
String get today_at => 'Heute um';
@override
String get undo => 'Rückgängig';
@override
String get unknown_exception => 'Unbekannter Fehler (siehe Konsole)';
@override
String get winner => 'Gewinner:in';
@override
String get winrate => 'Siegquote';
@override
String get wins => 'Siege';
@override
String get yesterday_at => 'Gestern um';
}

View File

@@ -0,0 +1,268 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for English (`en`).
class AppLocalizationsEn extends AppLocalizations {
AppLocalizationsEn([String locale = 'en']) : super(locale);
@override
String get all_players => 'All players';
@override
String get all_players_selected => 'All players selected';
@override
String get amount_of_matches => 'Amount of Matches';
@override
String get app_name => 'Game Tracker';
@override
String get cancel => 'Cancel';
@override
String get choose_game => 'Choose Game';
@override
String get choose_group => 'Choose Group';
@override
String get choose_ruleset => 'Choose Ruleset';
@override
String could_not_add_player(Object playerName) {
return 'Could not add player';
}
@override
String get create_group => 'Create Group';
@override
String get create_match => 'Create match';
@override
String get create_new_group => 'Create new group';
@override
String get create_new_match => 'Create new match';
@override
String get data_successfully_deleted => 'Data successfully deleted';
@override
String get data_successfully_exported => 'Data successfully exported';
@override
String get data_successfully_imported => 'Data successfully imported';
@override
String days_ago(int count) {
return '$count days ago';
}
@override
String get delete => 'Delete';
@override
String get delete_all_data => 'Delete all data';
@override
String get error_creating_group =>
'Error while creating group, please try again';
@override
String get error_reading_file => 'Error reading file';
@override
String get export_canceled => 'Export canceled';
@override
String get export_data => 'Export data';
@override
String get format_exception => 'Format Exception (see console)';
@override
String get game => 'Game';
@override
String get game_name => 'Game Name';
@override
String get group => 'Group';
@override
String get group_name => 'Group name';
@override
String get groups => 'Groups';
@override
String get home => 'Home';
@override
String get import_canceled => 'Import canceled';
@override
String get import_data => 'Import data';
@override
String get info => 'Info';
@override
String get invalid_schema => 'Invalid Schema';
@override
String get least_points => 'Least Points';
@override
String get match_in_progress => 'Match in progress...';
@override
String get match_name => 'Match name';
@override
String get matches => 'Matches';
@override
String get menu => 'Menu';
@override
String get most_points => 'Most Points';
@override
String get no_data_available => 'No data available';
@override
String get no_groups_created_yet => 'No groups created yet';
@override
String get no_matches_created_yet => 'No matches created yet';
@override
String get no_players_created_yet => 'No players created yet';
@override
String get no_players_found_with_that_name =>
'No players found with that name';
@override
String get no_players_selected => 'No players selected';
@override
String get no_recent_matches_available => 'No recent matches available';
@override
String get no_second_match_available => 'No second match available';
@override
String get no_statistics_available => 'No statistics available';
@override
String get none => 'None';
@override
String get none_group => 'None';
@override
String get not_available => 'Not available';
@override
String get player_name => 'Player name';
@override
String get players => 'Players';
@override
String players_count(int count) {
return '$count Players';
}
@override
String get quick_create => 'Quick Create';
@override
String get recent_matches => 'Recent Matches';
@override
String get ruleset => 'Ruleset';
@override
String get ruleset_least_points =>
'Inverse scoring: the player with the fewest points wins.';
@override
String get ruleset_most_points =>
'Traditional ruleset: the player with the most points wins.';
@override
String get ruleset_single_loser =>
'Exactly one loser is determined; last place receives the penalty or consequence.';
@override
String get ruleset_single_winner =>
'Exactly one winner is chosen; ties are resolved by a predefined tiebreaker.';
@override
String get search_for_groups => 'Search for groups';
@override
String get search_for_players => 'Search for players';
@override
String get select_winner => 'Select Winner:';
@override
String get selected_players => 'Selected players';
@override
String get settings => 'Settings';
@override
String get single_loser => 'Single Loser';
@override
String get single_winner => 'Single Winner';
@override
String get statistics => 'Statistics';
@override
String get stats => 'Stats';
@override
String successfully_added_player(String playerName) {
return 'Successfully added player $playerName';
}
@override
String get there_is_no_group_matching_your_search =>
'There is no group matching your search';
@override
String get this_cannot_be_undone => 'This can\'t be undone';
@override
String get today_at => 'Today at';
@override
String get undo => 'Undo';
@override
String get unknown_exception => 'Unknown Exception (see console)';
@override
String get winner => 'Winner';
@override
String get winrate => 'Winrate';
@override
String get wins => 'Wins';
@override
String get yesterday_at => 'Yesterday at';
}

View File

@@ -1,21 +1,57 @@
import 'package:flutter/material.dart';
import 'package:game_tracker/presentation/views/home_view.dart';
import 'package:game_tracker/core/custom_theme.dart';
import 'package:game_tracker/data/db/database.dart';
import 'package:game_tracker/l10n/generated/app_localizations.dart';
import 'package:game_tracker/presentation/views/main_menu/custom_navigation_bar.dart';
import 'package:provider/provider.dart';
void main() {
runApp(const MyApp());
runApp(
Provider<AppDatabase>(
create: (context) => AppDatabase(),
child: const GameTracker(),
dispose: (context, db) => db.close(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
class GameTracker extends StatelessWidget {
const GameTracker({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Game Tracker',
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
localeResolutionCallback: (locale, supportedLocales) {
for (final supportedLocale in supportedLocales) {
if (supportedLocale.languageCode == locale?.languageCode) {
return supportedLocale;
}
}
return supportedLocales.firstWhere(
(locale) => locale.languageCode == 'en',
);
},
debugShowCheckedModeBanner: false,
onGenerateTitle: (context) => AppLocalizations.of(context).app_name,
themeMode: ThemeMode.dark, // forces dark mode
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
primaryColor: CustomTheme.primaryColor,
scaffoldBackgroundColor: CustomTheme.backgroundColor,
appBarTheme: CustomTheme.appBarTheme,
colorScheme: ColorScheme.fromSeed(
seedColor: CustomTheme.primaryColor,
brightness: Brightness.dark,
).copyWith(surface: CustomTheme.backgroundColor),
pageTransitionsTheme: const PageTransitionsTheme(
builders: {
TargetPlatform.iOS: CupertinoPageTransitionsBuilder(),
TargetPlatform.android: PredictiveBackPageTransitionsBuilder(),
},
),
home: const HomeView(),
),
home: const CustomNavigationBar(),
);
}
}

View File

@@ -1,10 +0,0 @@
import 'package:flutter/material.dart';
class HomeView extends StatelessWidget {
const HomeView({super.key});
@override
Widget build(BuildContext context) {
return const Placeholder();
}
}

View File

@@ -0,0 +1,195 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:game_tracker/core/adaptive_page_route.dart';
import 'package:game_tracker/core/custom_theme.dart';
import 'package:game_tracker/l10n/generated/app_localizations.dart';
import 'package:game_tracker/presentation/views/main_menu/group_view/groups_view.dart';
import 'package:game_tracker/presentation/views/main_menu/home_view.dart';
import 'package:game_tracker/presentation/views/main_menu/match_view/match_view.dart';
import 'package:game_tracker/presentation/views/main_menu/settings_view.dart';
import 'package:game_tracker/presentation/views/main_menu/statistics_view.dart';
import 'package:game_tracker/presentation/widgets/navbar_item.dart';
class CustomNavigationBar extends StatefulWidget {
const CustomNavigationBar({super.key});
@override
State<CustomNavigationBar> createState() => _CustomNavigationBarState();
}
class _CustomNavigationBarState extends State<CustomNavigationBar>
with SingleTickerProviderStateMixin {
/// Currently selected tab index
int currentIndex = 0;
/// Key count to force rebuild of tab views
int tabKeyCount = 0;
@override
Widget build(BuildContext context) {
final loc = AppLocalizations.of(context);
// Pretty ugly but works
final List<Widget> tabs = [
KeyedSubtree(key: ValueKey('home_$tabKeyCount'), child: const HomeView()),
KeyedSubtree(
key: ValueKey('matches_$tabKeyCount'),
child: const MatchView(),
),
KeyedSubtree(
key: ValueKey('groups_$tabKeyCount'),
child: const GroupsView(),
),
KeyedSubtree(
key: ValueKey('stats_$tabKeyCount'),
child: const StatisticsView(),
),
];
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(
_currentTabTitle(context),
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
backgroundColor: CustomTheme.backgroundColor,
scrolledUnderElevation: 0,
actions: [
IconButton(
onPressed: () async {
await Navigator.push(
context,
adaptivePageRoute(builder: (_) => const SettingsView()),
);
setState(() {
tabKeyCount++;
});
},
icon: const Icon(Icons.settings),
),
],
elevation: 0,
),
backgroundColor: CustomTheme.backgroundColor,
body: tabs[currentIndex],
extendBody: true,
bottomNavigationBar: SizedBox(
height: 70 + MediaQuery.of(context).padding.bottom,
child: Stack(
children: [
// Dynamisch generierte Blur-Layer für ultra-smooth Übergang
...List.generate(35, (index) {
// Verwende kubische Kurve für noch natürlicheren, weicheren Übergang
final progress = index / 34.0; // 0.0 bis 1.0
final cubic = progress * progress * progress; // Kubische Kurve
final blurStrength = 0.5 + (cubic * 50.0); // Sehr sanft von 0.5 bis 50.5
// Höhe geht jetzt komplett von 100% bis 0% (ganz nach unten)
// Mit extra Dichte am unteren Ende für weicheren Übergang
final heightFactor = index < 25
? 1.0 - (progress * 0.7) // Erste 25 Layer: 100% bis 30%
: 0.3 - ((index - 25) / 34.0); // Letzte 10 Layer: 30% bis 0% (dichter)
return Positioned(
left: 0,
right: 0,
bottom: 0,
height: (70 + MediaQuery.of(context).padding.bottom) * heightFactor.clamp(0.05, 1.0),
child: ClipRect(
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaX: blurStrength,
sigmaY: blurStrength,
),
child: Container(
color: Colors.transparent,
),
),
),
);
}),
// Gradient-Overlay
Positioned.fill(
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: [
CustomTheme.boxColor.withValues(alpha: 1),
CustomTheme.boxColor.withValues(alpha: 0.0),
],
stops: const [0.4, 1],
),
),
),
),
// Navbar-Inhalt
SafeArea(
child: SizedBox(
height: 70,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
NavbarItem(
index: 0,
isSelected: currentIndex == 0,
icon: Icons.home_rounded,
label: loc.home,
onTabTapped: onTabTapped,
),
NavbarItem(
index: 1,
isSelected: currentIndex == 1,
icon: Icons.gamepad_rounded,
label: loc.matches,
onTabTapped: onTabTapped,
),
NavbarItem(
index: 2,
isSelected: currentIndex == 2,
icon: Icons.group_rounded,
label: loc.groups,
onTabTapped: onTabTapped,
),
NavbarItem(
index: 3,
isSelected: currentIndex == 3,
icon: Icons.bar_chart_rounded,
label: loc.statistics,
onTabTapped: onTabTapped,
),
],
),
),
),
],
),
),
);
}
/// Handles tab tap events. Updates the current [index] state.
void onTabTapped(int index) {
setState(() {
currentIndex = index;
});
}
/// Returns the title of the current tab based on [currentIndex].
String _currentTabTitle(context) {
final loc = AppLocalizations.of(context);
switch (currentIndex) {
case 0:
return loc.home;
case 1:
return loc.matches;
case 2:
return loc.groups;
case 3:
return loc.statistics;
default:
return '';
}
}
}

View File

@@ -0,0 +1,113 @@
import 'package:flutter/material.dart';
import 'package:game_tracker/core/custom_theme.dart';
import 'package:game_tracker/core/enums.dart';
import 'package:game_tracker/data/db/database.dart';
import 'package:game_tracker/data/dto/group.dart';
import 'package:game_tracker/data/dto/player.dart';
import 'package:game_tracker/l10n/generated/app_localizations.dart';
import 'package:game_tracker/presentation/widgets/buttons/custom_width_button.dart';
import 'package:game_tracker/presentation/widgets/player_selection.dart';
import 'package:game_tracker/presentation/widgets/text_input/text_input_field.dart';
import 'package:provider/provider.dart';
class CreateGroupView extends StatefulWidget {
const CreateGroupView({super.key});
@override
State<CreateGroupView> createState() => _CreateGroupViewState();
}
class _CreateGroupViewState extends State<CreateGroupView> {
late final AppDatabase db;
/// Controller for the group name input field
final _groupNameController = TextEditingController();
/// List of currently selected players
List<Player> selectedPlayers = [];
@override
void initState() {
super.initState();
db = Provider.of<AppDatabase>(context, listen: false);
_groupNameController.addListener(() {
setState(() {});
});
}
@override
void dispose() {
_groupNameController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final loc = AppLocalizations.of(context);
return ScaffoldMessenger(
child: Scaffold(
backgroundColor: CustomTheme.backgroundColor,
appBar: AppBar(title: Text(loc.create_new_group)),
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
margin: CustomTheme.standardMargin,
child: TextInputField(
controller: _groupNameController,
hintText: loc.group_name,
),
),
Expanded(
child: PlayerSelection(
onChanged: (value) {
setState(() {
selectedPlayers = [...value];
});
},
),
),
CustomWidthButton(
text: loc.create_group,
sizeRelativeToWidth: 0.95,
buttonType: ButtonType.primary,
onPressed:
(_groupNameController.text.isEmpty ||
(selectedPlayers.length < 2))
? null
: () async {
bool success = await db.groupDao.addGroup(
group: Group(
name: _groupNameController.text.trim(),
members: selectedPlayers,
),
);
if (!context.mounted) return;
if (success) {
Navigator.pop(context);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: CustomTheme.boxColor,
content: Center(
child: Text(
AppLocalizations.of(
context,
).error_creating_group,
style: const TextStyle(color: Colors.white),
),
),
),
);
}
},
),
const SizedBox(height: 20),
],
),
),
),
);
}
}

View File

@@ -0,0 +1,123 @@
import 'package:flutter/material.dart';
import 'package:game_tracker/core/adaptive_page_route.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';
import 'package:game_tracker/data/dto/player.dart';
import 'package:game_tracker/l10n/generated/app_localizations.dart';
import 'package:game_tracker/presentation/views/main_menu/group_view/create_group_view.dart';
import 'package:game_tracker/presentation/widgets/app_skeleton.dart';
import 'package:game_tracker/presentation/widgets/buttons/custom_width_button.dart';
import 'package:game_tracker/presentation/widgets/tiles/group_tile.dart';
import 'package:game_tracker/presentation/widgets/top_centered_message.dart';
import 'package:provider/provider.dart';
class GroupsView extends StatefulWidget {
const GroupsView({super.key});
@override
State<GroupsView> createState() => _GroupsViewState();
}
class _GroupsViewState extends State<GroupsView> {
late final AppDatabase db;
/// Loaded groups from the database
late List<Group> loadedGroups;
/// Loading state
bool isLoading = true;
List<Group> groups = List.filled(
7,
Group(
name: 'Skeleton Group',
members: List.filled(6, Player(name: 'Skeleton Player')),
),
);
@override
void initState() {
super.initState();
db = Provider.of<AppDatabase>(context, listen: false);
loadGroups();
}
@override
Widget build(BuildContext context) {
final loc = AppLocalizations.of(context);
return Scaffold(
backgroundColor: CustomTheme.backgroundColor,
body: Stack(
alignment: Alignment.center,
children: [
AppSkeleton(
enabled: isLoading,
child: Visibility(
visible: groups.isNotEmpty,
replacement: Center(
child: TopCenteredMessage(
icon: Icons.info,
title: loc.info,
message: loc.no_groups_created_yet,
),
),
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(
bottom: MediaQuery.paddingOf(context).bottom,
child: CustomWidthButton(
text: loc.create_group,
sizeRelativeToWidth: 0.90,
onPressed: () async {
await Navigator.push(
context,
adaptivePageRoute(
builder: (context) {
return const CreateGroupView();
},
),
);
setState(() {
loadGroups();
});
},
),
),
],
),
);
}
void loadGroups() {
Future.wait([
db.groupDao.getAllGroups(),
Future.delayed(Constants.minimumSkeletonDuration),
]).then((results) {
loadedGroups = results[0] as List<Group>;
setState(() {
groups = loadedGroups
..sort((a, b) => b.createdAt.compareTo(a.createdAt));
});
if (mounted) {
setState(() {
isLoading = false;
});
}
});
}
}

View File

@@ -0,0 +1,225 @@
import 'package:flutter/material.dart';
import 'package:game_tracker/core/adaptive_page_route.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';
import 'package:game_tracker/data/dto/player.dart';
import 'package:game_tracker/l10n/generated/app_localizations.dart';
import 'package:game_tracker/presentation/views/main_menu/match_view/match_result_view.dart';
import 'package:game_tracker/presentation/widgets/app_skeleton.dart';
import 'package:game_tracker/presentation/widgets/buttons/quick_create_button.dart';
import 'package:game_tracker/presentation/widgets/tiles/info_tile.dart';
import 'package:game_tracker/presentation/widgets/tiles/match_tile.dart';
import 'package:game_tracker/presentation/widgets/tiles/quick_info_tile.dart';
import 'package:provider/provider.dart';
class HomeView extends StatefulWidget {
const HomeView({super.key});
@override
State<HomeView> createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
bool isLoading = true;
/// Amount of matches in the database
int matchCount = 0;
/// Amount of groups in the database
int groupCount = 0;
/// Loaded recent matches from the database
List<Match> loadedRecentMatches = [];
/// Recent matches to display, initially filled with skeleton matches
List<Match> recentMatches = List.filled(
2,
Match(
name: 'Skeleton Match',
group: Group(
name: 'Skeleton Group',
members: [
Player(name: 'Skeleton Player 1'),
Player(name: 'Skeleton Player 2'),
],
),
),
);
@override
void initState() {
super.initState();
loadHomeViewData();
}
@override
Widget build(BuildContext context) {
final loc = AppLocalizations.of(context);
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return AppSkeleton(
fixLayoutBuilder: true,
enabled: isLoading,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
QuickInfoTile(
width: constraints.maxWidth * 0.45,
height: constraints.maxHeight * 0.15,
title: loc.matches,
icon: Icons.groups_rounded,
value: matchCount,
),
SizedBox(width: constraints.maxWidth * 0.05),
QuickInfoTile(
width: constraints.maxWidth * 0.45,
height: constraints.maxHeight * 0.15,
title: loc.groups,
icon: Icons.groups_rounded,
value: groupCount,
),
],
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: InfoTile(
width: constraints.maxWidth * 0.95,
title: loc.recent_matches,
icon: Icons.history_rounded,
content: Column(
children: [
if (recentMatches.isNotEmpty)
for (Match match in recentMatches)
Padding(
padding: const EdgeInsets.symmetric(
vertical: 6.0,
),
child: MatchTile(
compact: true,
width: constraints.maxWidth * 0.9,
match: match,
onTap: () async {
await Navigator.of(context).push(
adaptivePageRoute(
fullscreenDialog: true,
builder: (context) =>
MatchResultView(match: match),
),
);
await updatedWinnerinRecentMatches(match.id);
},
),
)
else
Center(
heightFactor: 5,
child: Text(loc.no_recent_matches_available),
),
],
),
),
),
Padding(
padding: EdgeInsets.zero,
child: InfoTile(
width: constraints.maxWidth * 0.95,
title: loc.quick_create,
icon: Icons.add_box_rounded,
content: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
QuickCreateButton(
text: 'Category 1',
onPressed: () {},
),
QuickCreateButton(
text: 'Category 2',
onPressed: () {},
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
QuickCreateButton(
text: 'Category 3',
onPressed: () {},
),
QuickCreateButton(
text: 'Category 4',
onPressed: () {},
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
QuickCreateButton(
text: 'Category 5',
onPressed: () {},
),
QuickCreateButton(
text: 'Category 6',
onPressed: () {},
),
],
),
],
),
),
),
SizedBox(height: MediaQuery.paddingOf(context).bottom),
],
),
),
);
},
);
}
/// Loads the data for the HomeView from the database.
/// This includes the match count, group count, and recent matches.
Future<void> loadHomeViewData() async {
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 (mounted) {
setState(() {
isLoading = false;
});
}
});
}
/// Updates the winner information for a specific match in the recent matches list.
Future<void> updatedWinnerinRecentMatches(String matchId) async {
final db = Provider.of<AppDatabase>(context, listen: false);
final winner = await db.matchDao.getWinner(matchId: matchId);
final matchIndex = recentMatches.indexWhere((match) => match.id == matchId);
if (matchIndex != -1) {
setState(() {
recentMatches[matchIndex].winner = winner;
});
}
}
}

View File

@@ -0,0 +1,99 @@
import 'package:flutter/material.dart';
import 'package:game_tracker/core/custom_theme.dart';
import 'package:game_tracker/core/enums.dart';
import 'package:game_tracker/l10n/generated/app_localizations.dart';
import 'package:game_tracker/presentation/widgets/text_input/custom_search_bar.dart';
import 'package:game_tracker/presentation/widgets/tiles/title_description_list_tile.dart';
class ChooseGameView extends StatefulWidget {
final List<(String, String, Ruleset)> games;
final int initialGameIndex;
const ChooseGameView({
super.key,
required this.games,
required this.initialGameIndex,
});
@override
State<ChooseGameView> createState() => _ChooseGameViewState();
}
class _ChooseGameViewState extends State<ChooseGameView> {
/// Controller for the search bar
final TextEditingController searchBarController = TextEditingController();
/// Currently selected game index
late int selectedGameIndex;
@override
void initState() {
selectedGameIndex = widget.initialGameIndex;
super.initState();
}
@override
Widget build(BuildContext context) {
final loc = AppLocalizations.of(context);
return Scaffold(
backgroundColor: CustomTheme.backgroundColor,
appBar: AppBar(
leading: IconButton(
icon: const Icon(Icons.arrow_back_ios),
onPressed: () {
Navigator.of(context).pop(selectedGameIndex);
},
),
title: Text(loc.choose_game),
),
body: PopScope(
// This fixes that the Android Back Gesture didn't return the
// selectedGameIndex and therefore the selected Game wasn't saved
canPop: false,
onPopInvokedWithResult: (bool didPop, Object? result) {
if (didPop) {
return;
}
Navigator.of(context).pop(selectedGameIndex);
},
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: CustomSearchBar(
controller: searchBarController,
hintText: loc.game_name,
),
),
const SizedBox(height: 5),
Expanded(
child: ListView.builder(
itemCount: widget.games.length,
itemBuilder: (BuildContext context, int index) {
return TitleDescriptionListTile(
title: widget.games[index].$1,
description: widget.games[index].$2,
badgeText: translateRulesetToString(
widget.games[index].$3,
context,
),
isHighlighted: selectedGameIndex == index,
onPressed: () async {
setState(() {
if (selectedGameIndex == index) {
selectedGameIndex = -1;
} else {
selectedGameIndex = index;
}
});
},
);
},
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,153 @@
import 'package:flutter/material.dart';
import 'package:game_tracker/core/custom_theme.dart';
import 'package:game_tracker/data/dto/group.dart';
import 'package:game_tracker/l10n/generated/app_localizations.dart';
import 'package:game_tracker/presentation/widgets/text_input/custom_search_bar.dart';
import 'package:game_tracker/presentation/widgets/tiles/group_tile.dart';
import 'package:game_tracker/presentation/widgets/top_centered_message.dart';
class ChooseGroupView extends StatefulWidget {
final List<Group> groups;
final String initialGroupId;
const ChooseGroupView({
super.key,
required this.groups,
required this.initialGroupId,
});
@override
State<ChooseGroupView> createState() => _ChooseGroupViewState();
}
class _ChooseGroupViewState extends State<ChooseGroupView> {
late String selectedGroupId;
final TextEditingController controller = TextEditingController();
late final List<Group> filteredGroups;
@override
void initState() {
selectedGroupId = widget.initialGroupId;
filteredGroups = [...widget.groups];
super.initState();
}
@override
Widget build(BuildContext context) {
final loc = AppLocalizations.of(context);
return Scaffold(
backgroundColor: CustomTheme.backgroundColor,
appBar: AppBar(
leading: IconButton(
icon: const Icon(Icons.arrow_back_ios),
onPressed: () {
Navigator.of(context).pop(
selectedGroupId == ''
? null
: widget.groups.firstWhere(
(group) => group.id == selectedGroupId,
),
);
},
),
title: Text(loc.choose_group),
),
body: PopScope(
// This fixes that the Android Back Gesture didn't return the
// selectedGroupId and therefore the selected Group wasn't saved
canPop: false,
onPopInvokedWithResult: (bool didPop, Object? result) {
if (didPop) {
return;
}
Navigator.of(context).pop(
selectedGroupId == ''
? null
: widget.groups.firstWhere(
(group) => group.id == selectedGroupId,
),
);
},
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: CustomSearchBar(
controller: controller,
hintText: loc.search_for_groups,
onChanged: (value) {
setState(() {
filterGroups(value);
});
},
),
),
Expanded(
child: Visibility(
visible: filteredGroups.isNotEmpty,
replacement: Visibility(
visible: widget.groups.isNotEmpty,
replacement: TopCenteredMessage(
icon: Icons.info,
title: loc.info,
message: loc.no_groups_created_yet,
),
child: TopCenteredMessage(
icon: Icons.info,
title: loc.info,
message: AppLocalizations.of(
context,
).there_is_no_group_matching_your_search,
),
),
child: ListView.builder(
padding: const EdgeInsets.only(bottom: 85),
itemCount: filteredGroups.length,
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onTap: () {
setState(() {
if (selectedGroupId != filteredGroups[index].id) {
selectedGroupId = filteredGroups[index].id;
} else {
selectedGroupId = '';
}
});
},
child: GroupTile(
group: filteredGroups[index],
isHighlighted:
selectedGroupId == filteredGroups[index].id,
),
);
},
),
),
),
],
),
),
);
}
/// Filters the groups based on the search [query].
void filterGroups(String query) {
setState(() {
if (query.isEmpty) {
filteredGroups.clear();
filteredGroups.addAll(widget.groups);
} else {
filteredGroups.clear();
filteredGroups.addAll(
widget.groups.where(
(group) =>
group.name.toLowerCase().contains(query.toLowerCase()) ||
group.members.any(
(player) => player.name.toLowerCase().contains(query.toLowerCase()),
),
),
);
}
});
}
}

View File

@@ -0,0 +1,93 @@
import 'package:flutter/material.dart';
import 'package:game_tracker/core/custom_theme.dart';
import 'package:game_tracker/core/enums.dart';
import 'package:game_tracker/l10n/generated/app_localizations.dart';
import 'package:game_tracker/presentation/widgets/tiles/title_description_list_tile.dart';
class ChooseRulesetView extends StatefulWidget {
final List<(Ruleset, String)> rulesets;
final int initialRulesetIndex;
const ChooseRulesetView({
super.key,
required this.rulesets,
required this.initialRulesetIndex,
});
@override
State<ChooseRulesetView> createState() => _ChooseRulesetViewState();
}
class _ChooseRulesetViewState extends State<ChooseRulesetView> {
/// Currently selected ruleset index
late int selectedRulesetIndex;
@override
void initState() {
selectedRulesetIndex = widget.initialRulesetIndex;
super.initState();
}
@override
Widget build(BuildContext context) {
final loc = AppLocalizations.of(context);
return DefaultTabController(
length: 2,
initialIndex: 0,
child: Scaffold(
backgroundColor: CustomTheme.backgroundColor,
appBar: AppBar(
leading: IconButton(
icon: const Icon(Icons.arrow_back_ios),
onPressed: () {
Navigator.of(context).pop(
selectedRulesetIndex == -1
? null
: widget.rulesets[selectedRulesetIndex].$1,
);
},
),
title: Text(loc.choose_ruleset),
),
body: PopScope(
// This fixes that the Android Back Gesture didn't return the
// selectedRulesetIndex and therefore the selected Ruleset wasn't saved
canPop: false,
onPopInvokedWithResult: (bool didPop, Object? result) {
if (didPop) {
return;
}
Navigator.of(context).pop(
selectedRulesetIndex == -1
? null
: widget.rulesets[selectedRulesetIndex].$1,
);
},
child: ListView.builder(
padding: const EdgeInsets.only(bottom: 85),
itemCount: widget.rulesets.length,
itemBuilder: (BuildContext context, int index) {
return TitleDescriptionListTile(
onPressed: () async {
setState(() {
if (selectedRulesetIndex == index) {
selectedRulesetIndex = -1;
} else {
selectedRulesetIndex = index;
}
});
},
title: translateRulesetToString(
widget.rulesets[index].$1,
context,
),
description: widget.rulesets[index].$2,
isHighlighted: selectedRulesetIndex == index,
);
},
),
),
),
);
}
}

Some files were not shown because too many files have changed in this diff Show More