From d6b48091c4d7d8e0a11c4a6cdd389d64b3607b1f Mon Sep 17 00:00:00 2001 From: Krille Date: Fri, 11 Aug 2023 09:59:58 +0200 Subject: [PATCH] refactor: Make router static --- lib/config/routes.dart | 574 +++++++++++----------- lib/widgets/fluffy_chat_app.dart | 8 +- lib/widgets/layouts/side_view_layout.dart | 24 +- 3 files changed, 308 insertions(+), 298 deletions(-) diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 0eeeb2124..92a93d1c9 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -1,7 +1,8 @@ +import 'dart:async'; + import 'package:flutter/cupertino.dart'; import 'package:go_router/go_router.dart'; -import 'package:matrix/matrix.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/add_story/add_story.dart'; @@ -33,235 +34,236 @@ import 'package:fluffychat/widgets/layouts/empty_page.dart'; import 'package:fluffychat/widgets/layouts/side_view_layout.dart'; import 'package:fluffychat/widgets/layouts/two_column_layout.dart'; import 'package:fluffychat/widgets/log_view.dart'; +import 'package:fluffychat/widgets/matrix.dart'; -class AppRoutes { - final List clients; +abstract class AppRoutes { + static FutureOr loggedInRedirect( + BuildContext context, + GoRouterState state, + ) => + Matrix.of(context).client.isLogged() ? '/rooms' : null; - bool get isLoggedIn => clients.any((client) => client.isLogged()); + static FutureOr loggedOutRedirect( + BuildContext context, + GoRouterState state, + ) => + Matrix.of(context).client.isLogged() ? null : '/home'; - AppRoutes(this.clients); + AppRoutes(); - List get routes => [ + static final List routes = [ + GoRoute( + path: '/', + redirect: (context, state) => + Matrix.of(context).client.isLogged() ? '/rooms' : '/home', + ), + GoRoute( + path: '/home', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const HomeserverPicker(), + ), + redirect: loggedInRedirect, + routes: [ GoRoute( - path: '/', - redirect: (context, state) => isLoggedIn ? '/rooms' : '/home', + path: 'login', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const Login(), + ), + redirect: loggedInRedirect, ), + ], + ), + GoRoute( + path: '/logs', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const LogViewer(), + ), + ), + ShellRoute( + pageBuilder: (context, state, child) => defaultPageBuilder( + context, + FluffyThemes.isColumnMode(context) && + state.fullPath?.startsWith('/rooms/settings') == false + ? TwoColumnLayout( + displayNavigationRail: + state.path?.startsWith('/rooms/settings') != true, + mainView: ChatList( + activeChat: state.pathParameters['roomid'], + displayNavigationRail: + state.path?.startsWith('/rooms/settings') != true, + ), + sideView: child, + ) + : child, + ), + routes: [ GoRoute( - path: '/home', + path: '/rooms', + redirect: loggedOutRedirect, pageBuilder: (context, state) => defaultPageBuilder( context, - const HomeserverPicker(), + FluffyThemes.isColumnMode(context) + ? const EmptyPage() + : ChatList( + activeChat: state.pathParameters['roomid'], + ), ), - redirect: (context, state) => isLoggedIn ? '/rooms' : null, routes: [ GoRoute( - path: 'login', + path: 'stories/create', pageBuilder: (context, state) => defaultPageBuilder( context, - const Login(), + const AddStoryPage(), ), - redirect: (context, state) => isLoggedIn ? '/rooms' : null, + redirect: loggedOutRedirect, ), - ], - ), - GoRoute( - path: '/logs', - pageBuilder: (context, state) => defaultPageBuilder( - context, - const LogViewer(), - ), - ), - ShellRoute( - pageBuilder: (context, state, child) => defaultPageBuilder( - context, - FluffyThemes.isColumnMode(context) && - state.fullPath?.startsWith('/rooms/settings') == false - ? TwoColumnLayout( - displayNavigationRail: - state.path?.startsWith('/rooms/settings') != true, - mainView: ChatList( - activeChat: state.pathParameters['roomid'], - displayNavigationRail: - state.path?.startsWith('/rooms/settings') != true, - ), - sideView: child, - ) - : child, - ), - routes: [ GoRoute( - path: '/rooms', - redirect: (context, state) => !isLoggedIn ? '/home' : null, + path: 'stories/:roomid', pageBuilder: (context, state) => defaultPageBuilder( context, - FluffyThemes.isColumnMode(context) - ? const EmptyPage() - : ChatList( - activeChat: state.pathParameters['roomid'], - ), + const StoryPage(), ), + redirect: loggedOutRedirect, routes: [ GoRoute( - path: 'stories/create', + path: 'share', pageBuilder: (context, state) => defaultPageBuilder( context, const AddStoryPage(), ), - redirect: (context, state) => !isLoggedIn ? '/home' : null, + redirect: loggedOutRedirect, ), - GoRoute( - path: 'stories/:roomid', - pageBuilder: (context, state) => defaultPageBuilder( - context, - const StoryPage(), - ), - redirect: (context, state) => !isLoggedIn ? '/home' : null, - routes: [ - GoRoute( - path: 'share', - pageBuilder: (context, state) => defaultPageBuilder( - context, - const AddStoryPage(), - ), - redirect: (context, state) => - !isLoggedIn ? '/home' : null, - ), - ], + ], + ), + GoRoute( + path: 'spaces/:roomid', + pageBuilder: (context, state) => defaultPageBuilder( + context, + ChatDetails( + roomId: state.pathParameters['roomid']!, ), + ), + routes: _chatDetailsRoutes, + redirect: loggedOutRedirect, + ), + GoRoute( + path: 'archive', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const Archive(), + ), + routes: [ GoRoute( - path: 'spaces/:roomid', + path: ':roomid', pageBuilder: (context, state) => defaultPageBuilder( context, - ChatDetails( + ChatPage( roomId: state.pathParameters['roomid']!, ), ), - routes: _chatDetailsRoutes, - redirect: (context, state) => !isLoggedIn ? '/home' : null, - ), - GoRoute( - path: 'archive', - pageBuilder: (context, state) => defaultPageBuilder( - context, - const Archive(), - ), - routes: [ - GoRoute( - path: ':roomid', - pageBuilder: (context, state) => defaultPageBuilder( - context, - ChatPage( - roomId: state.pathParameters['roomid']!, - ), - ), - redirect: (context, state) => - !isLoggedIn ? '/home' : null, - ), - ], - redirect: (context, state) => !isLoggedIn ? '/home' : null, + redirect: loggedOutRedirect, ), + ], + redirect: loggedOutRedirect, + ), + GoRoute( + path: 'newprivatechat', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const NewPrivateChat(), + ), + redirect: loggedOutRedirect, + ), + GoRoute( + path: 'newgroup', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const NewGroup(), + ), + redirect: loggedOutRedirect, + ), + GoRoute( + path: 'newspace', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const NewSpace(), + ), + redirect: loggedOutRedirect, + ), + ShellRoute( + pageBuilder: (context, state, child) => defaultPageBuilder( + context, + FluffyThemes.isColumnMode(context) + ? TwoColumnLayout( + mainView: const Settings(), + sideView: child, + displayNavigationRail: false, + ) + : child, + ), + routes: [ GoRoute( - path: 'newprivatechat', + path: 'settings', pageBuilder: (context, state) => defaultPageBuilder( context, - const NewPrivateChat(), + FluffyThemes.isColumnMode(context) + ? const EmptyPage() + : const Settings(), ), - redirect: (context, state) => !isLoggedIn ? '/home' : null, + routes: _settingsRoutes, + redirect: loggedOutRedirect, ), - GoRoute( - path: 'newgroup', - pageBuilder: (context, state) => defaultPageBuilder( - context, - const NewGroup(), + ], + ), + ShellRoute( + pageBuilder: (context, state, child) => defaultPageBuilder( + context, + SideViewLayout( + mainView: ChatPage( + roomId: state.pathParameters['roomid']!, ), - redirect: (context, state) => !isLoggedIn ? '/home' : null, + sideView: child, + hideSideView: state.fullPath == '/rooms/:roomid', ), + ), + routes: [ GoRoute( - path: 'newspace', + path: ':roomid', pageBuilder: (context, state) => defaultPageBuilder( context, - const NewSpace(), - ), - redirect: (context, state) => !isLoggedIn ? '/home' : null, - ), - ShellRoute( - pageBuilder: (context, state, child) => defaultPageBuilder( - context, - FluffyThemes.isColumnMode(context) - ? TwoColumnLayout( - mainView: const Settings(), - sideView: child, - displayNavigationRail: false, - ) - : child, + const SizedBox.shrink(), ), + redirect: loggedOutRedirect, routes: [ GoRoute( - path: 'settings', + path: 'encryption', pageBuilder: (context, state) => defaultPageBuilder( context, - FluffyThemes.isColumnMode(context) - ? const EmptyPage() - : const Settings(), + const ChatEncryptionSettings(), ), - routes: _settingsRoutes, - redirect: (context, state) => - !isLoggedIn ? '/home' : null, + redirect: loggedOutRedirect, ), - ], - ), - ShellRoute( - pageBuilder: (context, state, child) => defaultPageBuilder( - context, - SideViewLayout( - mainView: ChatPage( - roomId: state.pathParameters['roomid']!, + GoRoute( + path: 'invite', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const InvitationSelection(), ), - sideView: - state.fullPath == '/rooms/:roomid' ? null : child, + redirect: loggedOutRedirect, ), - ), - routes: [ GoRoute( - path: ':roomid', + path: 'details', pageBuilder: (context, state) => defaultPageBuilder( context, - const EmptyPage(), - ), - redirect: (context, state) => - !isLoggedIn ? '/home' : null, - routes: [ - GoRoute( - path: 'encryption', - pageBuilder: (context, state) => defaultPageBuilder( - context, - const ChatEncryptionSettings(), - ), - redirect: (context, state) => - !isLoggedIn ? '/home' : null, - ), - GoRoute( - path: 'invite', - pageBuilder: (context, state) => defaultPageBuilder( - context, - const InvitationSelection(), - ), - redirect: (context, state) => - !isLoggedIn ? '/home' : null, - ), - GoRoute( - path: 'details', - pageBuilder: (context, state) => defaultPageBuilder( - context, - ChatDetails( - roomId: state.pathParameters['roomid']!, - ), - ), - routes: _chatDetailsRoutes, - redirect: (context, state) => - !isLoggedIn ? '/home' : null, + ChatDetails( + roomId: state.pathParameters['roomid']!, ), - ], + ), + routes: _chatDetailsRoutes, + redirect: loggedOutRedirect, ), ], ), @@ -269,148 +271,150 @@ class AppRoutes { ), ], ), - ]; + ], + ), + ]; - List get _chatDetailsRoutes => [ - GoRoute( - path: 'permissions', - pageBuilder: (context, state) => defaultPageBuilder( - context, - const ChatPermissionsSettings(), - ), - redirect: (context, state) => !isLoggedIn ? '/home' : null, - ), - GoRoute( - path: 'invite', - pageBuilder: (context, state) => defaultPageBuilder( - context, - const InvitationSelection(), - ), - redirect: (context, state) => !isLoggedIn ? '/home' : null, - ), - GoRoute( - path: 'multiple_emotes', - pageBuilder: (context, state) => defaultPageBuilder( - context, - const MultipleEmotesSettings(), - ), - redirect: (context, state) => !isLoggedIn ? '/home' : null, - ), + static final List _chatDetailsRoutes = [ + GoRoute( + path: 'permissions', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const ChatPermissionsSettings(), + ), + redirect: loggedOutRedirect, + ), + GoRoute( + path: 'invite', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const InvitationSelection(), + ), + redirect: loggedOutRedirect, + ), + GoRoute( + path: 'multiple_emotes', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const MultipleEmotesSettings(), + ), + redirect: loggedOutRedirect, + ), + GoRoute( + path: 'emotes', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const EmotesSettings(), + ), + redirect: loggedOutRedirect, + ), + GoRoute( + path: 'emotes/:state_key', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const EmotesSettings(), + ), + redirect: loggedOutRedirect, + ), + ]; + + static final List _settingsRoutes = [ + GoRoute( + path: 'notifications', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const SettingsNotifications(), + ), + redirect: loggedOutRedirect, + ), + GoRoute( + path: 'style', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const SettingsStyle(), + ), + redirect: loggedOutRedirect, + ), + GoRoute( + path: 'devices', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const DevicesSettings(), + ), + redirect: loggedOutRedirect, + ), + GoRoute( + path: 'chat', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const SettingsChat(), + ), + routes: [ GoRoute( path: 'emotes', pageBuilder: (context, state) => defaultPageBuilder( context, const EmotesSettings(), ), - redirect: (context, state) => !isLoggedIn ? '/home' : null, - ), - GoRoute( - path: 'emotes/:state_key', - pageBuilder: (context, state) => defaultPageBuilder( - context, - const EmotesSettings(), - ), - redirect: (context, state) => !isLoggedIn ? '/home' : null, - ), - ]; - - List get _settingsRoutes => [ - GoRoute( - path: 'notifications', - pageBuilder: (context, state) => defaultPageBuilder( - context, - const SettingsNotifications(), - ), - redirect: (context, state) => !isLoggedIn ? '/home' : null, ), + ], + redirect: loggedOutRedirect, + ), + GoRoute( + path: 'addaccount', + redirect: loggedOutRedirect, + pageBuilder: (context, state) => defaultPageBuilder( + context, + const HomeserverPicker(), + ), + routes: [ GoRoute( - path: 'style', + path: 'login', pageBuilder: (context, state) => defaultPageBuilder( context, - const SettingsStyle(), + const Login(), ), - redirect: (context, state) => !isLoggedIn ? '/home' : null, + redirect: loggedOutRedirect, ), + ], + ), + GoRoute( + path: 'security', + redirect: loggedOutRedirect, + pageBuilder: (context, state) => defaultPageBuilder( + context, + const SettingsSecurity(), + ), + routes: [ GoRoute( - path: 'devices', + path: 'stories', pageBuilder: (context, state) => defaultPageBuilder( context, - const DevicesSettings(), + const SettingsStories(), ), - redirect: (context, state) => !isLoggedIn ? '/home' : null, + redirect: loggedOutRedirect, ), GoRoute( - path: 'chat', + path: 'ignorelist', pageBuilder: (context, state) => defaultPageBuilder( context, - const SettingsChat(), + const SettingsIgnoreList(), ), - routes: [ - GoRoute( - path: 'emotes', - pageBuilder: (context, state) => defaultPageBuilder( - context, - const EmotesSettings(), - ), - ), - ], - redirect: (context, state) => !isLoggedIn ? '/home' : null, - ), - GoRoute( - path: 'addaccount', - redirect: (context, state) => !isLoggedIn ? '/home' : null, - pageBuilder: (context, state) => defaultPageBuilder( - context, - const HomeserverPicker(), - ), - routes: [ - GoRoute( - path: 'login', - pageBuilder: (context, state) => defaultPageBuilder( - context, - const Login(), - ), - redirect: (context, state) => !isLoggedIn ? '/home' : null, - ), - ], + redirect: loggedOutRedirect, ), GoRoute( - path: 'security', - redirect: (context, state) => !isLoggedIn ? '/home' : null, + path: '3pid', pageBuilder: (context, state) => defaultPageBuilder( context, - const SettingsSecurity(), + const Settings3Pid(), ), - routes: [ - GoRoute( - path: 'stories', - pageBuilder: (context, state) => defaultPageBuilder( - context, - const SettingsStories(), - ), - redirect: (context, state) => !isLoggedIn ? '/home' : null, - ), - GoRoute( - path: 'ignorelist', - pageBuilder: (context, state) => defaultPageBuilder( - context, - const SettingsIgnoreList(), - ), - redirect: (context, state) => !isLoggedIn ? '/home' : null, - ), - GoRoute( - path: '3pid', - pageBuilder: (context, state) => defaultPageBuilder( - context, - const Settings3Pid(), - ), - redirect: (context, state) => !isLoggedIn ? '/home' : null, - ), - ], + redirect: loggedOutRedirect, ), - ]; + ], + ), + ]; - Page defaultPageBuilder(BuildContext context, Widget child) => + static Page defaultPageBuilder(BuildContext context, Widget child) => CustomTransitionPage( child: child, transitionsBuilder: (context, animation, secondaryAnimation, child) => diff --git a/lib/widgets/fluffy_chat_app.dart b/lib/widgets/fluffy_chat_app.dart index 21519b3b3..a8013d48a 100644 --- a/lib/widgets/fluffy_chat_app.dart +++ b/lib/widgets/fluffy_chat_app.dart @@ -26,6 +26,10 @@ class FluffyChatApp extends StatelessWidget { /// in with qr code or magic link. static bool gotInitialLink = false; + // Router must be outside of build method so that hot reload does not reset + // the current path. + static final GoRouter router = GoRouter(routes: AppRoutes.routes); + @override Widget build(BuildContext context) { return ThemeBuilder( @@ -37,11 +41,11 @@ class FluffyChatApp extends StatelessWidget { scrollBehavior: CustomScrollBehavior(), localizationsDelegates: L10n.localizationsDelegates, supportedLocales: L10n.supportedLocales, - routerConfig: GoRouter(routes: AppRoutes(clients).routes), + routerConfig: router, builder: (context, child) => Matrix( context: context, clients: clients, - child: child, + child: testWidget ?? child, ), ), ); diff --git a/lib/widgets/layouts/side_view_layout.dart b/lib/widgets/layouts/side_view_layout.dart index 27c403920..4162350f6 100644 --- a/lib/widgets/layouts/side_view_layout.dart +++ b/lib/widgets/layouts/side_view_layout.dart @@ -4,16 +4,20 @@ import 'package:fluffychat/config/themes.dart'; class SideViewLayout extends StatelessWidget { final Widget mainView; - final Widget? sideView; + final Widget sideView; + final bool hideSideView; - const SideViewLayout({Key? key, required this.mainView, this.sideView}) - : super(key: key); + const SideViewLayout({ + Key? key, + required this.mainView, + required this.sideView, + required this.hideSideView, + }) : super(key: key); @override Widget build(BuildContext context) { final sideView = this.sideView; - final hideSideView = - !FluffyThemes.isThreeColumnMode(context) || sideView == null; const sideViewWidth = 360.0; + final threeColumnMode = FluffyThemes.isThreeColumnMode(context); return Stack( children: [ AnimatedPositioned( @@ -22,7 +26,7 @@ class SideViewLayout extends StatelessWidget { top: 0, left: 0, bottom: 0, - right: hideSideView ? 0 : sideViewWidth, + right: !threeColumnMode || hideSideView ? 0 : sideViewWidth, child: ClipRRect(child: mainView), ), AnimatedPositioned( @@ -31,12 +35,10 @@ class SideViewLayout extends StatelessWidget { bottom: 0, top: 0, right: 0, - left: !FluffyThemes.isThreeColumnMode(context) && sideView != null + left: !threeColumnMode && !hideSideView ? 0 : null, + width: hideSideView ? 0 - : null, - width: sideView == null - ? 0 - : !FluffyThemes.isThreeColumnMode(context) + : !threeColumnMode ? null : sideViewWidth, child: Container(