From 5b9b48cd24f462927fe3519e68e9a12a50b1b536 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Tue, 28 Mar 2023 14:54:39 +0200 Subject: [PATCH] Migrated to GoRouter Reasons for migration: - buggy behaviour from old router - GoRouter is a recommended flutter plugin - ShellRoutes allow exposing Providers to a limited scope of routes - GoRoutes provides named routes, and the navigator allows us to provide parameters directly. --- lib/main.dart | 275 ++++++++++++++++++------------ lib/screens/auth.dart | 9 - lib/screens/home.dart | 120 ++++++------- lib/screens/room/edit.dart | 8 +- lib/screens/room/join.dart | 30 ++-- lib/screens/room/main.dart | 9 - lib/screens/room/members.dart | 16 +- lib/screens/room/new.dart | 14 +- lib/screens/room/pages/about.dart | 36 ++-- lib/screens/room/permissions.dart | 10 +- lib/screens/settings/main.dart | 18 +- lib/screens/welcome.dart | 23 ++- pubspec.lock | 24 ++- pubspec.yaml | 2 +- 14 files changed, 316 insertions(+), 278 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index f27d0ad..9433bdd 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; import 'package:outbag_app/backend/themes.dart'; import 'package:outbag_app/backend/user.dart'; import 'package:outbag_app/screens/room/edit.dart'; @@ -14,13 +15,19 @@ import './screens/welcome.dart'; import './screens/room/main.dart'; import './screens/auth.dart'; import './backend/request.dart'; -import 'package:routemaster/routemaster.dart'; void main() { WidgetsFlutterBinding.ensureInitialized(); runApp(const OutbagApp()); } +final GlobalKey _rootNavigatorKey = +GlobalKey(debugLabel: 'root'); +final GlobalKey _userShellNavigatorKey = +GlobalKey(debugLabel: 'user'); +final GlobalKey _roomShellNavigatorKey = +GlobalKey(debugLabel: 'room'); + class OutbagApp extends StatefulWidget { const OutbagApp({super.key}); @@ -41,43 +48,45 @@ class _OutbagAppState extends State { void initState() { super.initState(); - // wait for user to be authorized - User.listen((_) async { - try { - final user = await User.fromDisk(); - setState(() { - this.user = user; - }); - fetchInfo(); - } catch (_) { - // no userdata found - setState(() { - user = null; - }); - } - }); - - AppTheme.listen((_) async { - final theme = await AppTheme.fromDisk(); - setState(() { - this.theme = theme; - }); - }); - - (() async { - final theme = await AppTheme.fromDisk(); - setState(() { - this.theme = theme; - }); - })(); - WidgetsBinding.instance.addPostFrameCallback((_) async { + // wait for user to be authorized + User.listen((_) async { + try { + final user = await User.fromDisk(); + setState(() { + this.user = user; + }); + fetchInfo(user); + } catch (_) { + // no userdata found + setState(() { + user = null; + }); + } + }); + + AppTheme.listen((_) async { + final theme = await AppTheme.fromDisk(); + setState(() { + this.theme = theme; + }); + }); + + // load theme + try { + final theme = await AppTheme.fromDisk(); + setState(() { + this.theme = theme; + }); + } catch (_) {} + + // load user try { final user = await User.fromDisk(); setState(() { this.user = user; }); - fetchInfo(); + fetchInfo(user); } catch (_) { // user unavailable // invalid credentials @@ -89,15 +98,15 @@ class _OutbagAppState extends State { }); } - void fetchInfo() async { + void fetchInfo(User user) async { // try to obtain user account information // with existing details // NOTE: also functions as a way to verify ther data doNetworkRequest(null, req: () => postWithCreadentials( - target: (user?.server)!, + target: user.server, path: 'getMyAccount', - credentials: user!, + credentials: user, body: {}), onOK: (body) { final info = AccountMeta.fromJSON(body['data']); @@ -111,7 +120,7 @@ class _OutbagAppState extends State { setState(() { info = null; - user = null; + this.user = null; }); return true; }, @@ -132,87 +141,139 @@ class _OutbagAppState extends State { value: info, ), Provider.value(value: theme), - // conditional user provider - // used to only provide a user outside of the login area - ...(user!=null)?[ - Provider.value(value:user!) - ]:[] ], child: MaterialApp.router( title: "Outbag", themeMode: theme.mode, theme: ThemeData(useMaterial3: true, brightness: Brightness.light), darkTheme: ThemeData(useMaterial3: true, brightness: Brightness.dark), - routerDelegate: RoutemasterDelegate( - routesBuilder: (context) => RouteMap( - routes: { - // pre authentification routes - ...(user == null) - ? { - '/welcome/': (_) => - const MaterialPage(child: WelcomePage()), - '/signup': (_) => const MaterialPage( - child: AuthPage(mode: Mode.signup)), - '/signupOTA': (_) => const MaterialPage( - child: AuthPage(mode: Mode.signupOTA)), - '/signin': (_) => const MaterialPage( - child: AuthPage(mode: Mode.signin)), + routerConfig: GoRouter( + navigatorKey: _rootNavigatorKey, + initialLocation: '/', + redirect: (context, state) async { + if (user == null) { + // prelogin + if (!state.subloc.startsWith('/welcome')) { + // prevent unauthorized user from accessing home + return '/welcome'; } - : {}, + } else { + // post login + if (state.subloc.startsWith('/welcome')) { + // prevent authorized user from accessing /welcome + return '/'; + } + } - // routes that need the user - // to exis - ...(user!=null)?{ - '/': (_) => const MaterialPage(child: HomePage()), + return null; + }, + routes: [ + // unauthorized routes + GoRoute( + name: 'welcome', + path: '/welcome', + builder: (context, state) => const WelcomePage(), + routes: [ + GoRoute( + name: 'signin', + path: 'signin', + builder: (context, state) => + const AuthPage(mode: Mode.signin), + ), + GoRoute( + name: 'signup', + path: 'signup', + builder: (context, state) => + const AuthPage(mode: Mode.signup), + ), + GoRoute( + name: 'signup-ota', + path: 'signup-ota', + builder: (context, state) => + const AuthPage(mode: Mode.signupOTA), + ), + ]), - // user-space settings - '/settings': (_) => - const MaterialPage(child: SettingsPage()), + // authorized routes + ShellRoute( + navigatorKey: _userShellNavigatorKey, + builder: (context, state, child) => + Provider.value(value: user!, child: child), + routes: [ + GoRoute( + path: '/', + name: 'home', + builder: (context, state) => const HomePage(), + routes: [ + GoRoute( + name: 'settings', + path: 'settings', + builder: (context, state) => + const SettingsPage()), + GoRoute( + path: 'join-room', + name: 'add-room', + builder: (context, state) => + const JoinRoomPage(), + routes: [ + GoRoute( + path: 'new', + name: 'new-room', + builder: (context, state) => + const NewRoomPage()), + ]), + GoRoute( + name: 'room', + path: 'r/:server/:id', + builder: (context, state) => RoomPage( + state.params['server'] ?? '', + state.params['id'] ?? ''), + routes: [ + ShellRoute( + navigatorKey: _roomShellNavigatorKey, + builder: (context, state, child) => + Provider.value( + // TODO: provide nullable room data + value: null, + child: child), + routes: [ + GoRoute( + name: 'edit-room', + path: 'edit', + builder: (context, state) => + EditRoomPage( + state.params['server'] ?? + '', + state.params['id'] ?? '')), + GoRoute( + name: 'room-members', + path: 'members', + builder: (context, state) => + ManageRoomMembersPage( + state.params['server'] ?? + '', + state.params['id'] ?? '')), + GoRoute( + name: 'room-permissions', + path: 'roles', + builder: (context, state) => + EditRoomPermissionSetPage( + state.params['server'] ?? + '', + state.params['id'] ?? '')), + ]) + ]) + ]), + ]), - // server dashboard - // TODO: add permission check - // so routes are only available - // if user is allowed to view dashboard - ...{ - - }, - // room related settings - '/add-room/new': (_) => - const MaterialPage(child: NewRoomPage()), - '/add-room': (_) => - const MaterialPage(child: JoinRoomPage()), - '/r/:server/:tag/': (info) { - final server = info.pathParameters['server'] ?? ""; - final tag = info.pathParameters['tag'] ?? ""; - - return MaterialPage(child: RoomPage(server, tag)); - }, - '/r/:server/:tag/edit': (info) { - final server = info.pathParameters['server'] ?? ""; - final tag = info.pathParameters['tag'] ?? ""; - - return MaterialPage(child: EditRoomPage(server, tag)); - }, - '/r/:server/:tag/members': (info) { - final server = info.pathParameters['server'] ?? ""; - final tag = info.pathParameters['tag'] ?? ""; - - return MaterialPage( - child: ManageRoomMembersPage(server, tag)); - }, - '/r/:server/:tag/permissions': (info) { - final server = info.pathParameters['server'] ?? ""; - final tag = info.pathParameters['tag'] ?? ""; - - return MaterialPage( - child: EditRoomPermissionSetPage(server, tag)); - }, - }:{} - }, - onUnknownRoute: (_) => (user == null) - ? const MaterialPage(child: WelcomePage()) - : const Redirect('/'))), - routeInformationParser: const RoutemasterParser(), + // routes that can be accessed + // with and without an account + // i.e the about screen + GoRoute( + path: '/about', + name: 'about', + builder: (context, state) => const Text('About')) + ]), )); } } diff --git a/lib/screens/auth.dart b/lib/screens/auth.dart index 525613d..582c220 100644 --- a/lib/screens/auth.dart +++ b/lib/screens/auth.dart @@ -4,7 +4,6 @@ import 'package:outbag_app/backend/request.dart'; import 'package:outbag_app/backend/user.dart'; import 'package:outbag_app/tools/fetch_wrapper.dart'; import 'package:outbag_app/tools/snackbar.dart'; -import 'package:routemaster/routemaster.dart'; import '../backend/resolve_url.dart'; enum Mode { @@ -58,14 +57,6 @@ class _AuthPageState extends State { : Scaffold( appBar: AppBar( title: Text(modeName), - leading: IconButton( - onPressed: () { - // go back - Routemaster.of(context).history.back(); - }, - icon: const Icon(Icons.arrow_back), - tooltip: "Go back", - ), ), body: Center( child: ConstrainedBox( diff --git a/lib/screens/home.dart b/lib/screens/home.dart index d8fb930..9f340ec 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -5,7 +5,7 @@ import 'package:outbag_app/backend/request.dart'; import 'package:outbag_app/backend/user.dart'; import 'package:outbag_app/tools/fetch_wrapper.dart'; import 'package:provider/provider.dart'; -import 'package:routemaster/routemaster.dart'; +import 'package:go_router/go_router.dart'; import '../backend/room.dart'; class HomePage extends StatefulWidget { @@ -23,12 +23,12 @@ class _HomePageState extends State { // wait for background room changes Room.listen((_) async { - try { - final newRooms = await Room.listRooms(); - setState(() { - rooms = newRooms; - }); - } catch (_) {} + try { + final newRooms = await Room.listRooms(); + setState(() { + rooms = newRooms; + }); + } catch (_) {} }); WidgetsBinding.instance.addPostFrameCallback((_) => fetchList()); @@ -42,17 +42,17 @@ class _HomePageState extends State { try { final newRooms = await Room.listRooms(); setState(() { - rooms = newRooms; + rooms = newRooms; }); } catch (_) {} doNetworkRequest( sm, req: () => postWithCreadentials( - path: 'listRooms', credentials: user, target: user.server, body: {}), + path: 'listRooms', credentials: user, target: user.server, body: {}), onOK: (body) async { final List list = body['data'].map((json) { - return Room.fromJSON(json); + return Room.fromJSON(json); }).toList(); for (Room r in list) { await r.toDisk(); @@ -90,33 +90,33 @@ class _HomePageState extends State { }, menuChildren: [ MenuItemButton( - leadingIcon: const Icon(Icons.settings), - child: const Text('Settings'), + leadingIcon: const Icon(Icons.settings), + child: const Text('Settings'), + onPressed: () { + // show settings screen + context.goNamed('settings'); + }), + ...(context.watch() != null && + (context.watch()?.permissions)! & + ServerPermission.allManagement != + 0) + ? [ + MenuItemButton( + leadingIcon: const Icon(Icons.dns), + child: const Text('Server Dashboard'), onPressed: () { // show settings screen - Routemaster.of(context).push("/settings"); - }), - ...(context.watch() != null && - (context.watch()?.permissions)! & - ServerPermission.allManagement != - 0) - ? [ - MenuItemButton( - leadingIcon: const Icon(Icons.dns), - child: const Text('Server Dashboard'), - onPressed: () { - // show settings screen - Routemaster.of(context).push("/server"); - }), - ] - : [], + context.goNamed('dash'); + }), + ] + : [], MenuItemButton( - leadingIcon: const Icon(Icons.info_rounded), - child: const Text('About'), - onPressed: () { - // show about screen - Routemaster.of(context).push("/about"); - }), + leadingIcon: const Icon(Icons.info_rounded), + child: const Text('About'), + onPressed: () { + // show about screen + context.goNamed('about'); + }), ], ) ], @@ -126,31 +126,31 @@ class _HomePageState extends State { itemBuilder: (ctx, i) { final room = rooms[i]; return Card( - margin: const EdgeInsets.all(8.0), - clipBehavior: Clip.antiAliasWithSaveLayer, - semanticContainer: true, - child: InkWell( - onTap: () { - // open room - Routemaster.of(context) - .push("/r/${room.serverTag}/${room.id}"); - }, - onLongPress: () { - // open bottom sheet - // NOTE: feature yet to be confirmed - }, - child: Container( - padding: const EdgeInsets.fromLTRB(10, 5, 5, 10), - child: ListTile( - title: Text(room.name), - visualDensity: const VisualDensity(vertical: 3), - subtitle: Text(room.description), - leading: AspectRatio( - aspectRatio: 1 / 1, - child: SvgPicture.asset("${room.icon?.img}"), - ), - hoverColor: Colors.transparent, - )))); + margin: const EdgeInsets.all(8.0), + clipBehavior: Clip.antiAliasWithSaveLayer, + semanticContainer: true, + child: InkWell( + onTap: () { + // open room + context.goNamed('room', + params: {'server': room.serverTag, 'id': room.id}); + }, + onLongPress: () { + // open bottom sheet + // NOTE: feature yet to be confirmed + }, + child: Container( + padding: const EdgeInsets.fromLTRB(10, 5, 5, 10), + child: ListTile( + title: Text(room.name), + visualDensity: const VisualDensity(vertical: 3), + subtitle: Text(room.description), + leading: AspectRatio( + aspectRatio: 1 / 1, + child: SvgPicture.asset("${room.icon?.img}"), + ), + hoverColor: Colors.transparent, + )))); }, ), floatingActionButton: FloatingActionButton.extended( @@ -158,7 +158,7 @@ class _HomePageState extends State { icon: const Icon(Icons.add), onPressed: () { // create new room - Routemaster.of(context).push("/add-room"); + context.goNamed('add-room'); }, tooltip: 'Add new Room', ), diff --git a/lib/screens/room/edit.dart b/lib/screens/room/edit.dart index 4b58926..b1c2aec 100644 --- a/lib/screens/room/edit.dart +++ b/lib/screens/room/edit.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:go_router/go_router.dart'; import 'package:outbag_app/backend/errors.dart'; import 'package:outbag_app/backend/request.dart'; import 'package:outbag_app/backend/room.dart'; import 'package:outbag_app/backend/user.dart'; import 'package:outbag_app/tools/fetch_wrapper.dart'; import 'package:provider/provider.dart'; -import 'package:routemaster/routemaster.dart'; import 'dart:math'; class EditRoomPage extends StatefulWidget { @@ -44,7 +44,7 @@ class _EditRoomPageState extends State { // fetch room information void fetchInfo() { final sm = ScaffoldMessenger.of(context); - final rmaster = Routemaster.of(context); + final router = GoRouter.of(context); final user = context.read(); doNetworkRequest( @@ -69,7 +69,7 @@ class _EditRoomPageState extends State { } catch (_) { // no room data available // close screen - rmaster.replace('/'); + router.pushReplacementNamed('homoe'); } })(); return true; @@ -77,7 +77,7 @@ class _EditRoomPageState extends State { onServerErr: (json) { // user not allowed to be here // close screen - rmaster.replace('/'); + router.pushReplacementNamed('homoe'); return true; }, ); diff --git a/lib/screens/room/join.dart b/lib/screens/room/join.dart index 7eb19f1..adcbf44 100644 --- a/lib/screens/room/join.dart +++ b/lib/screens/room/join.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:go_router/go_router.dart'; import 'package:outbag_app/backend/request.dart'; import 'package:outbag_app/backend/room.dart'; import 'package:outbag_app/backend/user.dart'; import 'package:outbag_app/tools/fetch_wrapper.dart'; import 'package:provider/provider.dart'; -import 'package:routemaster/routemaster.dart'; import 'dart:math'; class JoinRoomPage extends StatefulWidget { @@ -99,14 +99,6 @@ class _JoinRoomPageState extends State { return Scaffold( appBar: AppBar( title: const Text('Join Room'), - leading: IconButton( - onPressed: () { - // go back - Routemaster.of(context).history.back(); - }, - icon: const Icon(Icons.arrow_back), - tooltip: "Go back", - ), actions: [ IconButton( icon: const Icon(Icons.search), @@ -143,7 +135,7 @@ class _JoinRoomPageState extends State { child: const Text('Join invite-only room'), onPressed: () { // show settings screen - Routemaster.of(context).push("/add-room/by-id"); + context.goNamed('join-room-ota'); }), ]) ], @@ -243,13 +235,13 @@ class _JoinRoomPageState extends State { final scaffMgr = ScaffoldMessenger.of( context); - final rmaster = - Routemaster.of( - context); + final nav = Navigator.of(context); final user = context.read(); + final router = + GoRouter.of(context); doNetworkRequest(scaffMgr, req: () => @@ -269,8 +261,14 @@ class _JoinRoomPageState extends State { onOK: (body) async { await room.toDisk(); nav.pop(); - rmaster.replace( - '/r/${room.serverTag}/${room.id}'); + router + .pushReplacementNamed( + 'room', + params: { + 'server': room + .serverTag, + 'id': room.id + }); }); }, )) @@ -300,7 +298,7 @@ class _JoinRoomPageState extends State { icon: const Icon(Icons.add), onPressed: () { // create new room - Routemaster.of(context).push("/add-room/new"); + context.goNamed('new-room'); }, tooltip: 'Create Room', ), diff --git a/lib/screens/room/main.dart b/lib/screens/room/main.dart index bbffa2a..339e624 100644 --- a/lib/screens/room/main.dart +++ b/lib/screens/room/main.dart @@ -8,7 +8,6 @@ import 'package:outbag_app/screens/room/pages/products.dart'; import 'package:outbag_app/screens/room/pages/list.dart'; import 'package:outbag_app/tools/fetch_wrapper.dart'; import 'package:provider/provider.dart'; -import 'package:routemaster/routemaster.dart'; class RoomPage extends StatefulWidget { final String server; @@ -105,14 +104,6 @@ class _RoomPageState extends State { return Scaffold( appBar: AppBar( title: Text(room?.name ?? 'Unknown Room'), - leading: IconButton( - onPressed: () { - // go back - Routemaster.of(context).history.back(); - }, - icon: const Icon(Icons.arrow_back), - tooltip: "Go back", - ), ), body: PageView( controller: _ctr, diff --git a/lib/screens/room/members.dart b/lib/screens/room/members.dart index bb538fa..6d920f8 100644 --- a/lib/screens/room/members.dart +++ b/lib/screens/room/members.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; import 'package:outbag_app/backend/permissions.dart'; import 'package:outbag_app/backend/request.dart'; import 'package:outbag_app/backend/room.dart'; import 'package:outbag_app/backend/user.dart'; import 'package:outbag_app/tools/fetch_wrapper.dart'; import 'package:provider/provider.dart'; -import 'package:routemaster/routemaster.dart'; class ManageRoomMembersPage extends StatefulWidget { final String server; @@ -22,7 +22,7 @@ class _ManageRoomMembersPageState extends State { RoomInfo? info; void fetchUserInfo() { - final rmaster = Routemaster.of(context); + final router = GoRouter.of(context); final sm = ScaffoldMessenger.of(context); final user = context.read(); @@ -36,7 +36,7 @@ class _ManageRoomMembersPageState extends State { onAnyErr: () { // user should not be here // close screen - rmaster.replace('/'); + router.pushReplacementNamed('home'); return false; }, onOK: (body) async { @@ -50,7 +50,7 @@ class _ManageRoomMembersPageState extends State { } void fetchMembers() { - final rmaster = Routemaster.of(context); + final router = GoRouter.of(context); final sm = ScaffoldMessenger.of(context); final user = context.read(); @@ -63,7 +63,7 @@ class _ManageRoomMembersPageState extends State { onAnyErr: () { // user should not be here // close screen - rmaster.replace('/'); + router.pushReplacementNamed('home'); return false; }, onOK: (body) { @@ -303,11 +303,7 @@ class _ManageRoomMembersPageState extends State { doNetworkRequest( scaffMgr, req: () => - postWithCreadentials( - path: 'kickMember', - credentials: user, - target: user.server, - body: { + postWithCreadentials(path: 'kickMember', credentials: user, target: user.server, body: { 'room': widget.tag, 'roomServer': widget.server, 'name': item.id, diff --git a/lib/screens/room/new.dart b/lib/screens/room/new.dart index 03024ba..6a144e0 100644 --- a/lib/screens/room/new.dart +++ b/lib/screens/room/new.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:go_router/go_router.dart'; import 'package:outbag_app/backend/request.dart'; import 'package:outbag_app/backend/room.dart'; import 'package:outbag_app/backend/user.dart'; import 'package:outbag_app/tools/fetch_wrapper.dart'; import 'package:outbag_app/tools/snackbar.dart'; import 'package:provider/provider.dart'; -import 'package:routemaster/routemaster.dart'; import 'dart:math'; class NewRoomPage extends StatefulWidget { @@ -48,14 +48,6 @@ class _NewRoomPageState extends State { : Scaffold( appBar: AppBar( title: const Text('New Room'), - leading: IconButton( - onPressed: () { - // go back - Routemaster.of(context).history.back(); - }, - icon: const Icon(Icons.arrow_back), - tooltip: "Go back", - ), ), body: SingleChildScrollView( child: Center( @@ -186,7 +178,7 @@ class _NewRoomPageState extends State { floatingActionButton: FloatingActionButton.extended( onPressed: () async { final scaffMgr = ScaffoldMessenger.of(context); - final rmaster = Routemaster.of(context); + final router = GoRouter.of(context); // ID should be at least three characters long if (_ctrID.text.length < 3) { @@ -233,7 +225,7 @@ class _NewRoomPageState extends State { // save room await room.toDisk(); // move to home page - rmaster.replace('/'); + router.pushReplacementNamed('home'); }); }, label: const Text('Create'), diff --git a/lib/screens/room/pages/about.dart b/lib/screens/room/pages/about.dart index 51a97c5..1559575 100644 --- a/lib/screens/room/pages/about.dart +++ b/lib/screens/room/pages/about.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:go_router/go_router.dart'; import 'package:outbag_app/backend/permissions.dart'; import 'package:outbag_app/backend/request.dart'; import 'package:outbag_app/backend/room.dart'; @@ -7,7 +8,6 @@ import 'package:outbag_app/backend/user.dart'; import 'dart:math'; import 'package:outbag_app/tools/fetch_wrapper.dart'; import 'package:provider/provider.dart'; -import 'package:routemaster/routemaster.dart'; class AboutRoomPage extends StatefulWidget { final RoomInfo? info; @@ -161,8 +161,10 @@ class _AboutRoomPageState extends State { 'Change the rooms name, description and icon'), onTap: () { // show edit room screen - Routemaster.of(context).push( - '/r/${widget.room?.serverTag}/${widget.room?.id}/edit'); + context.goNamed('edit-room', params: { + 'server': (widget.room?.serverTag)!, + 'id': (widget.room?.id)! + }); }, ), ] @@ -174,8 +176,10 @@ class _AboutRoomPageState extends State { subtitle: const Text('Show Member list'), onTap: () { // open member view screen - Routemaster.of(context).push( - '/r/${widget.room?.serverTag}/${widget.room?.id}/members'); + context.goNamed('room-members', params: { + 'server': (widget.room?.serverTag)!, + 'id': (widget.room?.id)! + }); }, ), // edit default member permission @@ -193,8 +197,10 @@ class _AboutRoomPageState extends State { 'Change the default permission-set for all members'), onTap: () { // show checkbox screen - Routemaster.of(context).push( - '/r/${widget.room?.serverTag}/${widget.room?.id}/permissions'); + context.goNamed('room-permissions', params: { + 'server': (widget.room?.serverTag)!, + 'id': (widget.room?.id)! + }); }, ), ] @@ -211,8 +217,10 @@ class _AboutRoomPageState extends State { subtitle: const Text('Add and delete OTAs'), onTap: () { // show manage ota screen - Routemaster.of(context).push( - '/r/${widget.room?.serverTag}/${widget.room?.id}/ota'); + context.goNamed('room-ota', params: { + 'server': (widget.room?.serverTag)!, + 'id': (widget.room?.id)! + }); }, ), ListTile( @@ -221,8 +229,10 @@ class _AboutRoomPageState extends State { subtitle: const Text('Invite people to this room'), onTap: () { // show manage ota screen - Routemaster.of(context).push( - '/r/${widget.room?.serverTag}/${widget.room?.id}/invite'); + context.goNamed('room-invite', params: { + 'server': (widget.room?.serverTag)!, + 'id': (widget.room?.id)! + }); }, ), ] @@ -262,7 +272,7 @@ class _AboutRoomPageState extends State { final scaffMgr = ScaffoldMessenger.of(ctx); final nav = Navigator.of(ctx); - final rmaster = Routemaster.of(ctx); + final router = GoRouter.of(ctx); final user = ctx.read(); doNetworkRequest(scaffMgr, @@ -284,7 +294,7 @@ class _AboutRoomPageState extends State { } catch (_) {} // go back home - rmaster.replace('/'); + router.pushReplacementNamed('home'); }, after: () { // close popup diff --git a/lib/screens/room/permissions.dart b/lib/screens/room/permissions.dart index 9d57b0d..c502495 100644 --- a/lib/screens/room/permissions.dart +++ b/lib/screens/room/permissions.dart @@ -1,13 +1,13 @@ import 'dart:math'; import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; import 'package:outbag_app/backend/permissions.dart'; import 'package:outbag_app/backend/request.dart'; import 'package:outbag_app/backend/room.dart'; import 'package:outbag_app/backend/user.dart'; import 'package:outbag_app/tools/fetch_wrapper.dart'; import 'package:provider/provider.dart'; -import 'package:routemaster/routemaster.dart'; class EditRoomPermissionSetPage extends StatefulWidget { final String server; @@ -24,7 +24,7 @@ class _EditRoomPermissionSetPageState extends State { int permissions = 0; void fetchInfo() { - final rmaster = Routemaster.of(context); + final router = GoRouter.of(context); final sm = ScaffoldMessenger.of(context); final user = context.read(); @@ -38,7 +38,7 @@ class _EditRoomPermissionSetPageState extends State { onAnyErr: () { // user should not be here // close screen - rmaster.replace('/'); + router.pushReplacementNamed('home'); return false; }, onOK: (body) async { @@ -95,7 +95,7 @@ class _EditRoomPermissionSetPageState extends State { tooltip: "Update default permission set", label: const Text('Edit'), onPressed: () { - final rmaster = Routemaster.of(context); + final router = GoRouter.of(context); final sm = ScaffoldMessenger.of(context); final user = context.read(); @@ -111,7 +111,7 @@ class _EditRoomPermissionSetPageState extends State { 'rights': permissions }), onOK: (_) { - rmaster.pop(); + router.pop(); }); }, ), diff --git a/lib/screens/settings/main.dart b/lib/screens/settings/main.dart index a9a20b4..7531ed5 100644 --- a/lib/screens/settings/main.dart +++ b/lib/screens/settings/main.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; import 'package:outbag_app/backend/request.dart'; import 'package:outbag_app/backend/themes.dart'; import 'package:outbag_app/backend/user.dart'; import 'package:outbag_app/screens/settings/dialogs/password.dart'; import 'package:outbag_app/tools/fetch_wrapper.dart'; import 'package:provider/provider.dart'; -import 'package:routemaster/routemaster.dart'; class SettingsPage extends StatefulWidget { const SettingsPage({super.key}); @@ -27,14 +27,6 @@ class _SettingsPageState extends State { return Scaffold( appBar: AppBar( title: const Text('Settings'), - leading: IconButton( - onPressed: () { - // go back - Navigator.of(context).pop(); - }, - icon: const Icon(Icons.arrow_back), - tooltip: "Go back", - ), ), body: SingleChildScrollView( child: Center( @@ -182,7 +174,7 @@ class _SettingsPageState extends State { // send request final scaffMgr = ScaffoldMessenger.of(ctx); final nav = Navigator.of(ctx); - final rmaster = Routemaster.of(ctx); + final router = GoRouter.of(ctx); doNetworkRequest(scaffMgr, req: () => postWithCreadentials( @@ -199,7 +191,7 @@ class _SettingsPageState extends State { // TODO: delete all rooms // go back home - rmaster.replace('/'); + router.pushReplacementNamed('home'); }, after: () { // close popup @@ -238,7 +230,7 @@ class _SettingsPageState extends State { FilledButton( onPressed: () async { // send request - final rmaster = Routemaster.of(ctx); + final router = GoRouter.of(ctx); // delete everything // delete user data (meta) @@ -248,7 +240,7 @@ class _SettingsPageState extends State { // TODO: delete all rooms // go back home - rmaster.replace('/'); + router.pushReplacementNamed('home'); }, child: const Text('Log out'), ) diff --git a/lib/screens/welcome.dart b/lib/screens/welcome.dart index 344a6f1..d593a73 100644 --- a/lib/screens/welcome.dart +++ b/lib/screens/welcome.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; import 'package:outbag_app/tools/assets.dart'; -import 'package:routemaster/routemaster.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'dart:math'; @@ -63,9 +63,8 @@ class _WelcomePageState extends State { children: [ SvgPicture.asset(asset("undraw/undraw_shopping_app.svg"), fit: BoxFit.contain, - width: smallest*0.5, - height: smallest*0.5 - ), + width: smallest * 0.5, + height: smallest * 0.5), Text( 'Welcome to Outbag', style: textTheme.displaySmall, @@ -79,8 +78,8 @@ class _WelcomePageState extends State { children: [ SvgPicture.asset(asset("undraw/undraw_mobile_login.svg"), fit: BoxFit.contain, - width: smallest*0.5, - height: smallest*0.5), + width: smallest * 0.5, + height: smallest * 0.5), Text( 'Open. Decentralized', style: textTheme.displaySmall, @@ -95,8 +94,8 @@ class _WelcomePageState extends State { children: [ SvgPicture.asset(asset("undraw/undraw_online_connection.svg"), fit: BoxFit.contain, - width: smallest*0.5, - height: smallest*0.5), + width: smallest * 0.5, + height: smallest * 0.5), Text( 'Made to share', style: textTheme.displaySmall, @@ -111,8 +110,8 @@ class _WelcomePageState extends State { children: [ SvgPicture.asset(asset("undraw/undraw_online_groceries.svg"), fit: BoxFit.contain, - width: smallest*0.5, - height: smallest*0.5), + width: smallest * 0.5, + height: smallest * 0.5), Text( 'Pocket-sized', style: textTheme.displaySmall, @@ -125,7 +124,7 @@ class _WelcomePageState extends State { )), TextButton( onPressed: () { - Routemaster.of(context).push("/signin"); + context.goNamed('signin'); }, child: const Text('I already have an account'), ) @@ -138,7 +137,7 @@ class _WelcomePageState extends State { onPressed: () { if (controller.page == 4 - 1) { // open signup screen - Routemaster.of(context).push("/signup"); + context.goNamed('signup'); } else { // move to next page controller.nextPage( diff --git a/pubspec.lock b/pubspec.lock index 01d40d7..ca4d5e1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -152,6 +152,14 @@ packages: description: flutter source: sdk version: "0.0.0" + go_router: + dependency: "direct main" + description: + name: go_router + sha256: "432409518740645ce7f28802171b78783197d01149fad44f9b8ae55f40277139" + url: "https://pub.dev" + source: hosted + version: "6.5.0" http: dependency: "direct main" description: @@ -208,6 +216,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.5" + logging: + dependency: transitive + description: + name: logging + sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d" + url: "https://pub.dev" + source: hosted + version: "1.1.1" matcher: dependency: transitive description: @@ -352,14 +368,6 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.5" - routemaster: - dependency: "direct main" - description: - name: routemaster - sha256: b3b10b6ee31c741b453091e6b33323cc96631b19e4a14fc6069e9de056c7311c - url: "https://pub.dev" - source: hosted - version: "1.0.1" sky_engine: dependency: transitive description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 3aaa468..2c0fee9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,12 +30,12 @@ environment: dependencies: flutter: sdk: flutter - routemaster: ^1.0.1 flutter_svg: ^2.0.4 http: ^0.13.5 localstore: ^1.3.5 crypto: ^3.0.2 provider: ^6.0.5 + go_router: ^6.5.0 dev_dependencies: flutter_test: