diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 2f409ab2..8e709d30 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -1,7 +1,9 @@ -import 'package:flutter/material.dart'; +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'; import 'package:fluffychat/pages/archive/archive.dart'; import 'package:fluffychat/pages/chat/chat.dart'; @@ -28,351 +30,402 @@ import 'package:fluffychat/pages/settings_stories/settings_stories.dart'; import 'package:fluffychat/pages/settings_style/settings_style.dart'; import 'package:fluffychat/pages/story/story_page.dart'; import 'package:fluffychat/widgets/layouts/empty_page.dart'; -import 'package:fluffychat/widgets/layouts/loading_view.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'; class AppRoutes { - final bool columnMode; + final List clients; - AppRoutes(this.columnMode); + bool get isLoggedIn => clients.any((client) => client.isLogged()); - List get routes => [ - ..._homeRoutes, - if (columnMode) ..._tabletRoutes, - if (!columnMode) ..._mobileRoutes, - ]; + AppRoutes(this.clients); - List get _mobileRoutes => [ - VWidget( - path: '/rooms', - widget: const ChatList(), - stackedRoutes: [ - VWidget( - path: '/stories/create', - widget: const AddStoryPage(), - ), - VWidget( - path: '/stories/:roomid', - widget: const StoryPage(), - stackedRoutes: [ - VWidget( - path: 'share', - widget: const AddStoryPage(), - ), - ], - ), - VWidget( - path: '/spaces/:roomid', - widget: const ChatDetails(), - stackedRoutes: _chatDetailsRoutes, - ), - VWidget( - path: ':roomid', - widget: const ChatPage(), - stackedRoutes: [ - VWidget( - path: 'encryption', - widget: const ChatEncryptionSettings(), - ), - VWidget( - path: 'invite', - widget: const InvitationSelection(), - ), - VWidget( - path: 'details', - widget: const ChatDetails(), - stackedRoutes: _chatDetailsRoutes, - ), - ], - ), - VWidget( - path: '/settings', - widget: const Settings(), - stackedRoutes: _settingsRoutes, - ), - VWidget( - path: '/archive', - widget: const Archive(), - stackedRoutes: [ - VWidget( - path: ':roomid', - widget: const ChatPage(), - buildTransition: _dynamicTransition, - ), - ], - ), - VWidget( - path: '/newprivatechat', - widget: const NewPrivateChat(), - ), - VWidget( - path: '/newgroup', - widget: const NewGroup(), - ), - VWidget( - path: '/newspace', - widget: const NewSpace(), - ), - ], + List get routes => [ + GoRoute( + path: '/', + redirect: (context, state) => isLoggedIn ? '/rooms' : '/home', ), - ]; - List get _tabletRoutes => [ - VNester( - path: '/rooms', - widgetBuilder: (child) => TwoColumnLayout( - mainView: const ChatList(), - sideView: child, - ), - buildTransition: _fadeTransition, - nestedRoutes: [ - VWidget( - path: '', - widget: const EmptyPage(), - buildTransition: _fadeTransition, - stackedRoutes: [ - VWidget( - path: '/stories/create', - buildTransition: _fadeTransition, - widget: const AddStoryPage(), - ), - VWidget( - path: '/stories/:roomid', - buildTransition: _fadeTransition, - widget: const StoryPage(), - stackedRoutes: [ - VWidget( - path: 'share', - widget: const AddStoryPage(), - ), - ], - ), - VWidget( - path: '/spaces/:roomid', - widget: const ChatDetails(), - buildTransition: _fadeTransition, - stackedRoutes: _chatDetailsRoutes, - ), - VWidget( - path: '/newprivatechat', - widget: const NewPrivateChat(), - buildTransition: _fadeTransition, - ), - VWidget( - path: '/newgroup', - widget: const NewGroup(), - buildTransition: _fadeTransition, - ), - VWidget( - path: '/newspace', - widget: const NewSpace(), - buildTransition: _fadeTransition, - ), - VNester( - path: ':roomid', - widgetBuilder: (child) => SideViewLayout( - mainView: const ChatPage(), - sideView: child, - ), - buildTransition: _fadeTransition, - nestedRoutes: [ - VWidget( - path: '', - widget: const ChatPage(), - buildTransition: _fadeTransition, - ), - VWidget( - path: 'encryption', - widget: const ChatEncryptionSettings(), - buildTransition: _fadeTransition, - ), - VWidget( - path: 'details', - widget: const ChatDetails(), - buildTransition: _fadeTransition, - stackedRoutes: _chatDetailsRoutes, - ), - VWidget( - path: 'invite', - widget: const InvitationSelection(), - buildTransition: _fadeTransition, - ), - ], - ), - ], - ), - ], - ), - VWidget( - path: '/rooms', - widget: const TwoColumnLayout( - mainView: ChatList(), - sideView: EmptyPage(), - ), - buildTransition: _fadeTransition, - stackedRoutes: [ - VNester( - path: '/settings', - widgetBuilder: (child) => TwoColumnLayout( - mainView: const Settings(), - sideView: child, - ), - buildTransition: _dynamicTransition, - nestedRoutes: [ - VWidget( - path: '', - widget: const EmptyPage(), - buildTransition: _dynamicTransition, - stackedRoutes: _settingsRoutes, - ), - ], - ), - VNester( - path: '/archive', - widgetBuilder: (child) => TwoColumnLayout( - mainView: const Archive(), - sideView: child, - ), - buildTransition: _fadeTransition, - nestedRoutes: [ - VWidget( - path: '', - widget: const EmptyPage(), - buildTransition: _dynamicTransition, - ), - VWidget( - path: ':roomid', - widget: const ChatPage(), - buildTransition: _dynamicTransition, - ), - ], - ), - ], - ), - ]; - - List get _homeRoutes => [ - VWidget(path: '/', widget: const LoadingView()), - VWidget( + GoRoute( path: '/home', - widget: const HomeserverPicker(), - buildTransition: _fadeTransition, - stackedRoutes: [ - VWidget( + pageBuilder: (context, state) => defaultPageBuilder( + context, + const HomeserverPicker(), + ), + redirect: (context, state) => isLoggedIn ? '/rooms' : null, + routes: [ + GoRoute( path: 'login', - widget: const Login(), - buildTransition: _fadeTransition, + pageBuilder: (context, state) => defaultPageBuilder( + context, + const Login(), + ), + redirect: (context, state) => isLoggedIn ? '/rooms' : null, ), - VWidget( - path: 'logs', - widget: const LogViewer(), - buildTransition: _dynamicTransition, + ], + ), + 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, + pageBuilder: (context, state) => defaultPageBuilder( + context, + FluffyThemes.isColumnMode(context) + ? const EmptyPage() + : ChatList( + activeChat: state.pathParameters['roomid'], + ), + ), + routes: [ + GoRoute( + path: 'stories/create', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const AddStoryPage(), + ), + redirect: (context, state) => !isLoggedIn ? '/home' : null, + ), + 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: (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, + ), + GoRoute( + path: 'newprivatechat', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const NewPrivateChat(), + ), + redirect: (context, state) => !isLoggedIn ? '/home' : null, + ), + GoRoute( + path: 'newgroup', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const NewGroup(), + ), + redirect: (context, state) => !isLoggedIn ? '/home' : null, + ), + GoRoute( + path: 'newspace', + 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, + ), + routes: [ + GoRoute( + path: 'settings', + pageBuilder: (context, state) => defaultPageBuilder( + context, + FluffyThemes.isColumnMode(context) + ? const EmptyPage() + : const Settings(), + ), + routes: _settingsRoutes, + redirect: (context, state) => + !isLoggedIn ? '/home' : null, + ), + ], + ), + GoRoute( + path: ':roomid', + pageBuilder: (context, state) => defaultPageBuilder( + context, + ChatPage( + roomId: state.pathParameters['roomid']!, + ), + ), + 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, + ), + ShellRoute( + pageBuilder: (context, state, child) => + defaultPageBuilder( + context, + !FluffyThemes.isThreeColumnMode(context) + ? child + : SideViewLayout( + mainView: ChatPage( + roomId: state.pathParameters['roomid']!, + ), + sideView: child, + ), + ), + routes: [ + GoRoute( + path: 'details', + pageBuilder: (context, state) => defaultPageBuilder( + context, + ChatDetails( + roomId: state.pathParameters['roomid']!, + ), + ), + routes: _chatDetailsRoutes, + redirect: (context, state) => + !isLoggedIn ? '/home' : null, + ), + ], + ), + ], + ), + ], ), ], ), ]; - List get _chatDetailsRoutes => [ - VWidget( + List get _chatDetailsRoutes => [ + GoRoute( path: 'permissions', - widget: const ChatPermissionsSettings(), - buildTransition: _dynamicTransition, + pageBuilder: (context, state) => defaultPageBuilder( + context, + const ChatPermissionsSettings(), + ), + redirect: (context, state) => !isLoggedIn ? '/home' : null, ), - VWidget( + GoRoute( path: 'invite', - widget: const InvitationSelection(), - buildTransition: _dynamicTransition, + pageBuilder: (context, state) => defaultPageBuilder( + context, + const InvitationSelection(), + ), + redirect: (context, state) => !isLoggedIn ? '/home' : null, ), - VWidget( + GoRoute( path: 'multiple_emotes', - widget: const MultipleEmotesSettings(), - buildTransition: _dynamicTransition, + pageBuilder: (context, state) => defaultPageBuilder( + context, + const MultipleEmotesSettings(), + ), + redirect: (context, state) => !isLoggedIn ? '/home' : null, ), - VWidget( + GoRoute( path: 'emotes', - widget: const EmotesSettings(), - buildTransition: _dynamicTransition, + pageBuilder: (context, state) => defaultPageBuilder( + context, + const EmotesSettings(), + ), + redirect: (context, state) => !isLoggedIn ? '/home' : null, ), - VWidget( + GoRoute( path: 'emotes/:state_key', - widget: const EmotesSettings(), - buildTransition: _dynamicTransition, + pageBuilder: (context, state) => defaultPageBuilder( + context, + const EmotesSettings(), + ), + redirect: (context, state) => !isLoggedIn ? '/home' : null, ), ]; - List get _settingsRoutes => [ - VWidget( + List get _settingsRoutes => [ + GoRoute( path: 'notifications', - widget: const SettingsNotifications(), - buildTransition: _dynamicTransition, + pageBuilder: (context, state) => defaultPageBuilder( + context, + const SettingsNotifications(), + ), + redirect: (context, state) => !isLoggedIn ? '/home' : null, ), - VWidget( + GoRoute( path: 'style', - widget: const SettingsStyle(), - buildTransition: _dynamicTransition, + pageBuilder: (context, state) => defaultPageBuilder( + context, + const SettingsStyle(), + ), + redirect: (context, state) => !isLoggedIn ? '/home' : null, ), - VWidget( + GoRoute( path: 'devices', - widget: const DevicesSettings(), - buildTransition: _dynamicTransition, + pageBuilder: (context, state) => defaultPageBuilder( + context, + const DevicesSettings(), + ), + redirect: (context, state) => !isLoggedIn ? '/home' : null, ), - VWidget( + GoRoute( path: 'chat', - widget: const SettingsChat(), - buildTransition: _dynamicTransition, - stackedRoutes: [ - VWidget( + pageBuilder: (context, state) => defaultPageBuilder( + context, + const SettingsChat(), + ), + routes: [ + GoRoute( path: 'emotes', - widget: const EmotesSettings(), - buildTransition: _dynamicTransition, + pageBuilder: (context, state) => defaultPageBuilder( + context, + const EmotesSettings(), + ), ), ], + redirect: (context, state) => !isLoggedIn ? '/home' : null, ), - VWidget( + GoRoute( path: 'addaccount', - widget: const HomeserverPicker(), - buildTransition: _fadeTransition, - stackedRoutes: [ - VWidget( + redirect: (context, state) => !isLoggedIn ? '/home' : null, + pageBuilder: (context, state) => defaultPageBuilder( + context, + const HomeserverPicker(), + ), + routes: [ + GoRoute( path: 'login', - widget: const Login(), - buildTransition: _fadeTransition, + pageBuilder: (context, state) => defaultPageBuilder( + context, + const Login(), + ), + redirect: (context, state) => !isLoggedIn ? '/home' : null, ), ], ), - VWidget( + GoRoute( path: 'security', - widget: const SettingsSecurity(), - buildTransition: _dynamicTransition, - stackedRoutes: [ - VWidget( + redirect: (context, state) => !isLoggedIn ? '/home' : null, + pageBuilder: (context, state) => defaultPageBuilder( + context, + const SettingsSecurity(), + ), + routes: [ + GoRoute( path: 'stories', - widget: const SettingsStories(), - buildTransition: _dynamicTransition, + pageBuilder: (context, state) => defaultPageBuilder( + context, + const SettingsStories(), + ), + redirect: (context, state) => !isLoggedIn ? '/home' : null, ), - VWidget( + GoRoute( path: 'ignorelist', - widget: const SettingsIgnoreList(), - buildTransition: _dynamicTransition, + pageBuilder: (context, state) => defaultPageBuilder( + context, + const SettingsIgnoreList(), + ), + redirect: (context, state) => !isLoggedIn ? '/home' : null, ), - VWidget( + GoRoute( path: '3pid', - widget: const Settings3Pid(), - buildTransition: _dynamicTransition, + pageBuilder: (context, state) => defaultPageBuilder( + context, + const Settings3Pid(), + ), + redirect: (context, state) => !isLoggedIn ? '/home' : null, ), ], ), - VWidget( - path: 'logs', - widget: const LogViewer(), - buildTransition: _dynamicTransition, - ), ]; - FadeTransition Function(dynamic, dynamic, dynamic)? get _dynamicTransition => - columnMode ? _fadeTransition : null; - - FadeTransition _fadeTransition(animation1, _, child) => - FadeTransition(opacity: animation1, child: child); + Page defaultPageBuilder(BuildContext context, Widget child) => + CustomTransitionPage( + child: child, + transitionDuration: FluffyThemes.animationDuration, + reverseTransitionDuration: FluffyThemes.animationDuration, + transitionsBuilder: (context, animation, secondaryAnimation, child) => + FluffyThemes.isColumnMode(context) + ? FadeTransition(opacity: animation, child: child) + : CupertinoPageTransition( + primaryRouteAnimation: animation, + secondaryRouteAnimation: secondaryAnimation, + linearTransition: false, + child: child, + ), + ); } diff --git a/lib/config/themes.dart b/lib/config/themes.dart index dfe1f936..e7739a9d 100644 --- a/lib/config/themes.dart +++ b/lib/config/themes.dart @@ -1,8 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:go_router/go_router.dart'; - import 'package:fluffychat/utils/platform_infos.dart'; import 'app_config.dart'; @@ -17,8 +15,8 @@ abstract class FluffyThemes { static bool isColumnMode(BuildContext context) => isColumnModeByWidth(MediaQuery.of(context).size.width); - static bool getDisplayNavigationRail(BuildContext context) => - !VRouter.of(context).path.startsWith('/settings'); + static bool isThreeColumnMode(BuildContext context) => + MediaQuery.of(context).size.width > FluffyThemes.columnWidth * 3.5; static const fallbackTextStyle = TextStyle( fontFamily: 'Roboto', diff --git a/lib/main.dart b/lib/main.dart index 8721d773..4db62dfa 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,18 +1,20 @@ -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:collection/collection.dart'; import 'package:flutter_app_lock/flutter_app_lock.dart'; +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:matrix/matrix.dart'; -import 'package:universal_html/html.dart' as html; import 'package:fluffychat/utils/client_manager.dart'; import 'package:fluffychat/utils/platform_infos.dart'; +import 'config/setting_keys.dart'; import 'utils/background_push.dart'; import 'widgets/fluffy_chat_app.dart'; import 'widgets/lock_screen.dart'; void main() async { + Logs().i('Welcome to FluffyChat'); + // Our background push shared isolate accesses flutter-internal things very early in the startup proccess // To make sure that the parts of flutter needed are started up already, we need to ensure that the // widget bindings are initialized already. @@ -26,29 +28,24 @@ void main() async { await firstClient?.roomsLoading; await firstClient?.accountDataLoading; + String? pin; if (PlatformInfos.isMobile) { BackgroundPush.clientOnly(clients.first); - } - - final queryParameters = {}; - if (kIsWeb) { - queryParameters - .addAll(Uri.parse(html.window.location.href).queryParameters); + try { + pin = + await const FlutterSecureStorage().read(key: SettingKeys.appLockKey); + } catch (e, s) { + Logs().d('Unable to read PIN from Secure storage', e, s); + } } runApp( PlatformInfos.isMobile ? AppLock( - builder: (args) => FluffyChatApp( - clients: clients, - queryParameters: queryParameters, - ), + builder: (args) => FluffyChatApp(clients: clients), lockScreen: const LockScreen(), - enabled: false, + enabled: pin?.isNotEmpty ?? false, ) - : FluffyChatApp( - clients: clients, - queryParameters: queryParameters, - ), + : FluffyChatApp(clients: clients), ); } diff --git a/lib/pages/add_story/add_story.dart b/lib/pages/add_story/add_story.dart index bf302c90..6b1bc6a4 100644 --- a/lib/pages/add_story/add_story.dart +++ b/lib/pages/add_story/add_story.dart @@ -207,7 +207,7 @@ class AddStoryController extends State { }, ); if (postResult.error == null) { - VRouter.of(context).pop(); + context.pop(); } } diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index 79fece75..053dffda 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -38,14 +38,17 @@ import 'sticker_picker_dialog.dart'; class ChatPage extends StatelessWidget { final Widget? sideView; + final String roomId; - const ChatPage({Key? key, this.sideView}) : super(key: key); + const ChatPage({ + Key? key, + this.sideView, + required this.roomId, + }) : super(key: key); @override Widget build(BuildContext context) { - final roomId = context.vRouter.pathParameters['roomid']; - final room = - roomId == null ? null : Matrix.of(context).client.getRoomById(roomId); + final room = Matrix.of(context).client.getRoomById(roomId); if (room == null) { return Scaffold( appBar: AppBar(title: Text(L10n.of(context)!.oopsSomethingWentWrong)), @@ -58,7 +61,11 @@ class ChatPage extends StatelessWidget { ), ); } - return ChatPageWithRoom(sideView: sideView, room: room); + return ChatPageWithRoom( + key: Key('chat_page_$roomId'), + sideView: sideView, + room: room, + ); } } @@ -188,7 +195,7 @@ class ChatController extends State { ); final roomId = success.result; if (roomId == null) return; - VRouter.of(context).toSegments(['rooms', roomId]); + context.go(['', 'rooms', roomId].join('/')); } void leaveChat() async { @@ -197,7 +204,7 @@ class ChatController extends State { future: room.leave, ); if (success.error != null) return; - VRouter.of(context).to('/rooms'); + context.go('/rooms'); } EmojiPickerType emojiPickerType = EmojiPickerType.keyboard; @@ -329,7 +336,7 @@ class ChatController extends State { // "load more" button is visible on the screen SchedulerBinding.instance.addPostFrameCallback((_) async { if (mounted) { - final event = VRouter.of(context).queryParameters['event']; + final event = GoRouterState.of(context).uri.queryParameters['event']; if (event != null) { scrollToEventId(event); } @@ -803,7 +810,7 @@ class ChatController extends State { }; } setState(() => selectedEvents.clear()); - VRouter.of(context).to('/rooms'); + context.go('/rooms'); } void sendAgainAction() { @@ -901,7 +908,7 @@ class ChatController extends State { future: room.forget, ); if (result.error != null) return; - VRouter.of(context).to('/archive'); + context.go('/rooms/archive'); } void typeEmoji(Emoji? emoji) { @@ -1017,7 +1024,7 @@ class ChatController extends State { future: room.leave, ); if (result.error == null) { - VRouter.of(context).toSegments(['rooms', result.result!]); + context.go(['', 'rooms', result.result!].join('/')); } } diff --git a/lib/pages/chat/chat_app_bar_title.dart b/lib/pages/chat/chat_app_bar_title.dart index 349e493c..8c2ba63e 100644 --- a/lib/pages/chat/chat_app_bar_title.dart +++ b/lib/pages/chat/chat_app_bar_title.dart @@ -36,8 +36,7 @@ class ChatAppBarTitle extends StatelessWidget { ) : controller.isArchived ? null - : () => - VRouter.of(context).toSegments(['rooms', room.id, 'details']), + : () => context.go(['', 'rooms', room.id, 'details'].join('/')), child: Row( children: [ Hero( diff --git a/lib/pages/chat/chat_view.dart b/lib/pages/chat/chat_view.dart index de83ecfe..cf3e1cd6 100644 --- a/lib/pages/chat/chat_view.dart +++ b/lib/pages/chat/chat_view.dart @@ -4,7 +4,6 @@ import 'package:badges/badges.dart'; import 'package:desktop_drop/desktop_drop.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; -import 'package:go_router/go_router.dart'; import 'package:matrix/matrix.dart'; import 'package:fluffychat/config/app_config.dart'; @@ -147,15 +146,16 @@ class ChatView extends StatelessWidget { } final bottomSheetPadding = FluffyThemes.isColumnMode(context) ? 16.0 : 8.0; - return VWidgetGuard( - onSystemPop: (redirector) async { + return WillPopScope( + onWillPop: () async { if (controller.selectedEvents.isNotEmpty) { controller.clearSelectedEvents(); - redirector.stopRedirection(); + return false; } else if (controller.showEmojiPicker) { controller.emojiPickerAction(); - redirector.stopRedirection(); + return false; } + return true; }, child: GestureDetector( onTapDown: (_) => controller.setReadMarker(), diff --git a/lib/pages/chat/encryption_button.dart b/lib/pages/chat/encryption_button.dart index c89808c2..9a60d8d5 100644 --- a/lib/pages/chat/encryption_button.dart +++ b/lib/pages/chat/encryption_button.dart @@ -38,8 +38,8 @@ class EncryptionButton extends StatelessWidget { ? Colors.orange : null, ), - onPressed: () => VRouter.of(context) - .toSegments(['rooms', room.id, 'encryption']), + onPressed: () => + context.go(['', 'rooms', room.id, 'encryption'].join('/')), ), ); }, diff --git a/lib/pages/chat_details/chat_details.dart b/lib/pages/chat_details/chat_details.dart index 48d105be..8c0c7f0e 100644 --- a/lib/pages/chat_details/chat_details.dart +++ b/lib/pages/chat_details/chat_details.dart @@ -19,7 +19,12 @@ import 'package:fluffychat/widgets/matrix.dart'; enum AliasActions { copy, delete, setCanonical } class ChatDetails extends StatefulWidget { - const ChatDetails({Key? key}) : super(key: key); + final String roomId; + + const ChatDetails({ + Key? key, + required this.roomId, + }) : super(key: key); @override ChatDetailsController createState() => ChatDetailsController(); @@ -32,7 +37,7 @@ class ChatDetailsController extends State { void toggleDisplaySettings() => setState(() => displaySettings = !displaySettings); - String? get roomId => VRouter.of(context).pathParameters['roomid']; + String? get roomId => widget.roomId; void setDisplaynameAction() async { final room = Matrix.of(context).client.getRoomById(roomId!)!; @@ -257,9 +262,9 @@ class ChatDetailsController extends State { if ((room.states['im.ponies.room_emotes'] ?? {}) .keys .any((String s) => s.isNotEmpty)) { - VRouter.of(context).to('multiple_emotes'); + context.go('/rooms/${room.id}/details/multiple_emotes'); } else { - VRouter.of(context).to('emotes'); + context.go('/rooms/${room.id}/details/emotes'); } } diff --git a/lib/pages/chat_details/chat_details_view.dart b/lib/pages/chat_details/chat_details_view.dart index f381ded9..3dbbbd49 100644 --- a/lib/pages/chat_details/chat_details_view.dart +++ b/lib/pages/chat_details/chat_details_view.dart @@ -53,10 +53,11 @@ class ChatDetailsView extends StatelessWidget { leading: IconButton( icon: const Icon(Icons.close_outlined), onPressed: () => - VRouter.of(context).path.startsWith('/spaces/') - ? VRouter.of(context).pop() - : VRouter.of(context) - .toSegments(['rooms', controller.roomId!]), + GoRouterState.of(context).uri.path.startsWith('/spaces/') + ? context.pop() + : context.go( + ['', 'rooms', controller.roomId!].join('/'), + ), ), elevation: Theme.of(context).appBarTheme.elevation, expandedHeight: 300.0, @@ -380,8 +381,8 @@ class ChatDetailsView extends StatelessWidget { Icons.edit_attributes_outlined, ), ), - onTap: () => - VRouter.of(context).to('permissions'), + onTap: () => context + .go('/rooms/${room.id}/details/permissions'), ), ], const Divider(height: 1), @@ -408,7 +409,8 @@ class ChatDetailsView extends StatelessWidget { radius: Avatar.defaultSize / 2, child: const Icon(Icons.add_outlined), ), - onTap: () => VRouter.of(context).to('invite'), + onTap: () => + context.go('/rooms/${room.id}/invite'), ) : const SizedBox.shrink(), ], diff --git a/lib/pages/chat_encryption_settings/chat_encryption_settings.dart b/lib/pages/chat_encryption_settings/chat_encryption_settings.dart index 35d739ee..b8df84c8 100644 --- a/lib/pages/chat_encryption_settings/chat_encryption_settings.dart +++ b/lib/pages/chat_encryption_settings/chat_encryption_settings.dart @@ -20,7 +20,7 @@ class ChatEncryptionSettings extends StatefulWidget { } class ChatEncryptionSettingsController extends State { - String? get roomId => VRouter.of(context).pathParameters['roomid']; + String? get roomId => GoRouterState.of(context).pathParameters['roomid']; Room get room => Matrix.of(context).client.getRoomById(roomId!)!; diff --git a/lib/pages/chat_encryption_settings/chat_encryption_settings_view.dart b/lib/pages/chat_encryption_settings/chat_encryption_settings_view.dart index 51888e0b..d3f1b1a7 100644 --- a/lib/pages/chat_encryption_settings/chat_encryption_settings_view.dart +++ b/lib/pages/chat_encryption_settings/chat_encryption_settings_view.dart @@ -28,7 +28,7 @@ class ChatEncryptionSettingsView extends StatelessWidget { leading: IconButton( icon: const Icon(Icons.close_outlined), onPressed: () => - VRouter.of(context).toSegments(['rooms', controller.roomId!]), + context.go(['', 'rooms', controller.roomId!].join('/')), ), title: Text(L10n.of(context)!.encryption), actions: [ diff --git a/lib/pages/chat_list/chat_list.dart b/lib/pages/chat_list/chat_list.dart index 284f7286..85bc1237 100644 --- a/lib/pages/chat_list/chat_list.dart +++ b/lib/pages/chat_list/chat_list.dart @@ -56,8 +56,14 @@ enum ActiveFilter { class ChatList extends StatefulWidget { static BuildContext? contextForVoip; + final bool displayNavigationRail; + final String? activeChat; - const ChatList({Key? key}) : super(key: key); + const ChatList({ + Key? key, + this.displayNavigationRail = false, + required this.activeChat, + }) : super(key: key); @override ChatListController createState() => ChatListController(); @@ -259,7 +265,7 @@ class ChatListController extends State Stream get clientStream => _clientStream.stream; - void addAccountAction() => VRouter.of(context).to('/settings/account'); + void addAccountAction() => context.go('/rooms/settings/account'); void _onScroll() { final newScrolledToTop = scrollController.position.pixels <= 0; @@ -271,7 +277,7 @@ class ChatListController extends State void editSpace(BuildContext context, String spaceId) async { await Matrix.of(context).client.getRoomById(spaceId)!.postLoad(); if (mounted) { - VRouter.of(context).toSegments(['spaces', spaceId]); + context.go('/rooms/spaces/$spaceId'); } } @@ -281,7 +287,7 @@ class ChatListController extends State final selectedRoomIds = {}; - String? get activeChat => VRouter.of(context).pathParameters['roomid']; + String? get activeChat => widget.activeChat; SelectMode get selectMode => Matrix.of(context).shareContent != null ? SelectMode.share @@ -300,7 +306,7 @@ class ChatListController extends State name: file.path, ).detectFileType, }; - VRouter.of(context).to('/rooms'); + context.go('/rooms'); } void _processIncomingSharedText(String? text) { @@ -315,12 +321,12 @@ class ChatListController extends State 'msgtype': 'm.text', 'body': text, }; - VRouter.of(context).to('/rooms'); + context.go('/rooms'); } void _processIncomingUris(String? text) async { if (text == null) return; - VRouter.of(context).to('/rooms'); + context.go('/rooms'); WidgetsBinding.instance.addPostFrameCallback((_) { UrlLauncher(context, text).openMatrixToUrl(); }); @@ -582,7 +588,7 @@ class ChatListController extends State } void setActiveClient(Client client) { - VRouter.of(context).to('/rooms'); + context.go('/rooms'); setState(() { activeFilter = AppConfig.separateChatTypes ? ActiveFilter.messages @@ -595,7 +601,7 @@ class ChatListController extends State } void setActiveBundle(String bundle) { - VRouter.of(context).to('/rooms'); + context.go('/rooms'); setState(() { selectedRoomIds.clear(); Matrix.of(context).activeBundle = bundle; diff --git a/lib/pages/chat_list/chat_list_item.dart b/lib/pages/chat_list/chat_list_item.dart index 4ed8aeb2..9941bf5b 100644 --- a/lib/pages/chat_list/chat_list_item.dart +++ b/lib/pages/chat_list/chat_list_item.dart @@ -61,7 +61,7 @@ class ChatListItem extends StatelessWidget { } if (room.membership == Membership.leave) { - VRouter.of(context).toSegments(['archive', room.id]); + context.go(['', 'archive', room.id].join('/')); } if (room.membership == Membership.join) { @@ -86,7 +86,7 @@ class ChatListItem extends StatelessWidget { Matrix.of(context).shareContent = null; } - VRouter.of(context).toSegments(['rooms', room.id]); + context.go(['', 'rooms', room.id].join('/')); } } diff --git a/lib/pages/chat_list/chat_list_view.dart b/lib/pages/chat_list/chat_list_view.dart index 0cce0822..c37bddf5 100644 --- a/lib/pages/chat_list/chat_list_view.dart +++ b/lib/pages/chat_list/chat_list_view.dart @@ -86,13 +86,12 @@ class ChatListView extends StatelessWidget { stream: Matrix.of(context).onShareContentChanged.stream, builder: (_, __) { final selectMode = controller.selectMode; - return VWidgetGuard( - onSystemPop: (redirector) async { + return WillPopScope( + onWillPop: () async { final selMode = controller.selectMode; if (selMode != SelectMode.normal) { controller.cancelAction(); - redirector.stopRedirection(); - return; + return false; } if (controller.activeFilter != (AppConfig.separateChatTypes @@ -100,14 +99,14 @@ class ChatListView extends StatelessWidget { : ActiveFilter.allChats)) { controller .onDestinationSelected(AppConfig.separateChatTypes ? 1 : 0); - redirector.stopRedirection(); - return; + return false; } + return true; }, child: Row( children: [ if (FluffyThemes.isColumnMode(context) && - FluffyThemes.getDisplayNavigationRail(context)) ...[ + controller.widget.displayNavigationRail) ...[ Builder( builder: (context) { final allSpaces = @@ -193,8 +192,7 @@ class ChatListView extends StatelessWidget { LogicalKeyboardKey.controlLeft, LogicalKeyboardKey.keyN }, - onKeysPressed: () => - VRouter.of(context).to('/newprivatechat'), + onKeysPressed: () => context.go('/rooms/newprivatechat'), helpLabel: L10n.of(context)!.newChat, child: selectMode == SelectMode.normal && !controller.isSearchMode diff --git a/lib/pages/chat_list/client_chooser_button.dart b/lib/pages/chat_list/client_chooser_button.dart index b1d29c7b..cc020142 100644 --- a/lib/pages/chat_list/client_chooser_button.dart +++ b/lib/pages/chat_list/client_chooser_button.dart @@ -261,16 +261,16 @@ class ClientChooserButton extends StatelessWidget { cancelLabel: L10n.of(context)!.cancel, ); if (consent != OkCancelResult.ok) return; - VRouter.of(context).to('/settings/addaccount'); + context.go('/rooms/settings/addaccount'); break; case SettingsAction.newStory: - VRouter.of(context).to('/stories/create'); + context.go('/rooms/stories/create'); break; case SettingsAction.newGroup: - VRouter.of(context).to('/newgroup'); + context.go('/rooms/newgroup'); break; case SettingsAction.newSpace: - VRouter.of(context).to('/newspace'); + context.go('/rooms/newspace'); break; case SettingsAction.invite: FluffyShare.share( @@ -282,10 +282,10 @@ class ClientChooserButton extends StatelessWidget { ); break; case SettingsAction.settings: - VRouter.of(context).to('/settings'); + context.go('/rooms/settings'); break; case SettingsAction.archive: - VRouter.of(context).to('/archive'); + context.go('/rooms/archive'); break; } } diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index 5e2bf727..1d8a7ba8 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -73,13 +73,13 @@ class _SpaceViewState extends State { } if (spaceChild.roomType == 'm.space') { if (spaceChild.roomId == widget.controller.activeSpaceId) { - VRouter.of(context).toSegments(['spaces', spaceChild.roomId]); + context.go('/rooms/spaces/${spaceChild.roomId}'); } else { widget.controller.setActiveSpace(spaceChild.roomId); } return; } - VRouter.of(context).toSegments(['rooms', spaceChild.roomId]); + context.go(['', 'rooms', spaceChild.roomId].join('/')); } void _onSpaceChildContextMenu([ @@ -234,13 +234,13 @@ class _SpaceViewState extends State { ); final spaceChildren = response.rooms; final canLoadMore = response.nextBatch != null; - return VWidgetGuard( - onSystemPop: (redirector) async { + return WillPopScope( + onWillPop: () async { if (parentSpace != null) { widget.controller.setActiveSpace(parentSpace.id); - redirector.stopRedirection(); - return; + return false; } + return true; }, child: CustomScrollView( controller: widget.scrollController, diff --git a/lib/pages/chat_list/start_chat_fab.dart b/lib/pages/chat_list/start_chat_fab.dart index 57706aac..f702ad69 100644 --- a/lib/pages/chat_list/start_chat_fab.dart +++ b/lib/pages/chat_list/start_chat_fab.dart @@ -22,13 +22,13 @@ class StartChatFloatingActionButton extends StatelessWidget { switch (activeFilter) { case ActiveFilter.allChats: case ActiveFilter.messages: - VRouter.of(context).to('/newprivatechat'); + context.go('/rooms/newprivatechat'); break; case ActiveFilter.groups: - VRouter.of(context).to('/newgroup'); + context.go('/rooms/newgroup'); break; case ActiveFilter.spaces: - VRouter.of(context).to('/newspace'); + context.go('/rooms/newspace'); break; } } diff --git a/lib/pages/chat_list/stories_header.dart b/lib/pages/chat_list/stories_header.dart index 7a472cbb..75ab67cd 100644 --- a/lib/pages/chat_list/stories_header.dart +++ b/lib/pages/chat_list/stories_header.dart @@ -23,7 +23,7 @@ class StoriesHeader extends StatelessWidget { const StoriesHeader({required this.filter, Key? key}) : super(key: key); void _addToStoryAction(BuildContext context) => - VRouter.of(context).to('/stories/create'); + context.go('/rooms/stories/create'); void _goToStoryAction(BuildContext context, String roomId) async { final room = Matrix.of(context).client.getRoomById(roomId); @@ -35,7 +35,7 @@ class StoriesHeader extends StatelessWidget { ); if (result.error != null) return; } - VRouter.of(context).toSegments(['stories', roomId]); + context.go(['', 'stories', roomId].join('/')); } void _contextualActions(BuildContext context, Room room) async { @@ -249,7 +249,7 @@ class _StoryButton extends StatelessWidget { child: FloatingActionButton.small( heroTag: null, onPressed: () => - VRouter.of(context).to('/stories/create'), + context.go('/rooms/stories/create'), child: const Icon( Icons.add_outlined, size: 16, diff --git a/lib/pages/chat_permissions_settings/chat_permissions_settings.dart b/lib/pages/chat_permissions_settings/chat_permissions_settings.dart index 4d219f6e..394206f1 100644 --- a/lib/pages/chat_permissions_settings/chat_permissions_settings.dart +++ b/lib/pages/chat_permissions_settings/chat_permissions_settings.dart @@ -21,7 +21,7 @@ class ChatPermissionsSettings extends StatefulWidget { } class ChatPermissionsSettingsController extends State { - String? get roomId => VRouter.of(context).pathParameters['roomid']; + String? get roomId => GoRouterState.of(context).pathParameters['roomid']; void editPowerLevel( BuildContext context, String key, @@ -105,7 +105,7 @@ class ChatPermissionsSettingsController extends State { await showFutureLoadingDialog( context: context, future: () => room.client.upgradeRoom(roomId!, newVersion), - ).then((_) => VRouter.of(context).pop()); + ).then((_) => context.pop()); } @override diff --git a/lib/pages/chat_permissions_settings/chat_permissions_settings_view.dart b/lib/pages/chat_permissions_settings/chat_permissions_settings_view.dart index 83a5e08c..6eb7005f 100644 --- a/lib/pages/chat_permissions_settings/chat_permissions_settings_view.dart +++ b/lib/pages/chat_permissions_settings/chat_permissions_settings_view.dart @@ -19,12 +19,12 @@ class ChatPermissionsSettingsView extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - leading: VRouter.of(context).path.startsWith('/spaces/') + leading: GoRouterState.of(context).uri.path.startsWith('/spaces/') ? null : IconButton( icon: const Icon(Icons.close_outlined), - onPressed: () => VRouter.of(context) - .toSegments(['rooms', controller.roomId!]), + onPressed: () => + context.go(['', 'rooms', controller.roomId!].join('/')), ), title: Text(L10n.of(context)!.editChatPermissions), ), diff --git a/lib/pages/homeserver_picker/homeserver_picker.dart b/lib/pages/homeserver_picker/homeserver_picker.dart index 88bf55cb..5272afcd 100644 --- a/lib/pages/homeserver_picker/homeserver_picker.dart +++ b/lib/pages/homeserver_picker/homeserver_picker.dart @@ -155,7 +155,7 @@ class HomeserverPickerController extends State { return list; } - void login() => VRouter.of(context).to('login'); + void login() => context.go('/home/login'); @override void initState() { diff --git a/lib/pages/image_viewer/image_viewer.dart b/lib/pages/image_viewer/image_viewer.dart index 45697a95..ac4505c4 100644 --- a/lib/pages/image_viewer/image_viewer.dart +++ b/lib/pages/image_viewer/image_viewer.dart @@ -21,7 +21,7 @@ class ImageViewerController extends State { /// Forward this image to another room. void forwardAction() { Matrix.of(context).shareContent = widget.event.content; - VRouter.of(context).to('/rooms'); + context.go('/rooms'); } /// Save this file with a system call. diff --git a/lib/pages/invitation_selection/invitation_selection.dart b/lib/pages/invitation_selection/invitation_selection.dart index aaa7f62b..e5e85616 100644 --- a/lib/pages/invitation_selection/invitation_selection.dart +++ b/lib/pages/invitation_selection/invitation_selection.dart @@ -28,7 +28,7 @@ class InvitationSelectionController extends State { List foundProfiles = []; Timer? coolDown; - String? get roomId => VRouter.of(context).pathParameters['roomid']; + String? get roomId => GoRouterState.of(context).pathParameters['roomid']; Future> getContacts(BuildContext context) async { final client = Matrix.of(context).client; diff --git a/lib/pages/invitation_selection/invitation_selection_view.dart b/lib/pages/invitation_selection/invitation_selection_view.dart index e7691302..d2d5f1e1 100644 --- a/lib/pages/invitation_selection/invitation_selection_view.dart +++ b/lib/pages/invitation_selection/invitation_selection_view.dart @@ -20,12 +20,12 @@ class InvitationSelectionView extends StatelessWidget { final groupName = room.name.isEmpty ? L10n.of(context)!.group : room.name; return Scaffold( appBar: AppBar( - leading: VRouter.of(context).path.startsWith('/spaces/') + leading: GoRouterState.of(context).uri.path.startsWith('/spaces/') ? null : IconButton( icon: const Icon(Icons.close_outlined), - onPressed: () => VRouter.of(context) - .toSegments(['rooms', controller.roomId!]), + onPressed: () => + context.go(['', 'rooms', controller.roomId!].join('/')), ), titleSpacing: 0, title: SizedBox( diff --git a/lib/pages/key_verification/key_verification_dialog.dart b/lib/pages/key_verification/key_verification_dialog.dart index 589336a6..0f1ff79b 100644 --- a/lib/pages/key_verification/key_verification_dialog.dart +++ b/lib/pages/key_verification/key_verification_dialog.dart @@ -108,10 +108,10 @@ class KeyVerificationPageState extends State { var title = Text(L10n.of(context)!.verifyTitle); Widget body; final buttons = []; + switch (widget.request.state) { case KeyVerificationState.showQRSuccess: case KeyVerificationState.confirmQRScan: - case KeyVerificationState.askChoice: throw 'Not implemented'; case KeyVerificationState.askSSSS: // prompt the user for their ssss passphrase / key @@ -200,6 +200,7 @@ class KeyVerificationPageState extends State { ), ); break; + case KeyVerificationState.askChoice: case KeyVerificationState.waitingAccept: body = Center( child: Column( diff --git a/lib/pages/new_group/new_group.dart b/lib/pages/new_group/new_group.dart index 79bd9d47..dc5423d5 100644 --- a/lib/pages/new_group/new_group.dart +++ b/lib/pages/new_group/new_group.dart @@ -37,7 +37,7 @@ class NewGroupController extends State { }, ); if (roomID.error == null) { - VRouter.of(context).toSegments(['rooms', roomID.result!, 'invite']); + context.go(['', 'rooms', roomID.result!, 'invite'].join('/')); } } diff --git a/lib/pages/new_private_chat/new_private_chat_view.dart b/lib/pages/new_private_chat/new_private_chat_view.dart index d0a65817..b5d49cc9 100644 --- a/lib/pages/new_private_chat/new_private_chat_view.dart +++ b/lib/pages/new_private_chat/new_private_chat_view.dart @@ -31,7 +31,7 @@ class NewPrivateChatView extends StatelessWidget { Padding( padding: const EdgeInsets.all(8.0), child: TextButton( - onPressed: () => VRouter.of(context).to('/newgroup'), + onPressed: () => context.go('/rooms/newgroup'), child: Text( L10n.of(context)!.createNewGroup, style: diff --git a/lib/pages/new_space/new_space.dart b/lib/pages/new_space/new_space.dart index 767ea719..8452b75b 100644 --- a/lib/pages/new_space/new_space.dart +++ b/lib/pages/new_space/new_space.dart @@ -38,7 +38,7 @@ class NewSpaceController extends State { ), ); if (roomID.error == null) { - VRouter.of(context).toSegments(['spaces', roomID.result!]); + context.go('/rooms/spaces/${roomID.result!}'); } } diff --git a/lib/pages/settings/settings_view.dart b/lib/pages/settings/settings_view.dart index 79332ed8..8a8fb27c 100644 --- a/lib/pages/settings/settings_view.dart +++ b/lib/pages/settings/settings_view.dart @@ -23,7 +23,7 @@ class SettingsView extends StatelessWidget { return Scaffold( appBar: AppBar( leading: CloseButton( - onPressed: VRouter.of(context).pop, + onPressed: () => context.go('/rooms'), ), title: Text(L10n.of(context)!.settings), actions: [ @@ -153,31 +153,31 @@ class SettingsView extends StatelessWidget { ListTile( leading: const Icon(Icons.format_paint_outlined), title: Text(L10n.of(context)!.changeTheme), - onTap: () => VRouter.of(context).to('/settings/style'), + onTap: () => context.go('/rooms/settings/style'), trailing: const Icon(Icons.chevron_right_outlined), ), ListTile( leading: const Icon(Icons.notifications_outlined), title: Text(L10n.of(context)!.notifications), - onTap: () => VRouter.of(context).to('/settings/notifications'), + onTap: () => context.go('/rooms/settings/notifications'), trailing: const Icon(Icons.chevron_right_outlined), ), ListTile( leading: const Icon(Icons.devices_outlined), title: Text(L10n.of(context)!.devices), - onTap: () => VRouter.of(context).to('/settings/devices'), + onTap: () => context.go('/rooms/settings/devices'), trailing: const Icon(Icons.chevron_right_outlined), ), ListTile( leading: const Icon(Icons.forum_outlined), title: Text(L10n.of(context)!.chat), - onTap: () => VRouter.of(context).to('/settings/chat'), + onTap: () => context.go('/rooms/settings/chat'), trailing: const Icon(Icons.chevron_right_outlined), ), ListTile( leading: const Icon(Icons.shield_outlined), title: Text(L10n.of(context)!.security), - onTap: () => VRouter.of(context).to('/settings/security'), + onTap: () => context.go('/rooms/settings/security'), trailing: const Icon(Icons.chevron_right_outlined), ), const Divider(thickness: 1), diff --git a/lib/pages/settings_chat/settings_chat_view.dart b/lib/pages/settings_chat/settings_chat_view.dart index f6e58920..b62277cd 100644 --- a/lib/pages/settings_chat/settings_chat_view.dart +++ b/lib/pages/settings_chat/settings_chat_view.dart @@ -29,7 +29,7 @@ class SettingsChatView extends StatelessWidget { children: [ ListTile( title: Text(L10n.of(context)!.emoteSettings), - onTap: () => VRouter.of(context).to('emotes'), + onTap: () => context.go('/rooms/settings/chat/emotes'), trailing: const Icon(Icons.chevron_right_outlined), leading: const Icon(Icons.emoji_emotions_outlined), ), diff --git a/lib/pages/settings_emotes/settings_emotes.dart b/lib/pages/settings_emotes/settings_emotes.dart index df078e8c..626622d4 100644 --- a/lib/pages/settings_emotes/settings_emotes.dart +++ b/lib/pages/settings_emotes/settings_emotes.dart @@ -29,12 +29,12 @@ class EmotesSettings extends StatefulWidget { } class EmotesSettingsController extends State { - String? get roomId => VRouter.of(context).pathParameters['roomid']; + String? get roomId => GoRouterState.of(context).pathParameters['roomid']; Room? get room => roomId != null ? Matrix.of(context).client.getRoomById(roomId!) : null; - String? get stateKey => VRouter.of(context).pathParameters['state_key']; + String? get stateKey => GoRouterState.of(context).pathParameters['state_key']; bool showSave = false; TextEditingController newImageCodeController = TextEditingController(); diff --git a/lib/pages/settings_multiple_emotes/settings_multiple_emotes.dart b/lib/pages/settings_multiple_emotes/settings_multiple_emotes.dart index b67d688f..b4901832 100644 --- a/lib/pages/settings_multiple_emotes/settings_multiple_emotes.dart +++ b/lib/pages/settings_multiple_emotes/settings_multiple_emotes.dart @@ -13,7 +13,7 @@ class MultipleEmotesSettings extends StatefulWidget { } class MultipleEmotesSettingsController extends State { - String? get roomId => VRouter.of(context).pathParameters['roomid']; + String? get roomId => GoRouterState.of(context).pathParameters['roomid']; @override Widget build(BuildContext context) => MultipleEmotesSettingsView(this); } diff --git a/lib/pages/settings_multiple_emotes/settings_multiple_emotes_view.dart b/lib/pages/settings_multiple_emotes/settings_multiple_emotes_view.dart index a2ece02c..e7a76227 100644 --- a/lib/pages/settings_multiple_emotes/settings_multiple_emotes_view.dart +++ b/lib/pages/settings_multiple_emotes/settings_multiple_emotes_view.dart @@ -49,8 +49,9 @@ class MultipleEmotesSettingsView extends StatelessWidget { return ListTile( title: Text(packName), onTap: () async { - VRouter.of(context).toSegments( - ['rooms', room.id, 'details', 'emotes', keys[i]], + context.go( + ['', 'rooms', room.id, 'details', 'emotes', keys[i]] + .join('/'), ); }, ); diff --git a/lib/pages/settings_security/settings_security_view.dart b/lib/pages/settings_security/settings_security_view.dart index 27242ebe..bce60726 100644 --- a/lib/pages/settings_security/settings_security_view.dart +++ b/lib/pages/settings_security/settings_security_view.dart @@ -27,13 +27,13 @@ class SettingsSecurityView extends StatelessWidget { leading: const Icon(Icons.camera_outlined), trailing: const Icon(Icons.chevron_right_outlined), title: Text(L10n.of(context)!.whoCanSeeMyStories), - onTap: () => VRouter.of(context).to('stories'), + onTap: () => context.go('/rooms/settings/security/stories'), ), ListTile( leading: const Icon(Icons.block_outlined), trailing: const Icon(Icons.chevron_right_outlined), title: Text(L10n.of(context)!.ignoredUsers), - onTap: () => VRouter.of(context).to('ignorelist'), + onTap: () => context.go('/rooms/settings/security/ignorelist'), ), ListTile( leading: const Icon(Icons.password_outlined), @@ -47,7 +47,7 @@ class SettingsSecurityView extends StatelessWidget { leading: const Icon(Icons.mail_outlined), trailing: const Icon(Icons.chevron_right_outlined), title: Text(L10n.of(context)!.passwordRecovery), - onTap: () => VRouter.of(context).to('3pid'), + onTap: () => context.go('/rooms/settings/security/3pid'), ), if (Matrix.of(context).client.encryption != null) ...{ const Divider(thickness: 1), diff --git a/lib/pages/story/story_page.dart b/lib/pages/story/story_page.dart index 4ac9961d..ebae8ee7 100644 --- a/lib/pages/story/story_page.dart +++ b/lib/pages/story/story_page.dart @@ -120,7 +120,7 @@ class StoryPageController extends State { void share() async { Matrix.of(context).shareContent = currentEvent?.content; hold(); - VRouter.of(context).to('share'); + context.go('share'); } void displaySeenByUsers() async { @@ -199,7 +199,7 @@ class StoryPageController extends State { return room.ownPowerLevel >= 100; } - String get roomId => VRouter.of(context).pathParameters['roomid'] ?? ''; + String get roomId => GoRouterState.of(context).pathParameters['roomid'] ?? ''; Future? loadVideoControllerFuture; @@ -228,9 +228,9 @@ class StoryPageController extends State { void skip() { if (index + 1 >= max) { if (isOwnStory) { - VRouter.of(context).to('/stories/create'); + context.go('/rooms/stories/create'); } else { - VRouter.of(context).to('/rooms'); + context.go('/rooms'); } return; } @@ -497,7 +497,8 @@ class StoryPageController extends State { currentEvent!.senderFromMemoryOrFallback.startDirectChat(), ); if (roomIdResult.error != null) return; - VRouter.of(context).toSegments(['rooms', roomIdResult.result!]); + context.go(['', 'rooms', roomIdResult.result!].join('/')); + break; } } diff --git a/lib/pages/user_bottom_sheet/user_bottom_sheet.dart b/lib/pages/user_bottom_sheet/user_bottom_sheet.dart index 6403fbbc..4fd0cc23 100644 --- a/lib/pages/user_bottom_sheet/user_bottom_sheet.dart +++ b/lib/pages/user_bottom_sheet/user_bottom_sheet.dart @@ -147,8 +147,7 @@ class UserBottomSheetController extends State { future: () => widget.user.startDirectChat(), ); if (roomIdResult.error != null) return; - VRouter.of(widget.outerContext) - .toSegments(['rooms', roomIdResult.result!]); + widget.outerContext.go(['', 'rooms', roomIdResult.result!].join('/')); Navigator.of(context, rootNavigator: false).pop(); break; case UserBottomSheetAction.ignore: diff --git a/lib/utils/background_push.dart b/lib/utils/background_push.dart index 8cdd2b2d..762f906a 100644 --- a/lib/utils/background_push.dart +++ b/lib/utils/background_push.dart @@ -37,7 +37,7 @@ import 'package:fluffychat/utils/matrix_sdk_extensions/client_stories_extension. import 'package:fluffychat/utils/push_helper.dart'; import '../config/app_config.dart'; import '../config/setting_keys.dart'; -import '../widgets/fluffy_chat_app.dart'; +import '../widgets/matrix.dart'; import 'famedlysdk_store.dart'; import 'platform_infos.dart'; @@ -52,8 +52,8 @@ class BackgroundPush { final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); Client client; - BuildContext? context; - GlobalKey get router => FluffyChatApp.routerKey; + MatrixState? matrix; + BuildContext? get context => matrix?.navigatorContext; String? _fcmToken; void Function(String errorMsg, {Uri? link})? onFcmError; L10n? l10n; @@ -77,6 +77,7 @@ class BackgroundPush { onRoomSync ??= client.onSync.stream .where((s) => s.hasRoomUpdate) .listen((s) => _onClearingPush(getFromServer: false)); + final context = this.context; firebase?.setListeners( onMessage: (message) => pushHelper( PushNotification.fromJson( @@ -84,7 +85,9 @@ class BackgroundPush { ), client: client, l10n: l10n, - activeRoomId: router.currentState?.pathParameters['roomid'], + activeRoomId: context == null + ? null + : GoRouterState.of(context).pathParameters['roomid'], onSelectNotification: goToRoom, ), ); @@ -104,12 +107,11 @@ class BackgroundPush { } factory BackgroundPush( - Client client, - BuildContext context, { + MatrixState matrix, { final void Function(String errorMsg, {Uri? link})? onFcmError, }) { - final instance = BackgroundPush.clientOnly(client); - instance.context = context; + final instance = BackgroundPush.clientOnly(matrix.client); + instance.matrix = matrix; // ignore: prefer_initializing_formals instance.onFcmError = onFcmError; return instance; @@ -250,8 +252,7 @@ class BackgroundPush { .then((details) { if (details == null || !details.didNotificationLaunchApp || - _wentToRoomOnStartup || - router.currentState == null) { + _wentToRoomOnStartup) { return; } _wentToRoomOnStartup = true; @@ -303,7 +304,7 @@ class BackgroundPush { try { final roomId = response?.payload; Logs().v('[Push] Attempting to go to room $roomId...'); - if (router.currentState == null || roomId == null) { + if (roomId == null) { return; } await client.roomsLoading; @@ -314,7 +315,7 @@ class BackgroundPush { ?.content .tryGet('type') == ClientStoriesExtension.storiesRoomType; - router.currentState!.toSegments([isStory ? 'stories' : 'rooms', roomId]); + context?.go(['', isStory ? 'stories' : 'rooms', roomId].join('/')); } catch (e, s) { Logs().e('[Push] Failed to open room', e, s); } @@ -390,11 +391,14 @@ class BackgroundPush { ); // UP may strip the devices list data['devices'] ??= []; + final context = this.context; await pushHelper( PushNotification.fromJson(data), client: client, l10n: l10n, - activeRoomId: router.currentState?.pathParameters['roomid'], + activeRoomId: context == null + ? null + : GoRouterState.of(context).pathParameters['roomid'], ); } diff --git a/lib/utils/platform_infos.dart b/lib/utils/platform_infos.dart index 602a80d7..e7a0c84c 100644 --- a/lib/utils/platform_infos.dart +++ b/lib/utils/platform_infos.dart @@ -46,20 +46,29 @@ abstract class PlatformInfos { final version = await PlatformInfos.getVersion(); showAboutDialog( context: context, - useRootNavigator: false, children: [ Text('Version: $version'), - OutlinedButton( + TextButton.icon( onPressed: () => launchUrlString(AppConfig.sourceCodeUrl), - child: Text(L10n.of(context)!.sourceCode), + icon: const Icon(Icons.source_outlined), + label: Text(L10n.of(context)!.sourceCode), ), - OutlinedButton( + TextButton.icon( onPressed: () => launchUrlString(AppConfig.emojiFontUrl), - child: const Text(AppConfig.emojiFontName), + icon: const Icon(Icons.emoji_emotions_outlined), + label: const Text(AppConfig.emojiFontName), ), - OutlinedButton( - onPressed: () => VRouter.of(context).to('logs'), - child: const Text('Logs'), + Builder( + builder: (context) { + return TextButton.icon( + onPressed: () { + Navigator.of(context).pop(); + context.go('/logs'); + }, + icon: const Icon(Icons.list_outlined), + label: const Text('Logs'), + ); + }, ), ], applicationIcon: Image.asset( diff --git a/lib/utils/uia_request_manager.dart b/lib/utils/uia_request_manager.dart index a21bca0c..60b053bd 100644 --- a/lib/utils/uia_request_manager.dart +++ b/lib/utils/uia_request_manager.dart @@ -49,7 +49,7 @@ extension UiaRequestManager on MatrixState { case AuthenticationTypes.emailIdentity: if (currentThreepidCreds == null) { return uiaRequest.cancel( - UiaException(L10n.of(widget.context)!.serverRequiresEmail), + UiaException(L10n.of(navigatorContext)!.serverRequiresEmail), ); } final auth = AuthenticationThreePidCreds( diff --git a/lib/utils/url_launcher.dart b/lib/utils/url_launcher.dart index fbc5950a..c48b2793 100644 --- a/lib/utils/url_launcher.dart +++ b/lib/utils/url_launcher.dart @@ -172,17 +172,20 @@ class UrlLauncher { if (room != null) { if (room.isSpace) { // TODO: Implement navigate to space - VRouter.of(context).toSegments(['rooms']); + context.go(['', 'rooms'].join('/')); + return; } // we have the room, so....just open it if (event != null) { - VRouter.of(context).toSegments( - ['rooms', room.id], - queryParameters: {'event': event}, + context.go( + Uri( + pathSegments: ['rooms', room.id], + queryParameters: {'event': event}, + ).toString(), ); } else { - VRouter.of(context).toSegments(['rooms', room.id]); + context.go(['', 'rooms', room.id].join('/')); } return; } else { @@ -216,12 +219,14 @@ class UrlLauncher { future: () => Future.delayed(const Duration(seconds: 2)), ); if (event != null) { - VRouter.of(context).toSegments( - ['rooms', response.result!], - queryParameters: {'event': event}, + context.go( + Uri( + pathSegments: ['rooms', response.result!], + queryParameters: {'event': event}, + ).toString(), ); } else { - VRouter.of(context).toSegments(['rooms', response.result!]); + context.go(['', 'rooms', response.result!].join('/')); } } } diff --git a/lib/utils/voip_plugin.dart b/lib/utils/voip_plugin.dart index f21e50dc..df484e55 100644 --- a/lib/utils/voip_plugin.dart +++ b/lib/utils/voip_plugin.dart @@ -12,14 +12,15 @@ import 'package:webrtc_interface/webrtc_interface.dart' hide Navigator; import 'package:fluffychat/pages/chat_list/chat_list.dart'; import 'package:fluffychat/pages/dialer/dialer.dart'; import 'package:fluffychat/utils/platform_infos.dart'; -import 'package:fluffychat/widgets/fluffy_chat_app.dart'; import '../../utils/famedlysdk_store.dart'; import '../../utils/voip/callkeep_manager.dart'; import '../../utils/voip/user_media_manager.dart'; +import '../widgets/matrix.dart'; class VoipPlugin with WidgetsBindingObserver implements WebRTCDelegate { - final Client client; - VoipPlugin(this.client) { + final MatrixState matrix; + Client get client => matrix.client; + VoipPlugin(this.matrix) { voip = VoIP(client, this); Connectivity() .onConnectivityChanged @@ -40,6 +41,7 @@ class VoipPlugin with WidgetsBindingObserver implements WebRTCDelegate { late VoIP voip; ConnectivityResult? _currentConnectivity; OverlayEntry? overlayEntry; + BuildContext get context => matrix.navigatorContext; void _handleNetworkChanged(ConnectivityResult result) async { /// Got a new connectivity status! @@ -59,9 +61,8 @@ class VoipPlugin with WidgetsBindingObserver implements WebRTCDelegate { } void addCallingOverlay(String callId, CallSession call) { - final context = kIsWeb - ? ChatList.contextForVoip! - : FluffyChatApp.matrixKey.currentContext!; // web is weird + final context = + kIsWeb ? ChatList.contextForVoip! : this.context; // web is weird if (overlayEntry != null) { Logs().e('[VOIP] addCallingOverlay: The call session already exists?'); @@ -166,8 +167,7 @@ class VoipPlugin with WidgetsBindingObserver implements WebRTCDelegate { addCallingOverlay(call.callId, call); try { if (!hasCallingAccount) { - ScaffoldMessenger.of(FluffyChatApp.matrixKey.currentContext!) - .showSnackBar( + ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text( 'No calling accounts found (used for native calls UI)', diff --git a/lib/widgets/chat_settings_popup_menu.dart b/lib/widgets/chat_settings_popup_menu.dart index 39fb3378..78e1b578 100644 --- a/lib/widgets/chat_settings_popup_menu.dart +++ b/lib/widgets/chat_settings_popup_menu.dart @@ -154,7 +154,7 @@ class ChatSettingsPopupMenuState extends State { future: () => widget.room.leave(), ); if (success.error == null) { - VRouter.of(context).to('/rooms'); + context.go('/rooms'); } } break; @@ -195,10 +195,10 @@ class ChatSettingsPopupMenuState extends State { ); void _showChatDetails() { - if (VRouter.of(context).path.endsWith('/details')) { - VRouter.of(context).toSegments(['rooms', widget.room.id]); + if (GoRouterState.of(context).uri.path.endsWith('/details')) { + context.go(['', 'rooms', widget.room.id].join('/')); } else { - VRouter.of(context).toSegments(['rooms', widget.room.id, 'details']); + context.go(['', 'rooms', widget.room.id, 'details'].join('/')); } } } diff --git a/lib/widgets/fluffy_chat_app.dart b/lib/widgets/fluffy_chat_app.dart index 45eb1e69..21519b3b 100644 --- a/lib/widgets/fluffy_chat_app.dart +++ b/lib/widgets/fluffy_chat_app.dart @@ -1,4 +1,3 @@ -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; @@ -12,17 +11,14 @@ import '../config/app_config.dart'; import '../utils/custom_scroll_behaviour.dart'; import 'matrix.dart'; -class FluffyChatApp extends StatefulWidget { +class FluffyChatApp extends StatelessWidget { final Widget? testWidget; final List clients; - final Map? queryParameters; - static GlobalKey routerKey = GlobalKey(); - static GlobalKey matrixKey = GlobalKey(); + const FluffyChatApp({ Key? key, this.testWidget, required this.clients, - this.queryParameters, }) : super(key: key); /// getInitialLink may rereturn the value multiple times if this view is @@ -30,59 +26,23 @@ class FluffyChatApp extends StatefulWidget { /// in with qr code or magic link. static bool gotInitialLink = false; - @override - FluffyChatAppState createState() => FluffyChatAppState(); -} - -class FluffyChatAppState extends State { - bool? columnMode; - String? _initialUrl; - - @override - void initState() { - super.initState(); - _initialUrl = - widget.clients.any((client) => client.isLogged()) ? '/rooms' : '/home'; - } - @override Widget build(BuildContext context) { return ThemeBuilder( - builder: (context, themeMode, primaryColor) => LayoutBuilder( - builder: (context, constraints) { - final isColumnMode = - FluffyThemes.isColumnModeByWidth(constraints.maxWidth); - if (isColumnMode != columnMode) { - Logs().v('Set Column Mode = $isColumnMode'); - WidgetsBinding.instance.addPostFrameCallback((_) { - setState(() { - _initialUrl = FluffyChatApp.routerKey.currentState?.url; - columnMode = isColumnMode; - FluffyChatApp.routerKey = GlobalKey(); - }); - }); - } - return VRouter( - key: FluffyChatApp.routerKey, - title: AppConfig.applicationName, - debugShowCheckedModeBanner: false, - themeMode: themeMode, - theme: FluffyThemes.buildTheme(Brightness.light, primaryColor), - darkTheme: FluffyThemes.buildTheme(Brightness.dark, primaryColor), - scrollBehavior: CustomScrollBehavior(), - logs: kReleaseMode ? VLogs.none : VLogs.info, - localizationsDelegates: L10n.localizationsDelegates, - supportedLocales: L10n.supportedLocales, - initialUrl: _initialUrl ?? '/', - routes: AppRoutes(columnMode ?? false).routes, - builder: (context, child) => Matrix( - key: FluffyChatApp.matrixKey, - context: context, - clients: widget.clients, - child: child, - ), - ); - }, + builder: (context, themeMode, primaryColor) => MaterialApp.router( + title: AppConfig.applicationName, + themeMode: themeMode, + theme: FluffyThemes.buildTheme(Brightness.light, primaryColor), + darkTheme: FluffyThemes.buildTheme(Brightness.dark, primaryColor), + scrollBehavior: CustomScrollBehavior(), + localizationsDelegates: L10n.localizationsDelegates, + supportedLocales: L10n.supportedLocales, + routerConfig: GoRouter(routes: AppRoutes(clients).routes), + builder: (context, child) => Matrix( + context: context, + clients: clients, + child: child, + ), ), ); } diff --git a/lib/widgets/layouts/loading_view.dart b/lib/widgets/layouts/loading_view.dart deleted file mode 100644 index d8390d24..00000000 --- a/lib/widgets/layouts/loading_view.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:go_router/go_router.dart'; -import 'package:matrix/matrix.dart'; - -import 'package:fluffychat/utils/update_checker_no_store.dart'; -import 'package:fluffychat/widgets/layouts/empty_page.dart'; -import 'package:fluffychat/widgets/matrix.dart'; - -class LoadingView extends StatelessWidget { - const LoadingView({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - WidgetsBinding.instance.addPostFrameCallback( - (_) async { - await UpdateCheckerNoStore(context).checkUpdate(); - VRouter.of(context).to( - Matrix.of(context).widget.clients.any( - (client) => - client.onLoginStateChanged.value == LoginState.loggedIn, - ) - ? '/rooms' - : '/home', - queryParameters: VRouter.of(context).queryParameters, - ); - }, - ); - return const EmptyPage(loading: true); - } -} diff --git a/lib/widgets/layouts/side_view_layout.dart b/lib/widgets/layouts/side_view_layout.dart index d2946c55..93383d83 100644 --- a/lib/widgets/layouts/side_view_layout.dart +++ b/lib/widgets/layouts/side_view_layout.dart @@ -1,7 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; - import 'package:fluffychat/config/themes.dart'; class SideViewLayout extends StatelessWidget { @@ -12,14 +10,12 @@ class SideViewLayout extends StatelessWidget { : super(key: key); @override Widget build(BuildContext context) { - var currentUrl = Uri.decodeFull(VRouter.of(context).url); - if (!currentUrl.endsWith('/')) currentUrl += '/'; - final hideSideView = currentUrl.split('/').length == 4; final sideView = this.sideView; + final hideSideView = + !FluffyThemes.isThreeColumnMode(context) || sideView == null; return sideView == null ? mainView - : MediaQuery.of(context).size.width < FluffyThemes.columnWidth * 3.5 && - !hideSideView + : hideSideView ? sideView : Row( children: [ diff --git a/lib/widgets/layouts/two_column_layout.dart b/lib/widgets/layouts/two_column_layout.dart index 3017e851..f0fdb991 100644 --- a/lib/widgets/layouts/two_column_layout.dart +++ b/lib/widgets/layouts/two_column_layout.dart @@ -1,15 +1,15 @@ import 'package:flutter/material.dart'; -import '../../config/themes.dart'; - class TwoColumnLayout extends StatelessWidget { final Widget mainView; final Widget sideView; + final bool displayNavigationRail; const TwoColumnLayout({ Key? key, required this.mainView, required this.sideView, + required this.displayNavigationRail, }) : super(key: key); @override Widget build(BuildContext context) { @@ -20,8 +20,7 @@ class TwoColumnLayout extends StatelessWidget { Container( clipBehavior: Clip.antiAlias, decoration: const BoxDecoration(), - width: 360.0 + - (FluffyThemes.getDisplayNavigationRail(context) ? 64 : 0), + width: 360.0 + (displayNavigationRail ? 64 : 0), child: mainView, ), Container( diff --git a/lib/widgets/local_notifications_extension.dart b/lib/widgets/local_notifications_extension.dart index 84388407..68ba4db1 100644 --- a/lib/widgets/local_notifications_extension.dart +++ b/lib/widgets/local_notifications_extension.dart @@ -34,9 +34,9 @@ extension LocalNotificationsExtension on MatrixState { final event = Event.fromJson(eventUpdate.content, room); final title = - room.getLocalizedDisplayname(MatrixLocals(L10n.of(widget.context)!)); + room.getLocalizedDisplayname(MatrixLocals(L10n.of(navigatorContext)!)); final body = await event.calcLocalizedBody( - MatrixLocals(L10n.of(widget.context)!), + MatrixLocals(L10n.of(navigatorContext)!), withSenderNamePrefix: !room.isDirectChat || room.lastEvent?.senderId == client.userID, plaintextBody: true, @@ -95,11 +95,11 @@ extension LocalNotificationsExtension on MatrixState { actions: [ NotificationAction( DesktopNotificationActions.openChat.name, - L10n.of(widget.context)!.openChat, + L10n.of(navigatorContext)!.openChat, ), NotificationAction( DesktopNotificationActions.seen.name, - L10n.of(widget.context)!.markAsRead, + L10n.of(navigatorContext)!.markAsRead, ), ], hints: [ @@ -114,7 +114,7 @@ extension LocalNotificationsExtension on MatrixState { room.setReadMarker(event.eventId, mRead: event.eventId); break; case DesktopNotificationActions.openChat: - VRouter.of(navigatorContext).toSegments(['rooms', room.id]); + navigatorContext.go(['', 'rooms', room.id].join('/')); break; } }); diff --git a/lib/widgets/log_view.dart b/lib/widgets/log_view.dart index 8e62f7b8..4c58f8b4 100644 --- a/lib/widgets/log_view.dart +++ b/lib/widgets/log_view.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; import 'package:matrix/matrix.dart'; class LogViewer extends StatefulWidget { @@ -22,7 +23,9 @@ class LogViewerState extends State { backgroundColor: Colors.black, appBar: AppBar( title: Text(logLevel.toString()), - leading: const BackButton(), + leading: BackButton( + onPressed: () => context.go('/'), + ), actions: [ IconButton( icon: const Icon(Icons.zoom_in_outlined), diff --git a/lib/widgets/matrix.dart b/lib/widgets/matrix.dart index eb75a837..d82806e5 100644 --- a/lib/widgets/matrix.dart +++ b/lib/widgets/matrix.dart @@ -8,9 +8,7 @@ import 'package:flutter/material.dart'; import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:collection/collection.dart'; import 'package:desktop_notifications/desktop_notifications.dart'; -import 'package:flutter_app_lock/flutter_app_lock.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:go_router/go_router.dart'; import 'package:http/http.dart' as http; @@ -18,7 +16,6 @@ import 'package:image_picker/image_picker.dart'; import 'package:matrix/encryption.dart'; import 'package:matrix/matrix.dart'; import 'package:provider/provider.dart'; -import 'package:shared_preferences/shared_preferences.dart'; import 'package:universal_html/html.dart' as html; import 'package:url_launcher/url_launcher_string.dart'; @@ -33,7 +30,6 @@ import '../pages/key_verification/key_verification_dialog.dart'; import '../utils/account_bundles.dart'; import '../utils/background_push.dart'; import '../utils/famedlysdk_store.dart'; -import 'fluffy_chat_app.dart'; import 'local_notifications_extension.dart'; // import 'package:flutter_secure_storage/flutter_secure_storage.dart'; @@ -41,8 +37,7 @@ import 'local_notifications_extension.dart'; class Matrix extends StatefulWidget { final Widget? child; - GlobalKey get router => FluffyChatApp.routerKey; - + @Deprecated('') final BuildContext context; final List clients; @@ -177,7 +172,7 @@ class MatrixState extends State with WidgetsBindingObserver { ClientManager.addClientNameToStore(_loginClientCandidate!.clientName); _registerSubs(_loginClientCandidate!.clientName); _loginClientCandidate = null; - widget.router.currentState!.to('/rooms'); + navigatorContext.go('/rooms'); }); return candidate; } @@ -244,7 +239,8 @@ class MatrixState extends State with WidgetsBindingObserver { bool webHasFocus = true; - String? get activeRoomId => navigatorContext.vRouter.pathParameters['roomid']; + String? get activeRoomId => + GoRouterState.of(navigatorContext).pathParameters['roomid']; final linuxNotifications = PlatformInfos.isLinux ? NotificationsClient() : null; @@ -334,15 +330,21 @@ class MatrixState extends State with WidgetsBindingObserver { ); if (state != LoginState.loggedIn) { - widget.router.currentState?.to( - '/rooms', - queryParameters: widget.router.currentState?.queryParameters ?? {}, + navigatorContext.go( + Uri( + path: '/rooms', + queryParameters: + GoRouterState.of(navigatorContext).uri.queryParameters, + ).toString(), ); } } else { - widget.router.currentState?.to( - state == LoginState.loggedIn ? '/rooms' : '/home', - queryParameters: widget.router.currentState?.queryParameters ?? {}, + navigatorContext.go( + Uri( + path: state == LoginState.loggedIn ? '/rooms' : '/home', + queryParameters: + GoRouterState.of(navigatorContext).uri.queryParameters, + ).toString(), ); } }); @@ -375,23 +377,6 @@ class MatrixState extends State with WidgetsBindingObserver { } void initMatrix() { - // Display the app lock - if (PlatformInfos.isMobile) { - WidgetsBinding.instance.addPostFrameCallback((_) { - ([TargetPlatform.linux].contains(Theme.of(context).platform) - ? SharedPreferences.getInstance() - .then((prefs) => prefs.getString(SettingKeys.appLockKey)) - : const FlutterSecureStorage() - .read(key: SettingKeys.appLockKey)) - .then((lock) { - if (lock?.isNotEmpty ?? false) { - AppLock.of(widget.context)!.enable(); - AppLock.of(widget.context)!.showLockScreen(); - } - }); - }); - } - _initWithStore(); for (final c in widget.clients) { @@ -405,8 +390,7 @@ class MatrixState extends State with WidgetsBindingObserver { if (PlatformInfos.isMobile) { backgroundPush = BackgroundPush( - client, - context, + this, onFcmError: (errorMsg, {Uri? link}) async { final result = await showOkCancelAlertDialog( barrierDismissible: true, @@ -435,7 +419,7 @@ class MatrixState extends State with WidgetsBindingObserver { voipPlugin = null; return; } - voipPlugin = webrtcIsSupported ? VoipPlugin(client) : null; + voipPlugin = webrtcIsSupported ? VoipPlugin(this) : null; } @override @@ -529,30 +513,6 @@ class MatrixState extends State with WidgetsBindingObserver { } } -class FixedThreepidCreds extends ThreepidCreds { - FixedThreepidCreds({ - required String sid, - required String clientSecret, - String? idServer, - String? idAccessToken, - }) : super( - sid: sid, - clientSecret: clientSecret, - idServer: idServer, - idAccessToken: idAccessToken, - ); - - @override - Map toJson() { - final data = {}; - data['sid'] = sid; - data['client_secret'] = clientSecret; - if (idServer != null) data['id_server'] = idServer; - if (idAccessToken != null) data['id_access_token'] = idAccessToken; - return data; - } -} - class _AccountBundleWithClient { final Client? client; final AccountBundle? bundle; diff --git a/lib/widgets/profile_bottom_sheet.dart b/lib/widgets/profile_bottom_sheet.dart index 2b0cec60..0afb51cb 100644 --- a/lib/widgets/profile_bottom_sheet.dart +++ b/lib/widgets/profile_bottom_sheet.dart @@ -25,7 +25,8 @@ class ProfileBottomSheet extends StatelessWidget { future: () => client.startDirectChat(userId), ); if (result.error == null) { - VRouter.of(context).toSegments(['rooms', result.result!]); + context.go(['', 'rooms', result.result!].join('/')); + Navigator.of(context, rootNavigator: false).pop(); return; } diff --git a/lib/widgets/public_room_bottom_sheet.dart b/lib/widgets/public_room_bottom_sheet.dart index 379737dc..645e13a3 100644 --- a/lib/widgets/public_room_bottom_sheet.dart +++ b/lib/widgets/public_room_bottom_sheet.dart @@ -31,7 +31,6 @@ class PublicRoomBottomSheet extends StatelessWidget { final client = Matrix.of(context).client; final chunk = this.chunk; final navigator = Navigator.of(context); - final router = VRouter.of(context); final result = await showFutureLoadingDialog( context: context, future: () async { @@ -54,7 +53,7 @@ class PublicRoomBottomSheet extends StatelessWidget { navigator.pop(); // don't open the room if the joined room is a space if (!client.getRoomById(result.result!)!.isSpace) { - router.toSegments(['rooms', result.result!]); + context.go(['', 'rooms', result.result!].join('/')); } return; }