From 2c23951ea85245018da00e86c6fda91d186bd9e9 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Mon, 6 Apr 2026 09:57:03 -0400 Subject: [PATCH] Fix via handling --- lib/helpers/extensions/focus_room.dart | 27 ----- .../extensions/join_room_with_snackbars.dart | 63 ----------- lib/helpers/extensions/link_to_mention.dart | 3 +- lib/widgets/chat_page/join_dialog.dart | 105 ++++++++++++++++-- lib/widgets/chat_page/sidebar.dart | 2 +- 5 files changed, 101 insertions(+), 99 deletions(-) delete mode 100644 lib/helpers/extensions/focus_room.dart delete mode 100644 lib/helpers/extensions/join_room_with_snackbars.dart diff --git a/lib/helpers/extensions/focus_room.dart b/lib/helpers/extensions/focus_room.dart deleted file mode 100644 index e8b3140..0000000 --- a/lib/helpers/extensions/focus_room.dart +++ /dev/null @@ -1,27 +0,0 @@ -import "package:collection/collection.dart"; -import "package:flutter_riverpod/flutter_riverpod.dart"; -import "package:nexus/controllers/key_controller.dart"; -import "package:nexus/controllers/spaces_controller.dart"; - -extension FocusRoom on WidgetRef { - Future focusRoom(String id) async { - final spaces = watch(SpacesController.provider); - final space = spaces.firstWhereOrNull((space) => space.id == id); - - await watch(KeyController.provider(KeyController.spaceKey).notifier).set( - space?.id ?? - spaces - .firstWhere( - (space) => - space.children.any((child) => child.metadata?.id == id), - ) - .id, - ); - - if (space == null) { - await watch( - KeyController.provider(KeyController.roomKey).notifier, - ).set(id); - } - } -} diff --git a/lib/helpers/extensions/join_room_with_snackbars.dart b/lib/helpers/extensions/join_room_with_snackbars.dart deleted file mode 100644 index 0267ac3..0000000 --- a/lib/helpers/extensions/join_room_with_snackbars.dart +++ /dev/null @@ -1,63 +0,0 @@ -import "package:fast_immutable_collections/fast_immutable_collections.dart"; -import "package:flutter/material.dart"; -import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:nexus/controllers/client_controller.dart"; -import "package:nexus/helpers/extensions/focus_room.dart"; -import "package:nexus/helpers/extensions/link_to_mention.dart"; -import "package:nexus/models/requests/join_room_request.dart"; - -extension JoinRoomWithSnackbars on ClientController { - Future joinRoomWithSnackBars( - BuildContext context, - String roomAlias, - WidgetRef ref, - ) async { - final roomIdOrAlias = roomAlias.mention ?? roomAlias; - // TODO: Parse vias properly - - final scaffoldMessenger = ScaffoldMessenger.of(context); - - final snackbar = scaffoldMessenger.showSnackBar( - SnackBar( - content: Text("Joining room $roomIdOrAlias."), - duration: Duration(days: 999), - ), - ); - - try { - final id = await joinRoom( - JoinRoomRequest( - roomIdOrAlias: roomIdOrAlias, - via: IList(Uri.tryParse(roomAlias)?.queryParametersAll["via"] ?? []), - ), - ); - - snackbar.close(); - - scaffoldMessenger.showSnackBar( - SnackBar( - content: Text("Room $roomIdOrAlias successfully joined."), - action: SnackBarAction( - label: "Open", - onPressed: () => ref.focusRoom(id), - ), - ), - ); - } catch (error) { - snackbar.close(); - if (context.mounted) { - scaffoldMessenger.showSnackBar( - SnackBar( - backgroundColor: Theme.of(context).colorScheme.errorContainer, - content: Text( - error.toString(), - style: TextStyle( - color: Theme.of(context).colorScheme.onErrorContainer, - ), - ), - ), - ); - } - } - } -} diff --git a/lib/helpers/extensions/link_to_mention.dart b/lib/helpers/extensions/link_to_mention.dart index b0e62aa..f4868d3 100644 --- a/lib/helpers/extensions/link_to_mention.dart +++ b/lib/helpers/extensions/link_to_mention.dart @@ -30,7 +30,8 @@ extension LinkToMention on String { final identifier = uri.pathSegments.last; if (identifier.isNotEmpty) { return "${switch (uri.pathSegments.firstOrNull) { - "r" || "roomid" => "#", + "r" => "#", + "roomid" => "!", "u" => "@", _ => "", }}${Uri.decodeComponent(identifier)}"; diff --git a/lib/widgets/chat_page/join_dialog.dart b/lib/widgets/chat_page/join_dialog.dart index 0128037..e718200 100644 --- a/lib/widgets/chat_page/join_dialog.dart +++ b/lib/widgets/chat_page/join_dialog.dart @@ -1,15 +1,21 @@ +import "package:collection/collection.dart"; +import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:flutter/material.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/controllers/client_controller.dart"; -import "package:nexus/helpers/extensions/join_room_with_snackbars.dart"; +import "package:nexus/controllers/key_controller.dart"; +import "package:nexus/controllers/spaces_controller.dart"; +import "package:nexus/helpers/extensions/link_to_mention.dart"; +import "package:nexus/models/requests/join_room_request.dart"; import "package:nexus/widgets/form_text_input.dart"; -class JoinDialog extends HookConsumerWidget { - const JoinDialog({super.key}); +class JoinDialog extends HookWidget { + final WidgetRef ref; + const JoinDialog(this.ref, {super.key}); @override - Widget build(BuildContext context, WidgetRef ref) { + Widget build(BuildContext context) { final roomAlias = useTextEditingController(); return AlertDialog( title: Text("Join a Room"), @@ -17,7 +23,7 @@ class JoinDialog extends HookConsumerWidget { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text("Enter the room alias, ID, or a Matrix.to link."), + Text("Enter the room alias, Matrix URI, or Matrix.to link."), SizedBox(height: 12), FormTextInput( required: false, @@ -33,9 +39,94 @@ class JoinDialog extends HookConsumerWidget { onPressed: () async { Navigator.of(context).pop(); - final client = ref.watch(ClientController.provider.notifier); if (context.mounted) { - client.joinRoomWithSnackBars(context, roomAlias.text, ref); + final roomIdOrAlias = roomAlias.text.mention ?? roomAlias.text; + + final scaffoldMessenger = ScaffoldMessenger.of(context); + + final snackbar = scaffoldMessenger.showSnackBar( + SnackBar( + content: Text("Joining room $roomIdOrAlias."), + duration: Duration(days: 999), + ), + ); + + try { + final id = await ref + .watch(ClientController.provider.notifier) + .joinRoom( + JoinRoomRequest( + roomIdOrAlias: roomIdOrAlias, + via: IList( + Uri.tryParse( + roomAlias.text.replaceAll("/#", ""), + )?.queryParametersAll["via"] ?? + [], + ), + ), + ); + + snackbar.close(); + + scaffoldMessenger.showSnackBar( + SnackBar( + content: Text("Room $roomIdOrAlias successfully joined."), + action: SnackBarAction( + label: "Open", + onPressed: () async { + final spaces = ref.watch(SpacesController.provider); + final space = spaces.firstWhereOrNull( + (space) => space.id == id, + ); + + await ref + .watch( + KeyController.provider( + KeyController.spaceKey, + ).notifier, + ) + .set( + space?.id ?? + spaces + .firstWhere( + (space) => space.children.any( + (child) => child.metadata?.id == id, + ), + ) + .id, + ); + + if (space == null) { + await ref + .watch( + KeyController.provider( + KeyController.roomKey, + ).notifier, + ) + .set(id); + } + }, + ), + ), + ); + } catch (error) { + snackbar.close(); + if (context.mounted) { + scaffoldMessenger.showSnackBar( + SnackBar( + backgroundColor: Theme.of( + context, + ).colorScheme.errorContainer, + content: Text( + error.toString(), + style: TextStyle( + color: Theme.of(context).colorScheme.onErrorContainer, + ), + ), + ), + ); + } + } } }, child: Text("Join"), diff --git a/lib/widgets/chat_page/sidebar.dart b/lib/widgets/chat_page/sidebar.dart index 8534dc3..f79c38f 100644 --- a/lib/widgets/chat_page/sidebar.dart +++ b/lib/widgets/chat_page/sidebar.dart @@ -88,7 +88,7 @@ class Sidebar extends HookConsumerWidget { PopupMenuItem( onTap: () => showDialog( context: context, - builder: (_) => JoinDialog(), + builder: (_) => JoinDialog(ref), ), child: ListTile( title: Text("Join an existing room (or space)"),