Event Stuff
Dieser Commit ist enthalten in:
Ursprung
744c79408f
Commit
9fc40df916
@ -1,5 +1,8 @@
|
|||||||
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:intl/intl.dart';
|
||||||
import 'package:steamwar_multitool/src/app.dart';
|
import 'package:steamwar_multitool/src/app.dart';
|
||||||
|
|
||||||
|
final kDateFormat = DateFormat("dd.MM.yyyy HH:mm");
|
||||||
|
|
||||||
void main() => runApp(const ProviderScope(child: DevServerStarterApp()));
|
void main() => runApp(const ProviderScope(child: DevServerStarterApp()));
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:steamwar_multitool/src/provider/types.dart';
|
import 'package:steamwar_multitool/src/provider/types.dart';
|
||||||
@ -122,15 +123,21 @@ class EventFight {
|
|||||||
this.blueTeam, this.kampfleiter, this.score);
|
this.blueTeam, this.kampfleiter, this.score);
|
||||||
|
|
||||||
Team get winner {
|
Team get winner {
|
||||||
|
return getTeamWithContextColor(Colors.white);
|
||||||
|
}
|
||||||
|
|
||||||
|
Team getTeamWithContextColor(Color color) {
|
||||||
switch (score) {
|
switch (score) {
|
||||||
case 1:
|
case 1:
|
||||||
return blueTeam;
|
return blueTeam;
|
||||||
case 2:
|
case 2:
|
||||||
return redTeam;
|
return redTeam;
|
||||||
case 3:
|
case 3:
|
||||||
return Team(-1, "Tie", "TIE", "7");
|
return Team(
|
||||||
|
-1, "Tie", "TIE", color.computeLuminance() > 0.5 ? "f" : "0");
|
||||||
default:
|
default:
|
||||||
return Team(-1, "Unknown", "UNK", "7");
|
return Team(
|
||||||
|
-1, "Unknown", "UNK", color.computeLuminance() > 0.5 ? "f" : "0");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,6 +276,9 @@ class ShortEvent {
|
|||||||
|
|
||||||
get isUpcoming => start.isAfter(DateTime.now());
|
get isUpcoming => start.isAfter(DateTime.now());
|
||||||
|
|
||||||
|
get isCurrent =>
|
||||||
|
start.isBefore(DateTime.now()) && end.isAfter(DateTime.now());
|
||||||
|
|
||||||
factory ShortEvent.fromJson(Map<String, dynamic> json) {
|
factory ShortEvent.fromJson(Map<String, dynamic> json) {
|
||||||
return ShortEvent(
|
return ShortEvent(
|
||||||
json["name"],
|
json["name"],
|
||||||
|
@ -4,6 +4,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||||||
import 'package:steamwar_multitool/src/provider/user.dart';
|
import 'package:steamwar_multitool/src/provider/user.dart';
|
||||||
|
|
||||||
final serverUrlProvider = Provider<String>((ref) {
|
final serverUrlProvider = Provider<String>((ref) {
|
||||||
|
return "https://steamwar.de/eventplanner-api";
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
return "http://localhost:1337";
|
return "http://localhost:1337";
|
||||||
} else {
|
} else {
|
||||||
|
11
lib/src/screens/bracket_generator.dart
Normale Datei
11
lib/src/screens/bracket_generator.dart
Normale Datei
@ -0,0 +1,11 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
|
||||||
|
class BracketGeneratorScreen extends HookConsumerWidget {
|
||||||
|
const BracketGeneratorScreen({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
return const Placeholder();
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:steamwar_multitool/main.dart';
|
||||||
|
|
||||||
import '../../provider/events.dart';
|
import '../../provider/events.dart';
|
||||||
import '../../provider/user.dart';
|
|
||||||
import '../event.dart';
|
|
||||||
import 'error.dart';
|
import 'error.dart';
|
||||||
import 'event_dialog.dart';
|
import 'event_dialog.dart';
|
||||||
|
|
||||||
@ -14,10 +13,11 @@ class EventListComponent extends HookConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final events = ref.watch(eventsListProvider);
|
final events = ref.watch(eventsListProvider);
|
||||||
final userData = ref.watch(userDataProvider);
|
|
||||||
return events.when(data: (data) {
|
return events.when(data: (data) {
|
||||||
final upcomingEvents = data.where((element) => element.isUpcoming);
|
final upcomingEvents = data.where((element) => element.isUpcoming);
|
||||||
final pastEvents = data.where((element) => !element.isUpcoming);
|
final pastEvents =
|
||||||
|
data.where((element) => !element.isUpcoming && !element.isCurrent);
|
||||||
|
final currentEvent = data.indexWhere((element) => element.isCurrent);
|
||||||
return ListView(
|
return ListView(
|
||||||
children: [
|
children: [
|
||||||
FloatingActionButton.extended(
|
FloatingActionButton.extended(
|
||||||
@ -30,6 +30,21 @@ class EventListComponent extends HookConsumerWidget {
|
|||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 16,
|
height: 16,
|
||||||
),
|
),
|
||||||
|
if (currentEvent != -1)
|
||||||
|
ListTile(
|
||||||
|
title: Text(
|
||||||
|
data[currentEvent].name,
|
||||||
|
style: Theme.of(context).textTheme.headline6,
|
||||||
|
),
|
||||||
|
subtitle: Text(
|
||||||
|
"Current Event",
|
||||||
|
style: Theme.of(context).textTheme.subtitle1,
|
||||||
|
),
|
||||||
|
leading: const Icon(Icons.priority_high),
|
||||||
|
onTap: () {
|
||||||
|
context.go("/event/${data[currentEvent].id}");
|
||||||
|
},
|
||||||
|
),
|
||||||
if (upcomingEvents.isNotEmpty)
|
if (upcomingEvents.isNotEmpty)
|
||||||
Text(
|
Text(
|
||||||
"Upcoming Events",
|
"Upcoming Events",
|
||||||
@ -38,7 +53,8 @@ class EventListComponent extends HookConsumerWidget {
|
|||||||
...upcomingEvents.map(
|
...upcomingEvents.map(
|
||||||
(e) => ListTile(
|
(e) => ListTile(
|
||||||
title: Text(e.name),
|
title: Text(e.name),
|
||||||
subtitle: Text("${e.start} - ${e.end}"),
|
subtitle: Text(
|
||||||
|
"${kDateFormat.format(e.start)} - ${kDateFormat.format(e.end)}"),
|
||||||
leading: const Icon(Icons.event),
|
leading: const Icon(Icons.event),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
context.go("/event/${e.id}");
|
context.go("/event/${e.id}");
|
||||||
@ -53,7 +69,8 @@ class EventListComponent extends HookConsumerWidget {
|
|||||||
...pastEvents.map((e) => ListTile(
|
...pastEvents.map((e) => ListTile(
|
||||||
title: Text(e.name),
|
title: Text(e.name),
|
||||||
leading: const Icon(Icons.check),
|
leading: const Icon(Icons.check),
|
||||||
subtitle: Text("${e.start} - ${e.end}"),
|
subtitle: Text(
|
||||||
|
"${kDateFormat.format(e.start)} - ${kDateFormat.format(e.end)}"),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
context.go("/event/${e.id}");
|
context.go("/event/${e.id}");
|
||||||
},
|
},
|
||||||
|
@ -4,8 +4,9 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:steamwar_multitool/src/provider/user.dart';
|
import 'package:steamwar_multitool/src/util/event_fight_exporter.dart';
|
||||||
|
|
||||||
|
import '../../main.dart';
|
||||||
import '../provider/events.dart';
|
import '../provider/events.dart';
|
||||||
import '../provider/types.dart';
|
import '../provider/types.dart';
|
||||||
import 'search_delegates.dart';
|
import 'search_delegates.dart';
|
||||||
@ -348,8 +349,9 @@ class _EventFightList extends HookConsumerWidget {
|
|||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
SizedBox(
|
Row(
|
||||||
width: double.infinity,
|
children: [
|
||||||
|
Expanded(
|
||||||
child: FloatingActionButton.extended(
|
child: FloatingActionButton.extended(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
showDialog(
|
showDialog(
|
||||||
@ -366,22 +368,50 @@ class _EventFightList extends HookConsumerWidget {
|
|||||||
icon: const Icon(Icons.add),
|
icon: const Icon(Icons.add),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
PopupMenuButton(
|
||||||
|
itemBuilder: (context) {
|
||||||
|
return [
|
||||||
|
PopupMenuItem(
|
||||||
|
child: const Text("Export Data"),
|
||||||
|
value: "export",
|
||||||
|
),
|
||||||
|
];
|
||||||
|
},
|
||||||
|
onSelected: (value) {
|
||||||
|
if (value == "export") {
|
||||||
|
openExportedFights(fights.value, event.name);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
for (final fight in fights.value)
|
for (final fight in fights.value)
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
"${fight.blueTeam.name} vs ${fight.redTeam.name}",
|
"${fight.blueTeam.name} vs ${fight.redTeam.name}",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: fight.winner.color.computeLuminance() > 0.5
|
color: fight
|
||||||
|
.getTeamWithContextColor(
|
||||||
|
Theme.of(context).scaffoldBackgroundColor)
|
||||||
|
.color
|
||||||
|
.computeLuminance() >
|
||||||
|
0.5
|
||||||
? Colors.black
|
? Colors.black
|
||||||
: Colors.white),
|
: Colors.white),
|
||||||
),
|
),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
fight.score == 0
|
fight.score == 0
|
||||||
? fight.start.toString()
|
? kDateFormat.format(fight.start)
|
||||||
: "Winner: ${fight.winner.name}",
|
: "Winner: ${fight.winner.name}",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: fight.winner.color.computeLuminance() > 0.5
|
color: fight
|
||||||
|
.getTeamWithContextColor(
|
||||||
|
Theme.of(context).scaffoldBackgroundColor)
|
||||||
|
.color
|
||||||
|
.computeLuminance() >
|
||||||
|
0.5
|
||||||
? Colors.black
|
? Colors.black
|
||||||
: Colors.white)),
|
: Colors.white)),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
@ -725,7 +755,7 @@ class DateTimeEditor extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
child: Text(initialDate.toString()),
|
child: Text(kDateFormat.format(initialDate)),
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: enabled
|
onPressed: enabled
|
||||||
|
34
lib/src/util/event_fight_exporter.dart
Normale Datei
34
lib/src/util/event_fight_exporter.dart
Normale Datei
@ -0,0 +1,34 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:html';
|
||||||
|
|
||||||
|
import 'package:csv/csv.dart';
|
||||||
|
import 'package:steamwar_multitool/src/provider/events.dart';
|
||||||
|
|
||||||
|
/*
|
||||||
|
Start,BlueTeam,RedTeam,WinnerTeam
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
Uri exportFights(List<EventFight> fights, String eventName) {
|
||||||
|
List<List<String>> csv = [];
|
||||||
|
csv.add(['Start', 'BlueTeam', 'RedTeam', 'WinnerTeam']);
|
||||||
|
for (var fight in fights) {
|
||||||
|
csv.add([
|
||||||
|
fight.start.toString(),
|
||||||
|
fight.blueTeam.name,
|
||||||
|
fight.redTeam.name,
|
||||||
|
fight.winner.name,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Uri.dataFromBytes(
|
||||||
|
Encoding.getByName("utf-8")!
|
||||||
|
.encode(const ListToCsvConverter(eol: "\n").convert(csv)),
|
||||||
|
mimeType: "text/csv",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void openExportedFights(List<EventFight> fights, String eventName) async {
|
||||||
|
final uri = exportFights(fights, eventName);
|
||||||
|
window.open(uri.toString(), "export");
|
||||||
|
}
|
22
pubspec.lock
22
pubspec.lock
@ -119,7 +119,7 @@ packages:
|
|||||||
name: code_builder
|
name: code_builder
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.3.0"
|
version: "4.4.0"
|
||||||
collection:
|
collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -141,6 +141,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.2"
|
version: "3.0.2"
|
||||||
|
csv:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: csv
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "5.0.1"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -222,7 +229,7 @@ packages:
|
|||||||
name: flutter_riverpod
|
name: flutter_riverpod
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.3"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -281,7 +288,7 @@ packages:
|
|||||||
name: hooks_riverpod
|
name: hooks_riverpod
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.3"
|
||||||
http_multi_server:
|
http_multi_server:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -296,6 +303,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.2"
|
version: "4.0.2"
|
||||||
|
intl:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: intl
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.18.0"
|
||||||
io:
|
io:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -463,7 +477,7 @@ packages:
|
|||||||
name: riverpod
|
name: riverpod
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.3"
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -21,6 +21,8 @@ dependencies:
|
|||||||
xterm: ^3.4.0
|
xterm: ^3.4.0
|
||||||
dio: ^4.0.6
|
dio: ^4.0.6
|
||||||
go_router: ^6.0.0
|
go_router: ^6.0.0
|
||||||
|
intl: ^0.18.0
|
||||||
|
csv: ^5.0.1
|
||||||
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
var serviceWorkerVersion = null;
|
var serviceWorkerVersion = null;
|
||||||
</script>
|
</script>
|
||||||
<!-- This script adds the flutter initialization JS code -->
|
<!-- This script adds the flutter initialization JS code -->
|
||||||
<script src="main.dart.js" defer></script>
|
<script src="flutter.js" defer></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script>
|
<script>
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren