Update Edit Event State Backend
Dieser Commit ist enthalten in:
Ursprung
89d1e1d5b5
Commit
a2649c6a28
@ -31,3 +31,10 @@ final eventsListProvider = FutureProvider<List<ShortEvent>>((ref) async {
|
|||||||
final repo = await ref.watch(eventRepositoryProvider.future);
|
final repo = await ref.watch(eventRepositoryProvider.future);
|
||||||
return repo.listEvents();
|
return repo.listEvents();
|
||||||
}, dependencies: [eventRepositoryProvider]);
|
}, dependencies: [eventRepositoryProvider]);
|
||||||
|
|
||||||
|
final eventFutureProvider =
|
||||||
|
FutureProvider.family.autoDispose<EventExtended, int>((ref, id) async {
|
||||||
|
return ref
|
||||||
|
.watch(eventRepositoryProvider.future)
|
||||||
|
.then((value) => value.getEvent(id));
|
||||||
|
});
|
||||||
|
@ -26,57 +26,24 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||||||
import 'package:steamwar_multitool/src/components/components.dart';
|
import 'package:steamwar_multitool/src/components/components.dart';
|
||||||
import 'package:steamwar_multitool/src/components/date_time_editor.dart';
|
import 'package:steamwar_multitool/src/components/date_time_editor.dart';
|
||||||
import 'package:steamwar_multitool/src/provider/provider.dart';
|
import 'package:steamwar_multitool/src/provider/provider.dart';
|
||||||
import 'package:steamwar_multitool/src/screens/event/components/fight_list.dart';
|
import 'package:steamwar_multitool/src/screens/event/components/tabs/edit_event.dart';
|
||||||
import 'package:steamwar_multitool/src/screens/event/components/team_list.dart';
|
import 'package:steamwar_multitool/src/screens/event/components/tabs/fight_list.dart';
|
||||||
|
import 'package:steamwar_multitool/src/screens/event/components/tabs/team_list.dart';
|
||||||
import 'package:steamwar_multitool/src/screens/event/event.dart';
|
import 'package:steamwar_multitool/src/screens/event/event.dart';
|
||||||
import 'package:steamwar_multitool/src/delegates/delegates.dart';
|
import 'package:steamwar_multitool/src/delegates/delegates.dart';
|
||||||
|
import 'package:steamwar_multitool/src/screens/event/state/event.dart';
|
||||||
import 'package:steamwar_multitool/src/types/types.dart';
|
import 'package:steamwar_multitool/src/types/types.dart';
|
||||||
|
|
||||||
class LoadedEventScreen extends HookConsumerWidget {
|
class LoadedEventScreen extends HookConsumerWidget {
|
||||||
const LoadedEventScreen({Key? key, required this.eventData})
|
const LoadedEventScreen({Key? key}) : super(key: key);
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
final EventExtended eventData;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final eventData = ref.watch(eventProvider);
|
||||||
final event = eventData.event;
|
final event = eventData.event;
|
||||||
|
|
||||||
final nameController = useTextEditingController(text: event.name);
|
|
||||||
final deadlineState = useState(event.deadline);
|
|
||||||
final startDateState = useState(event.start);
|
|
||||||
final endDateState = useState(event.end);
|
|
||||||
final maxTeamMembersState = useState(event.maxTeamMembers);
|
|
||||||
final maxTeamMembersController =
|
|
||||||
useTextEditingController(text: event.maxTeamMembers.toString());
|
|
||||||
final invalidMaxTeamMembers = useState(false);
|
|
||||||
final schematicTypeState = useState<SchematicType?>(null);
|
|
||||||
final publicOnlyState = useState(event.publicSchemsOnly);
|
|
||||||
final spectateSystemState = useState(event.spectateSystem);
|
|
||||||
final tabController = useTabController(initialLength: 3);
|
final tabController = useTabController(initialLength: 3);
|
||||||
|
|
||||||
useMemoized(() async {
|
|
||||||
schematicTypeState.value = await ref
|
|
||||||
.read(schematicTypesProvider.future)
|
|
||||||
.then((value) => catchToNull(() =>
|
|
||||||
value.firstWhere((element) => element.db == event.schemType)));
|
|
||||||
});
|
|
||||||
|
|
||||||
final fightCount = useMemoized(() {
|
|
||||||
Map<int, int> fightCount = {};
|
|
||||||
for (var team in eventData.teams) {
|
|
||||||
fightCount[team.id] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var fight in eventData.fights) {
|
|
||||||
fightCount[fight.blueTeam.id] =
|
|
||||||
(fightCount[fight.blueTeam.id] ?? 0) + 1;
|
|
||||||
fightCount[fight.redTeam.id] = (fightCount[fight.redTeam.id] ?? 0) + 1;
|
|
||||||
}
|
|
||||||
return fightCount;
|
|
||||||
}, [eventData.fights, eventData.teams]);
|
|
||||||
|
|
||||||
final changed = useState(false);
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text("${"Edit"} ${event.name}"),
|
title: Text("${"Edit"} ${event.name}"),
|
||||||
@ -113,20 +80,20 @@ class LoadedEventScreen extends HookConsumerWidget {
|
|||||||
icon: const Icon(Icons.delete_outline, color: Colors.red),
|
icon: const Icon(Icons.delete_outline, color: Colors.red),
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: changed.value
|
onPressed: ref.watch(changedProvider)
|
||||||
? () {
|
? () {
|
||||||
ref
|
ref
|
||||||
.read(eventRepositoryProvider.future)
|
.read(eventRepositoryProvider.future)
|
||||||
.then((value) => value.updateEvent(
|
.then((value) => value.updateEvent(
|
||||||
event.id,
|
event.id,
|
||||||
nameController.text,
|
ref.read(eventNameProvider),
|
||||||
deadlineState.value,
|
ref.read(eventDeadlineProvider),
|
||||||
startDateState.value,
|
ref.read(eventStartProvider),
|
||||||
endDateState.value,
|
ref.read(eventEndProvider),
|
||||||
maxTeamMembersState.value,
|
ref.read(maxTeamSizeProvider),
|
||||||
schematicTypeState.value?.db,
|
ref.read(schematicTypeProvider),
|
||||||
publicOnlyState.value,
|
ref.read(publicOnlyProvider),
|
||||||
spectateSystemState.value,
|
ref.read(spectateSystemProvider),
|
||||||
))
|
))
|
||||||
.whenComplete(
|
.whenComplete(
|
||||||
() => ref.invalidate(eventsListProvider));
|
() => ref.invalidate(eventsListProvider));
|
||||||
@ -138,7 +105,7 @@ class LoadedEventScreen extends HookConsumerWidget {
|
|||||||
leading: BackButton(
|
leading: BackButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
var canPop = false;
|
var canPop = false;
|
||||||
if (changed.value) {
|
if (ref.read(changedProvider)) {
|
||||||
final accepted = await showDialog(
|
final accepted = await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
@ -181,171 +148,10 @@ class LoadedEventScreen extends HookConsumerWidget {
|
|||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: TabBarView(
|
child: TabBarView(
|
||||||
controller: tabController,
|
controller: tabController,
|
||||||
children: [
|
children: const [
|
||||||
ListView(
|
EditEventTab(),
|
||||||
shrinkWrap: true,
|
TeamList(),
|
||||||
children: [
|
EventFightList(),
|
||||||
const SizedBox(height: 8),
|
|
||||||
TextField(
|
|
||||||
controller: nameController,
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
labelText: "Name",
|
|
||||||
border: OutlineInputBorder(),
|
|
||||||
),
|
|
||||||
onChanged: (value) {
|
|
||||||
changed.value = true;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
Wrap(
|
|
||||||
alignment: WrapAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
const Tooltip(
|
|
||||||
message: "Deadline",
|
|
||||||
child: Icon(Icons.block),
|
|
||||||
),
|
|
||||||
DateTimeEditor((p0) {
|
|
||||||
deadlineState.value = p0;
|
|
||||||
changed.value = true;
|
|
||||||
}, deadlineState.value, true),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
const Tooltip(
|
|
||||||
message: "Start",
|
|
||||||
child: Icon(Icons.swipe_right_alt),
|
|
||||||
),
|
|
||||||
DateTimeEditor((p0) {
|
|
||||||
startDateState.value = p0;
|
|
||||||
changed.value = true;
|
|
||||||
}, startDateState.value, true),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
const Tooltip(
|
|
||||||
message: "End",
|
|
||||||
child: Icon(Icons.swipe_left_alt),
|
|
||||||
),
|
|
||||||
DateTimeEditor((p0) {
|
|
||||||
endDateState.value = p0;
|
|
||||||
changed.value = true;
|
|
||||||
}, endDateState.value, true),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
SizedBox(
|
|
||||||
width: 150,
|
|
||||||
child: TextField(
|
|
||||||
controller: maxTeamMembersController,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
labelText: "Max Team Members",
|
|
||||||
border: const OutlineInputBorder(),
|
|
||||||
errorText: invalidMaxTeamMembers.value
|
|
||||||
? "Must be a number above 0"
|
|
||||||
: null),
|
|
||||||
keyboardType: TextInputType.number,
|
|
||||||
onChanged: (value) {
|
|
||||||
if (value.isEmpty ||
|
|
||||||
int.tryParse(value) == null ||
|
|
||||||
int.parse(value) <= 0) {
|
|
||||||
invalidMaxTeamMembers.value = true;
|
|
||||||
} else {
|
|
||||||
invalidMaxTeamMembers.value = false;
|
|
||||||
maxTeamMembersState.value = int.parse(value);
|
|
||||||
changed.value = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Slider(
|
|
||||||
value: maxTeamMembersState.value.toDouble(),
|
|
||||||
onChanged: (p0) {
|
|
||||||
maxTeamMembersState.value = p0.toInt();
|
|
||||||
maxTeamMembersController.text =
|
|
||||||
p0.toInt().toString();
|
|
||||||
changed.value = true;
|
|
||||||
},
|
|
||||||
min: min(1, maxTeamMembersState.value.toDouble()),
|
|
||||||
max:
|
|
||||||
max(30, maxTeamMembersState.value.toDouble()),
|
|
||||||
divisions:
|
|
||||||
max(30, maxTeamMembersState.value.toDouble())
|
|
||||||
.toInt() -
|
|
||||||
1,
|
|
||||||
label: maxTeamMembersState.value.toString(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
ref.read(schematicTypesProvider).when(
|
|
||||||
data: (data) {
|
|
||||||
return DropdownMenu(
|
|
||||||
dropdownMenuEntries: [
|
|
||||||
const DropdownMenuEntry(value: null, label: ""),
|
|
||||||
if (schematicTypeState.value != null &&
|
|
||||||
!data.contains(schematicTypeState.value))
|
|
||||||
DropdownMenuEntry(
|
|
||||||
value: schematicTypeState.value!,
|
|
||||||
label: schematicTypeState.value!.name,
|
|
||||||
),
|
|
||||||
for (final type in data)
|
|
||||||
DropdownMenuEntry(
|
|
||||||
value: type,
|
|
||||||
label: type.name,
|
|
||||||
)
|
|
||||||
],
|
|
||||||
initialSelection: schematicTypeState.value,
|
|
||||||
enableSearch: true,
|
|
||||||
enableFilter: true,
|
|
||||||
width: 200,
|
|
||||||
menuHeight: 300,
|
|
||||||
label: const Text("Schematic Type"),
|
|
||||||
onSelected: (v) async {
|
|
||||||
schematicTypeState.value = v;
|
|
||||||
changed.value = true;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
error: (err, stk) {
|
|
||||||
return ErrorComponent(err, stk);
|
|
||||||
},
|
|
||||||
loading: () {
|
|
||||||
return const Disabled(initialValue: "Schematic Type");
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
SwitchListTile(
|
|
||||||
value: publicOnlyState.value,
|
|
||||||
onChanged: (value) {
|
|
||||||
publicOnlyState.value = value;
|
|
||||||
changed.value = true;
|
|
||||||
},
|
|
||||||
title: const Text("Public Only"),
|
|
||||||
),
|
|
||||||
SwitchListTile(
|
|
||||||
value: spectateSystemState.value,
|
|
||||||
onChanged: (value) {
|
|
||||||
spectateSystemState.value = value;
|
|
||||||
changed.value = true;
|
|
||||||
},
|
|
||||||
title: const Text("Use Spectate System"),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
TeamList(eventData.teams, fightCount),
|
|
||||||
EventFightList(
|
|
||||||
eventData: eventData,
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
197
lib/src/screens/event/components/tabs/edit_event.dart
Normale Datei
197
lib/src/screens/event/components/tabs/edit_event.dart
Normale Datei
@ -0,0 +1,197 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:steamwar_multitool/src/components/components.dart';
|
||||||
|
import 'package:steamwar_multitool/src/provider/data.dart';
|
||||||
|
import 'package:steamwar_multitool/src/screens/event/event.dart';
|
||||||
|
import 'package:steamwar_multitool/src/screens/event/state/event.dart';
|
||||||
|
import 'package:steamwar_multitool/src/types/schematic.dart';
|
||||||
|
|
||||||
|
class EditEventTab extends HookConsumerWidget {
|
||||||
|
const EditEventTab({
|
||||||
|
Key? key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final nameTextController =
|
||||||
|
useTextEditingController(text: ref.watch(eventNameProvider));
|
||||||
|
|
||||||
|
final maxTeamMembersController = useTextEditingController(
|
||||||
|
text: ref.watch(maxTeamSizeProvider).toString());
|
||||||
|
final invalidMaxTeamMembers = useState(false);
|
||||||
|
|
||||||
|
return ListView(
|
||||||
|
shrinkWrap: true,
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
TextField(
|
||||||
|
controller: nameTextController,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: "Name",
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
),
|
||||||
|
onChanged: (value) {
|
||||||
|
ref.read(eventNameProvider.notifier).state = value;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Wrap(
|
||||||
|
alignment: WrapAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
const Tooltip(
|
||||||
|
message: "Deadline",
|
||||||
|
child: Icon(Icons.block),
|
||||||
|
),
|
||||||
|
DateTimeEditor(
|
||||||
|
(p0) {
|
||||||
|
ref.read(eventDeadlineProvider.notifier).state = p0;
|
||||||
|
},
|
||||||
|
ref.watch(eventDeadlineProvider),
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
const Tooltip(
|
||||||
|
message: "Start",
|
||||||
|
child: Icon(Icons.swipe_right_alt),
|
||||||
|
),
|
||||||
|
DateTimeEditor((p0) {
|
||||||
|
ref.read(eventStartProvider.notifier).state = p0;
|
||||||
|
}, ref.watch(eventStartProvider), true),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
const Tooltip(
|
||||||
|
message: "End",
|
||||||
|
child: Icon(Icons.swipe_left_alt),
|
||||||
|
),
|
||||||
|
DateTimeEditor((p0) {
|
||||||
|
ref.read(eventEndProvider.notifier).state = p0;
|
||||||
|
}, ref.watch(eventEndProvider), true),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 150,
|
||||||
|
child: TextField(
|
||||||
|
controller: maxTeamMembersController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: "Max Team Members",
|
||||||
|
border: const OutlineInputBorder(),
|
||||||
|
errorText: invalidMaxTeamMembers.value
|
||||||
|
? "Must be a number above 0"
|
||||||
|
: null),
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value.isEmpty ||
|
||||||
|
int.tryParse(value) == null ||
|
||||||
|
int.parse(value) <= 0) {
|
||||||
|
invalidMaxTeamMembers.value = true;
|
||||||
|
} else {
|
||||||
|
invalidMaxTeamMembers.value = false;
|
||||||
|
ref.read(maxTeamSizeProvider.notifier).state =
|
||||||
|
int.parse(value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Slider(
|
||||||
|
value: ref.read(maxTeamSizeProvider).toDouble(),
|
||||||
|
onChanged: (p0) {
|
||||||
|
ref.read(maxTeamSizeProvider.notifier).state = p0.toInt();
|
||||||
|
maxTeamMembersController.text = p0.toInt().toString();
|
||||||
|
},
|
||||||
|
min: min(1, ref.read(maxTeamSizeProvider).toDouble()),
|
||||||
|
max: max(30, ref.read(maxTeamSizeProvider).toDouble()),
|
||||||
|
divisions:
|
||||||
|
max(30, ref.read(maxTeamSizeProvider).toDouble()).toInt() -
|
||||||
|
1,
|
||||||
|
label: ref.read(maxTeamSizeProvider).toString(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
ref.watch(schematicTypesProvider).when(
|
||||||
|
data: (data) {
|
||||||
|
final schematicTypeState = ref.watch(schematicTypeProvider);
|
||||||
|
|
||||||
|
return DropdownMenu<SchematicType?>(
|
||||||
|
dropdownMenuEntries: [
|
||||||
|
const DropdownMenuEntry(value: null, label: ""),
|
||||||
|
for (final type in data)
|
||||||
|
DropdownMenuEntry(
|
||||||
|
value: type,
|
||||||
|
label: type.name,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
initialSelection: catchToNull(() => data
|
||||||
|
.firstWhere((element) => element.db == schematicTypeState)),
|
||||||
|
enableSearch: true,
|
||||||
|
enableFilter: true,
|
||||||
|
width: 200,
|
||||||
|
menuHeight: 300,
|
||||||
|
label: const Text("Schematic Type"),
|
||||||
|
onSelected: (v) async {
|
||||||
|
ref.read(schematicTypeProvider.notifier).state = v?.db;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
error: (err, stk) {
|
||||||
|
return ErrorComponent(err, stk);
|
||||||
|
},
|
||||||
|
loading: () {
|
||||||
|
return const Disabled(initialValue: "Schematic Type");
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
SwitchListTile(
|
||||||
|
value: ref.watch(publicOnlyProvider),
|
||||||
|
onChanged: (value) {
|
||||||
|
ref.read(publicOnlyProvider.notifier).state = value;
|
||||||
|
},
|
||||||
|
title: const Text("Public Only"),
|
||||||
|
),
|
||||||
|
SwitchListTile(
|
||||||
|
value: ref.watch(spectateSystemProvider),
|
||||||
|
onChanged: (value) {
|
||||||
|
ref.read(spectateSystemProvider.notifier).state = value;
|
||||||
|
},
|
||||||
|
title: const Text("Use Spectate System"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -29,6 +29,7 @@ import 'package:steamwar_multitool/src/components/date_time_editor.dart';
|
|||||||
import 'package:steamwar_multitool/src/provider/provider.dart';
|
import 'package:steamwar_multitool/src/provider/provider.dart';
|
||||||
import 'package:steamwar_multitool/src/delegates/delegates.dart';
|
import 'package:steamwar_multitool/src/delegates/delegates.dart';
|
||||||
import 'package:steamwar_multitool/src/screens/event/components/dialogs/dialogs.dart';
|
import 'package:steamwar_multitool/src/screens/event/components/dialogs/dialogs.dart';
|
||||||
|
import 'package:steamwar_multitool/src/screens/event/state/event.dart';
|
||||||
import 'package:steamwar_multitool/src/screens/generator/bracket_generator.dart';
|
import 'package:steamwar_multitool/src/screens/generator/bracket_generator.dart';
|
||||||
import 'package:steamwar_multitool/src/screens/generator/generators/group_generator.dart';
|
import 'package:steamwar_multitool/src/screens/generator/generators/group_generator.dart';
|
||||||
import 'package:steamwar_multitool/src/types/types.dart';
|
import 'package:steamwar_multitool/src/types/types.dart';
|
||||||
@ -36,12 +37,11 @@ import 'package:steamwar_multitool/src/util/constants.dart';
|
|||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
class EventFightList extends HookConsumerWidget {
|
class EventFightList extends HookConsumerWidget {
|
||||||
final EventExtended eventData;
|
const EventFightList({Key? key}) : super(key: key);
|
||||||
|
|
||||||
const EventFightList({Key? key, required this.eventData}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final eventData = ref.watch(eventProvider);
|
||||||
final event = eventData.event;
|
final event = eventData.event;
|
||||||
final fights = useState<List<EventFight>>(eventData.fights);
|
final fights = useState<List<EventFight>>(eventData.fights);
|
||||||
final selected = useState<List<int>>([]);
|
final selected = useState<List<int>>([]);
|
@ -19,20 +19,19 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:steamwar_multitool/src/screens/event/state/event.dart';
|
||||||
import 'package:steamwar_multitool/src/types/types.dart';
|
import 'package:steamwar_multitool/src/types/types.dart';
|
||||||
|
|
||||||
class TeamList extends HookConsumerWidget {
|
class TeamList extends HookConsumerWidget {
|
||||||
final List<Team> teams;
|
const TeamList({
|
||||||
final Map<int, int> fightCount;
|
|
||||||
|
|
||||||
const TeamList(
|
|
||||||
this.teams,
|
|
||||||
this.fightCount, {
|
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final teams = ref.watch(eventProvider).teams;
|
||||||
|
final fightCount = ref.watch(eventFightsProvider);
|
||||||
|
|
||||||
return ListView(
|
return ListView(
|
||||||
children: [
|
children: [
|
||||||
ListTile(
|
ListTile(
|
@ -22,6 +22,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:steamwar_multitool/src/provider/events.dart';
|
import 'package:steamwar_multitool/src/provider/events.dart';
|
||||||
import 'package:steamwar_multitool/src/screens/event/components/loaded_event.dart';
|
import 'package:steamwar_multitool/src/screens/event/components/loaded_event.dart';
|
||||||
|
import 'package:steamwar_multitool/src/screens/event/state/event.dart';
|
||||||
import 'package:steamwar_multitool/src/types/types.dart';
|
import 'package:steamwar_multitool/src/types/types.dart';
|
||||||
|
|
||||||
T? catchToNull<T>(T Function() f) {
|
T? catchToNull<T>(T Function() f) {
|
||||||
@ -38,9 +39,7 @@ class EditEventScreen extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final eventFuture = useMemoized(() => ref
|
final eventFuture = ref.watch(eventFutureProvider(eventId).future);
|
||||||
.watch(eventRepositoryProvider.future)
|
|
||||||
.then((value) => value.getEvent(eventId)));
|
|
||||||
|
|
||||||
return FutureBuilder(
|
return FutureBuilder(
|
||||||
future: eventFuture,
|
future: eventFuture,
|
||||||
@ -65,8 +64,21 @@ class EditEventScreen extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
final eventData = snapshot.data as EventExtended;
|
final eventData = snapshot.data as EventExtended;
|
||||||
|
|
||||||
return LoadedEventScreen(
|
return ProviderScope(
|
||||||
eventData: eventData,
|
overrides: [
|
||||||
|
eventProvider.overrideWithValue(eventData),
|
||||||
|
eventNameProvider,
|
||||||
|
eventDeadlineProvider,
|
||||||
|
eventStartProvider,
|
||||||
|
eventEndProvider,
|
||||||
|
maxTeamSizeProvider,
|
||||||
|
schematicTypeProvider,
|
||||||
|
publicOnlyProvider,
|
||||||
|
spectateSystemProvider,
|
||||||
|
changedProvider,
|
||||||
|
eventFightsProvider,
|
||||||
|
],
|
||||||
|
child: const LoadedEventScreen(),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
92
lib/src/screens/event/state/event.dart
Normale Datei
92
lib/src/screens/event/state/event.dart
Normale Datei
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:steamwar_multitool/src/provider/provider.dart';
|
||||||
|
import 'package:steamwar_multitool/src/screens/event/event.dart';
|
||||||
|
import 'package:steamwar_multitool/src/types/types.dart';
|
||||||
|
|
||||||
|
final eventProvider = Provider<EventExtended>((ref) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
});
|
||||||
|
|
||||||
|
final eventNameProvider = StateProvider<String>((ref) {
|
||||||
|
return ref.read(eventProvider).event.name;
|
||||||
|
});
|
||||||
|
|
||||||
|
final eventDeadlineProvider = StateProvider<DateTime>((ref) {
|
||||||
|
return ref.read(eventProvider).event.deadline;
|
||||||
|
});
|
||||||
|
|
||||||
|
final eventStartProvider = StateProvider<DateTime>((ref) {
|
||||||
|
return ref.read(eventProvider).event.start;
|
||||||
|
});
|
||||||
|
|
||||||
|
final eventEndProvider = StateProvider<DateTime>((ref) {
|
||||||
|
return ref.read(eventProvider).event.end;
|
||||||
|
});
|
||||||
|
|
||||||
|
final maxTeamSizeProvider = StateProvider<int>((ref) {
|
||||||
|
return ref.read(eventProvider).event.maxTeamMembers;
|
||||||
|
});
|
||||||
|
|
||||||
|
final schematicTypeProvider = StateProvider<String?>((ref) {
|
||||||
|
return ref.read(eventProvider).event.schemType;
|
||||||
|
});
|
||||||
|
|
||||||
|
final schematicTypeFutureProvider = FutureProvider<SchematicType?>((ref) async {
|
||||||
|
final types = await ref.read(schematicTypesProvider.future);
|
||||||
|
final type = catchToNull(() => types
|
||||||
|
.firstWhere((element) => element.db == ref.watch(schematicTypeProvider)));
|
||||||
|
return type;
|
||||||
|
});
|
||||||
|
|
||||||
|
final publicOnlyProvider = StateProvider<bool>((ref) {
|
||||||
|
return ref.read(eventProvider).event.publicSchemsOnly;
|
||||||
|
});
|
||||||
|
|
||||||
|
final spectateSystemProvider = StateProvider<bool>((ref) {
|
||||||
|
return ref.read(eventProvider).event.spectateSystem;
|
||||||
|
});
|
||||||
|
|
||||||
|
final changedProvider = Provider<bool>((ref) {
|
||||||
|
final event = ref.watch(eventProvider);
|
||||||
|
return event.event.name != ref.watch(eventNameProvider) ||
|
||||||
|
event.event.deadline != ref.watch(eventDeadlineProvider) ||
|
||||||
|
event.event.start != ref.watch(eventStartProvider) ||
|
||||||
|
event.event.end != ref.watch(eventEndProvider) ||
|
||||||
|
event.event.maxTeamMembers != ref.watch(maxTeamSizeProvider) ||
|
||||||
|
event.event.schemType != ref.watch(schematicTypeProvider) ||
|
||||||
|
event.event.publicSchemsOnly != ref.watch(publicOnlyProvider) ||
|
||||||
|
event.event.spectateSystem != ref.watch(spectateSystemProvider);
|
||||||
|
});
|
||||||
|
|
||||||
|
final eventFightsProvider = Provider<Map<int, int>>((ref) {
|
||||||
|
final eventData = ref.watch(eventProvider);
|
||||||
|
Map<int, int> fightCount = {};
|
||||||
|
for (var team in eventData.teams) {
|
||||||
|
fightCount[team.id] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var fight in eventData.fights) {
|
||||||
|
fightCount[fight.blueTeam.id] = (fightCount[fight.blueTeam.id] ?? 0) + 1;
|
||||||
|
fightCount[fight.redTeam.id] = (fightCount[fight.redTeam.id] ?? 0) + 1;
|
||||||
|
}
|
||||||
|
return fightCount;
|
||||||
|
});
|
In neuem Issue referenzieren
Einen Benutzer sperren