diff --git a/lib/src/provider/events.dart b/lib/src/provider/events.dart index 6487dc6..960a7ea 100644 --- a/lib/src/provider/events.dart +++ b/lib/src/provider/events.dart @@ -3,6 +3,7 @@ import 'dart:ui'; import 'package:dio/dio.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:json_annotation/json_annotation.dart'; +import 'package:steamwar_multitool/src/provider/types.dart'; import 'http.dart'; @@ -69,8 +70,15 @@ class EventRepository { await _client.delete("/fights/$id"); } - Future createFight(int eventId, DateTime start, String mode, String map, - Team blue, Team red) { + Future createFight( + int eventId, + DateTime start, + String mode, + String map, + Team blue, + Team red, + int referee, + ) { return _client.post("/fights", data: { "event": eventId, "spielmodus": mode, @@ -78,6 +86,7 @@ class EventRepository { "start": start.millisecondsSinceEpoch, "blueTeam": blue.id, "redTeam": red.id, + "kampfleiter": referee, }); } @@ -86,13 +95,15 @@ class EventRepository { return (res.data as List).map((e) => EventFight.fromJson(e)).toList(); } - Future updateFight( - int id, DateTime start, String mode, String map, int referee) { + Future updateFight(int id, DateTime start, String mode, String map, + int referee, Team blue, Team red) { return _client.put("/fights/$id", data: { "spielmodus": mode, "map": map, "start": start.millisecondsSinceEpoch, "kampfleiter": referee, + "blueTeam": blue.id, + "redTeam": red.id, }); } } @@ -104,11 +115,11 @@ class EventFight { final DateTime start; final Team redTeam; final Team blueTeam; - final int fightLeaderId; + final User kampfleiter; final int score; EventFight(this.id, this.gameMode, this.map, this.start, this.redTeam, - this.blueTeam, this.fightLeaderId, this.score); + this.blueTeam, this.kampfleiter, this.score); Team get winner { switch (score) { @@ -131,7 +142,7 @@ class EventFight { DateTime.fromMillisecondsSinceEpoch(json["start"]), Team.fromJson(json["redTeam"]), Team.fromJson(json["blueTeam"]), - json["kampfleiter"], + User.fromJson(json["kampfleiter"]), json["ergebnis"]); } } diff --git a/lib/src/provider/http.dart b/lib/src/provider/http.dart index b587983..a9dc1c4 100644 --- a/lib/src/provider/http.dart +++ b/lib/src/provider/http.dart @@ -21,8 +21,3 @@ final httpClient = FutureProvider( contentType: "application/json", )), ); - -final test = FutureProvider((ref) async { - final client = await ref.watch(httpClient.future); - await client.get("/data"); -}); diff --git a/lib/src/screens/event.dart b/lib/src/screens/event.dart index 8c62862..6d3a827 100644 --- a/lib/src/screens/event.dart +++ b/lib/src/screens/event.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:steamwar_multitool/src/provider/user.dart'; import '../provider/events.dart'; import '../provider/types.dart'; @@ -182,6 +183,7 @@ class _EventScreen extends HookConsumerWidget { padding: const EdgeInsets.all(8.0), child: ListView( children: [ + const SizedBox(height: 8), TextField( controller: nameController, decoration: const InputDecoration( @@ -343,24 +345,26 @@ class _EventFightList extends HookConsumerWidget { fights.value = await repo.listFights(event.id); } - return ListView( - shrinkWrap: true, + return Column( children: [ const SizedBox(height: 8), - FloatingActionButton.extended( - onPressed: () { - showDialog( - context: context, - builder: (context) { - return _AddFightWidget( - eventData, - () => update(), - ); - }, - ); - }, - label: const Text("Add Fight"), - icon: const Icon(Icons.add), + SizedBox( + width: double.infinity, + child: FloatingActionButton.extended( + onPressed: () { + showDialog( + context: context, + builder: (context) { + return _AddFightWidget( + eventData, + () => update(), + ); + }, + ); + }, + label: const Text("Add Fight"), + icon: const Icon(Icons.add), + ), ), const SizedBox(height: 8), for (final fight in fights.value) @@ -385,10 +389,14 @@ class _EventFightList extends HookConsumerWidget { context: context, builder: (context) { return EditEventFightDialog( - fight: fight, fightsRefresher: () => update()); + fight: fight, + fightsRefresher: () => update(), + event: eventData, + ); }); }, - tileColor: fight.score != 0 ? fight.winner.color : null, + tileColor: + fight.score != 0 ? fight.winner.color.withOpacity(0.5) : null, ) ], ); @@ -396,27 +404,41 @@ class _EventFightList extends HookConsumerWidget { } class EditEventFightDialog extends HookConsumerWidget { - const EditEventFightDialog({ - Key? key, - required this.fight, - required this.fightsRefresher, - }) : super(key: key); + const EditEventFightDialog( + {Key? key, + required this.fight, + required this.fightsRefresher, + required this.event}) + : super(key: key); final EventFight fight; + final EventExtended event; final void Function() fightsRefresher; @override Widget build(BuildContext context, WidgetRef ref) { + final blueTeam = useState(fight.blueTeam); + final redTeam = useState(fight.redTeam); final start = useState(fight.start); final mode = useState(fight.gameMode); final map = useState(fight.map); - final referrer = useState(fight.fightLeaderId); + final referrer = useState(fight.kampfleiter); return AlertDialog( title: Text("${fight.blueTeam.name} vs ${fight.redTeam.name}"), content: Column( mainAxisSize: MainAxisSize.min, children: [ + const SizedBox(height: 8), + const Text("Blue Team"), + _TeamSelector(event.event, blueTeam.value, (p0) { + blueTeam.value = p0; + }, event.teams), + const SizedBox(height: 8), + const Text("Red Team"), + _TeamSelector(event.event, redTeam.value, (p0) { + redTeam.value = p0; + }, event.teams), const SizedBox(height: 8), const Text("Start"), const SizedBox(height: 8), @@ -469,12 +491,13 @@ class EditEventFightDialog extends HookConsumerWidget { final user = await showSearch( context: context, delegate: UserSearchDelegate(users)); if (user != null) { - referrer.value = user.id; + referrer.value = user; fightsRefresher(); } }, - child: - Text(referrer.value == 0 ? "None" : referrer.value.toString()), + child: Text(referrer.value.id == 0 + ? "None" + : "${referrer.value.name} (${referrer.value!.id})"), ), ], ), @@ -518,8 +541,8 @@ class EditEventFightDialog extends HookConsumerWidget { onPressed: () async { var nav = Navigator.of(context); final repo = await ref.read(eventRepositoryProvider.future); - await repo.updateFight( - fight.id, start.value, mode.value, map.value, referrer.value); + await repo.updateFight(fight.id, start.value, mode.value, + map.value, referrer.value.id, blueTeam.value, redTeam.value); fightsRefresher(); nav.pop(); }, @@ -546,6 +569,7 @@ class _AddFightWidget extends HookConsumerWidget { final blueTeam = useState(null); final redTeam = useState(null); final date = useState(event.start); + final referrer = useState(null); final canCreate = useMemoized(() { return gamemode.value != null && @@ -599,6 +623,22 @@ class _AddFightWidget extends HookConsumerWidget { eventData.teams), const SizedBox(height: 8), DateTimeEditor((p0) => date.value = p0, date.value, true), + const SizedBox(height: 8), + const Text("Kampfleiter"), + const SizedBox(height: 8), + TextButton( + onPressed: () async { + final users = await ref.read(usersProvider.future); + final user = await showSearch( + context: context, delegate: UserSearchDelegate(users)); + if (user != null) { + referrer.value = user; + } + }, + child: Text(referrer.value == null || referrer.value!.id == 0 + ? "None" + : "${referrer.value!.name} (${referrer.value!.id})"), + ), ], ), actions: [ @@ -618,7 +658,8 @@ class _AddFightWidget extends HookConsumerWidget { gamemode.value!, map.value!, blueTeam.value!, - redTeam.value!); + redTeam.value!, + referrer.value?.id ?? 0); onAdded.call(); nav.pop(); } diff --git a/lib/src/screens/home.dart b/lib/src/screens/home.dart index 5c4ca4b..f249fc8 100644 --- a/lib/src/screens/home.dart +++ b/lib/src/screens/home.dart @@ -45,7 +45,7 @@ class HomeScreen extends HookConsumerWidget { onPressed: servers.isLoading ? null : () { - ref.refresh(eventsListProvider); + ref.invalidate(eventsListProvider); }, icon: const Icon(Icons.refresh), ), @@ -67,7 +67,7 @@ class HomeScreen extends HookConsumerWidget { final nav = Navigator.of(context); final prefs = await SharedPreferences.getInstance(); await prefs.remove("key"); - ref.refresh(userDataProvider); + ref.invalidate(userDataProvider); nav.pop(); context.go('/login'); }, @@ -99,7 +99,7 @@ class HomeScreen extends HookConsumerWidget { trailing: IconButton( icon: const Icon(Icons.person), onPressed: () { - Navigator.pushNamed(context, "/settings"); + context.go('/settings'); }, ), selectedIndex: navRailIndex.value, diff --git a/lib/src/screens/search_delegates.dart b/lib/src/screens/search_delegates.dart index 68628d8..4513afd 100644 --- a/lib/src/screens/search_delegates.dart +++ b/lib/src/screens/search_delegates.dart @@ -277,6 +277,12 @@ class TeamSearchDelegate extends SearchDelegate { Widget buildResults(BuildContext context) { return ListView( children: [ + ListTile( + title: const Text("?"), + onTap: () { + close(context, Team(-1, "?", "?", "8")); + }, + ), for (final team in teams) if (team.name.toLowerCase().contains(query.toLowerCase())) ListTile( @@ -293,6 +299,12 @@ class TeamSearchDelegate extends SearchDelegate { Widget buildSuggestions(BuildContext context) { return ListView( children: [ + ListTile( + title: const Text("?"), + onTap: () { + close(context, Team(-1, "?", "?", "8")); + }, + ), for (final team in teams) if (team.name.toLowerCase().contains(query.toLowerCase())) ListTile(