1
0

Fixes and new Router

Dieser Commit ist enthalten in:
Chaoscaot 2022-12-24 11:06:17 +01:00
Ursprung cbcbd9ca81
Commit 7b05d2ed39
14 geänderte Dateien mit 185 neuen und 104 gelöschten Zeilen

Datei anzeigen

@ -1,20 +1,39 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:steamwar_multitool/src/screens/event.dart';
import 'screens/home.dart'; import 'screens/home.dart';
import 'screens/login.dart'; import 'screens/login.dart';
import 'screens/userinfo.dart'; import 'screens/userinfo.dart';
final _routes = GoRouter(
routes: [
GoRoute(path: "/", builder: (context, state) => const HomeScreen()),
GoRoute(
path: "/login", builder: (context, state) => const LoginScreenWidget()),
GoRoute(
path: "/settings", builder: (context, state) => const SettingsScreen()),
GoRoute(
path: "/event/:eventId",
builder: (context, state) {
final eventId = int.tryParse(state.params['eventId']!);
if (eventId == null) {
context.go("/");
return const SizedBox();
}
return EditEventScreen(eventId);
}),
],
initialLocation: "/login",
);
class DevServerStarterApp extends StatelessWidget { class DevServerStarterApp extends StatelessWidget {
const DevServerStarterApp({Key? key}) : super(key: key); const DevServerStarterApp({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp.router(
routes: { routerConfig: _routes,
"/": (context) => const LoginScreenWidget(),
"/home": (context) => const HomeScreen(),
"/settings": (context) => const SettingsScreen(),
},
title: 'Event-Tool', title: 'Event-Tool',
theme: ThemeData( theme: ThemeData(
useMaterial3: true, useMaterial3: true,

Datei anzeigen

@ -7,7 +7,7 @@ final serverUrlProvider = Provider<String>((ref) {
if (kDebugMode) { if (kDebugMode) {
return "http://localhost:8000"; return "http://localhost:8000";
} else { } else {
return "https://steamwar.de"; return "http://localhost:8000";
} }
}); });

Datei anzeigen

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; 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:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../provider/events.dart'; import '../../provider/events.dart';
@ -65,21 +66,13 @@ class EventDialog extends HookConsumerWidget {
), ),
TextButton( TextButton(
onPressed: () async { onPressed: () async {
final nav = Navigator.of(context);
final event = await ref.read(eventRepositoryProvider.future).then( final event = await ref.read(eventRepositoryProvider.future).then(
(value) => value.createEvent( (value) => value.createEvent(
eventName.text, startTime.value, endTime.value)); eventName.text, startTime.value, endTime.value));
final eventFull = await ref final eventFull = await ref
.read(eventRepositoryProvider.future) .read(eventRepositoryProvider.future)
.then((value) => value.getEvent(event.id)); .then((value) => value.getEvent(event.id));
nav.pop(); context.go('/event/${event.id}');
nav.push(
MaterialPageRoute(
builder: (context) {
return EditEventScreen(true, eventFull);
},
),
);
}, },
child: const Text("Create"), child: const Text("Create"),
), ),

Datei anzeigen

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../provider/events.dart'; import '../../provider/events.dart';
@ -40,17 +41,7 @@ class EventListComponent extends HookConsumerWidget {
subtitle: Text("${e.start} - ${e.end}"), subtitle: Text("${e.start} - ${e.end}"),
leading: const Icon(Icons.event), leading: const Icon(Icons.event),
onTap: () async { onTap: () async {
final nav = Navigator.of(context); context.go("/event/${e.id}");
final event = await ref
.read(eventRepositoryProvider.future)
.then((value) => value.getEvent(e.id));
nav.push(
MaterialPageRoute(
builder: (context) {
return EditEventScreen(true, event);
},
),
);
}, },
), ),
), ),
@ -64,21 +55,7 @@ class EventListComponent extends HookConsumerWidget {
leading: const Icon(Icons.check), leading: const Icon(Icons.check),
subtitle: Text("${e.start} - ${e.end}"), subtitle: Text("${e.start} - ${e.end}"),
onTap: () async { onTap: () async {
final nav = Navigator.of(context); context.go("/event/${e.id}");
final event = await ref
.read(eventRepositoryProvider.future)
.then((value) => value.getEvent(e.id));
nav.push(
MaterialPageRoute(
builder: (context) {
return EditEventScreen(
false ||
(userData.valueOrNull?.uneditablePastEvents ??
false),
event);
},
),
);
}, },
)), )),
], ],

Datei anzeigen

@ -2,6 +2,7 @@ import 'dart:math';
import 'package:flutter/material.dart'; 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:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../provider/events.dart'; import '../provider/events.dart';
@ -17,14 +18,57 @@ T? catchToNull<T>(T Function() f) {
} }
class EditEventScreen extends HookConsumerWidget { class EditEventScreen extends HookConsumerWidget {
final bool editable; final int eventId;
const EditEventScreen(this.eventId, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final eventFuture = useMemoized(() => ref
.watch(eventRepositoryProvider.future)
.then((value) => value.getEvent(eventId)));
return FutureBuilder(
future: eventFuture,
builder: (context, snapshot) {
if (snapshot.hasError) {
return Scaffold(
appBar: AppBar(
title: const Text('Error'),
),
body: Center(
child: Text('Error: ${snapshot.error}'),
),
);
}
if (!snapshot.hasData) {
return Scaffold(
appBar: AppBar(
title: const Text('Loading'),
),
body: const Center(
child: CircularProgressIndicator(),
),
);
}
final eventData = snapshot.data as EventExtended;
return _EventScreen(
eventData: eventData,
);
},
);
}
}
class _EventScreen extends HookConsumerWidget {
const _EventScreen({Key? key, required this.eventData}) : super(key: key);
final EventExtended eventData; final EventExtended eventData;
const EditEventScreen(this.editable, this.eventData, {Key? key})
: super(key: key);
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final event = eventData.event; final event = eventData.event;
final nameController = useTextEditingController(text: event.name); final nameController = useTextEditingController(text: event.name);
final deadlineState = useState(event.deadline); final deadlineState = useState(event.deadline);
final startDateState = useState(event.start); final startDateState = useState(event.start);
@ -41,10 +85,9 @@ class EditEventScreen extends HookConsumerWidget {
final spectateSystemState = useState(event.spectateSystem); final spectateSystemState = useState(event.spectateSystem);
final changed = useState(false); final changed = useState(false);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text("${editable ? "Edit" : "View"} ${event.name}"), title: Text("${"Edit"} ${event.name}"),
actions: [ actions: [
IconButton( IconButton(
onPressed: () { onPressed: () {
@ -95,7 +138,7 @@ class EditEventScreen extends HookConsumerWidget {
)) ))
.whenComplete( .whenComplete(
() => ref.invalidate(eventsListProvider)); () => ref.invalidate(eventsListProvider));
Navigator.of(context).pop(); context.go('/');
} }
: null, : null,
icon: const Icon(Icons.save)), icon: const Icon(Icons.save)),
@ -126,7 +169,7 @@ class EditEventScreen extends HookConsumerWidget {
} else { } else {
canPop = true; canPop = true;
} }
if (canPop) Navigator.of(context).pop(); if (canPop) context.go("/");
}, },
icon: const Icon(Icons.arrow_back), icon: const Icon(Icons.arrow_back),
), ),
@ -141,7 +184,6 @@ class EditEventScreen extends HookConsumerWidget {
labelText: "Name", labelText: "Name",
border: OutlineInputBorder(), border: OutlineInputBorder(),
), ),
enabled: editable,
onChanged: (value) { onChanged: (value) {
changed.value = true; changed.value = true;
}, },
@ -153,7 +195,7 @@ class EditEventScreen extends HookConsumerWidget {
DateTimeEditor((p0) { DateTimeEditor((p0) {
deadlineState.value = p0; deadlineState.value = p0;
changed.value = true; changed.value = true;
}, deadlineState.value, editable), }, deadlineState.value, true),
], ],
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
@ -163,7 +205,7 @@ class EditEventScreen extends HookConsumerWidget {
DateTimeEditor((p0) { DateTimeEditor((p0) {
startDateState.value = p0; startDateState.value = p0;
changed.value = true; changed.value = true;
}, startDateState.value, editable), }, startDateState.value, true),
], ],
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
@ -173,7 +215,7 @@ class EditEventScreen extends HookConsumerWidget {
DateTimeEditor((p0) { DateTimeEditor((p0) {
endDateState.value = p0; endDateState.value = p0;
changed.value = true; changed.value = true;
}, endDateState.value, editable), }, endDateState.value, true),
], ],
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
@ -185,7 +227,6 @@ class EditEventScreen extends HookConsumerWidget {
errorText: invalidMaxTeamMembers.value errorText: invalidMaxTeamMembers.value
? "Must be a number above 0" ? "Must be a number above 0"
: null), : null),
enabled: editable,
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
onChanged: (value) { onChanged: (value) {
if (value.isEmpty || if (value.isEmpty ||
@ -199,44 +240,39 @@ class EditEventScreen extends HookConsumerWidget {
} }
}, },
), ),
if (editable) Slider(
Slider( value: maxTeamMembersState.value.toDouble(),
value: maxTeamMembersState.value.toDouble(), onChanged: (p0) {
onChanged: editable maxTeamMembersState.value = p0.toInt();
? (p0) { maxTeamMembersController.text = p0.toInt().toString();
maxTeamMembersState.value = p0.toInt(); changed.value = true;
maxTeamMembersController.text = p0.toInt().toString(); },
changed.value = true; min: min(1, maxTeamMembersState.value.toDouble()),
} max: max(30, maxTeamMembersState.value.toDouble()),
: null, divisions:
min: min(1, maxTeamMembersState.value.toDouble()), max(30, maxTeamMembersState.value.toDouble()).toInt() - 1,
max: max(30, maxTeamMembersState.value.toDouble()), label: maxTeamMembersState.value.toString(),
divisions: ),
max(30, maxTeamMembersState.value.toDouble()).toInt() - 1,
label: maxTeamMembersState.value.toString(),
),
const SizedBox(height: 8), const SizedBox(height: 8),
Row( Row(
children: [ children: [
const Text("Schematic Type: "), const Text("Schematic Type: "),
TextButton( TextButton(
onPressed: editable onPressed: () async {
? () async { final types =
final types = await ref.read(schematicTypesProvider.future);
await ref.read(schematicTypesProvider.future); final out = await showSearch(
final out = await showSearch( context: context,
context: context, delegate: SchematicTypeSearchDelegate(types));
delegate: SchematicTypeSearchDelegate(types)); if (out == RESET_TYPE) {
if (out == RESET_TYPE) { schematicTypeState.value = null;
schematicTypeState.value = null; changed.value = true;
changed.value = true; } else {
} else { schematicTypeState.value =
schematicTypeState.value = out ?? schematicTypeState.value;
out ?? schematicTypeState.value; changed.value = true;
changed.value = true; }
} },
}
: null,
child: Text(schematicTypeState.value?.name ?? "Select")), child: Text(schematicTypeState.value?.name ?? "Select")),
], ],
), ),
@ -248,7 +284,6 @@ class EditEventScreen extends HookConsumerWidget {
changed.value = true; changed.value = true;
}, },
title: const Text("Public Only"), title: const Text("Public Only"),
enabled: editable,
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
CheckboxListTile( CheckboxListTile(
@ -258,7 +293,6 @@ class EditEventScreen extends HookConsumerWidget {
changed.value = true; changed.value = true;
}, },
title: const Text("Use Spectate System"), title: const Text("Use Spectate System"),
enabled: editable,
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
Text("Teams", style: Theme.of(context).textTheme.headline6), Text("Teams", style: Theme.of(context).textTheme.headline6),

Datei anzeigen

@ -1,5 +1,8 @@
import 'dart:async';
import 'package:flutter/material.dart'; 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:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -15,6 +18,23 @@ class HomeScreen extends HookConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final servers = ref.watch(serversProvider); final servers = ref.watch(serversProvider);
final userData = ref.watch(userDataProvider);
if (userData.hasError) {
Timer.run(() {
context.go('/login');
});
return Scaffold(
body: Center(
child: FloatingActionButton.large(
onPressed: () {
context.go('/login');
},
child: const Icon(Icons.login)),
),
);
}
final navRailIndex = useState(0); final navRailIndex = useState(0);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
@ -49,7 +69,7 @@ class HomeScreen extends HookConsumerWidget {
await prefs.remove("key"); await prefs.remove("key");
ref.refresh(userDataProvider); ref.refresh(userDataProvider);
nav.pop(); nav.pop();
nav.pushReplacementNamed("/"); context.go('/login');
}, },
child: const Text('Logout', child: const Text('Logout',
style: TextStyle(color: Colors.red)), style: TextStyle(color: Colors.red)),

Datei anzeigen

@ -1,7 +1,12 @@
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart'; 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:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:steamwar_multitool/src/provider/http.dart';
import '../provider/user.dart'; import '../provider/user.dart';
@ -15,14 +20,22 @@ class LoginScreenWidget extends HookConsumerWidget {
final keyController = useTextEditingController(); final keyController = useTextEditingController();
final updater = useState(0); final updater = useState(0);
ref.read(userDataProvider).when( final userData = ref.watch(userDataProvider);
data: (data) {
keyController.text = data.key; if (userData.hasValue) {
updater.value++; Timer.run(() {
}, context.go('/');
loading: () {}, });
error: (error, stack) {}, return Scaffold(
); body: Center(
child: FloatingActionButton.large(
onPressed: () {
context.go('/');
},
child: const Icon(Icons.home)),
),
);
}
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
@ -53,11 +66,28 @@ class LoginScreenWidget extends HookConsumerWidget {
FloatingActionButton.large( FloatingActionButton.large(
onPressed: keyController.text.isNotEmpty onPressed: keyController.text.isNotEmpty
? () async { ? () async {
final nav = Navigator.of(context); final dio = Dio(
final prefs = await SharedPreferences.getInstance(); BaseOptions(
await prefs.setString("key", keyController.text); baseUrl: ref.read(serverUrlProvider),
ref.invalidate(userDataProvider); headers: {
nav.pushReplacementNamed("/home"); 'X-SW-Auth': keyController.text,
},
contentType: 'application/json',
),
);
try {
await dio.get('/data');
final prefs = await SharedPreferences.getInstance();
await prefs.setString("key", keyController.text);
ref.invalidate(userDataProvider);
context.go('/');
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Invalid Key'),
),
);
}
} }
: null, : null,
child: const Icon(Icons.forward), child: const Icon(Icons.forward),

Datei anzeigen

@ -261,6 +261,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.1" version: "2.1.1"
go_router:
dependency: "direct main"
description:
name: go_router
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.0"
graphs: graphs:
dependency: transitive dependency: transitive
description: description:
@ -667,4 +674,4 @@ packages:
version: "3.1.1" version: "3.1.1"
sdks: sdks:
dart: ">=2.18.1 <3.0.0" dart: ">=2.18.1 <3.0.0"
flutter: ">=3.0.0" flutter: ">=3.3.0"

Datei anzeigen

@ -20,6 +20,7 @@ dependencies:
shared_preferences: ^2.0.15 shared_preferences: ^2.0.15
xterm: ^3.4.0 xterm: ^3.4.0
dio: ^4.0.6 dio: ^4.0.6
go_router: ^6.0.0
dev_dependencies: dev_dependencies:

Binäre Datei nicht angezeigt.

Vorher

Breite:  |  Höhe:  |  Größe: 917 B

Nachher

Breite:  |  Höhe:  |  Größe: 7.9 KiB

Binäre Datei nicht angezeigt.

Vorher

Breite:  |  Höhe:  |  Größe: 5.2 KiB

Nachher

Breite:  |  Höhe:  |  Größe: 37 KiB

Binäre Datei nicht angezeigt.

Vorher

Breite:  |  Höhe:  |  Größe: 8.1 KiB

Nachher

Breite:  |  Höhe:  |  Größe: 101 KiB

Binäre Datei nicht angezeigt.

Vorher

Breite:  |  Höhe:  |  Größe: 5.5 KiB

Nachher

Breite:  |  Höhe:  |  Größe: 37 KiB

Binäre Datei nicht angezeigt.

Vorher

Breite:  |  Höhe:  |  Größe: 20 KiB

Nachher

Breite:  |  Höhe:  |  Größe: 95 KiB