From a8383951ba5fe93d6d1678235b6252dd4efbb134 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 4 Apr 2026 18:26:19 -0400 Subject: [PATCH] Refactor dialog stuff --- lib/helpers/extensions/focus_room.dart | 27 ++++++++++ .../extensions/join_room_with_snackbars.dart | 34 ++---------- lib/helpers/extensions/link_to_mention.dart | 4 +- lib/widgets/chat_page/html/mention_chip.dart | 9 ++-- lib/widgets/chat_page/join_dialog.dart | 46 ++++++++++++++++ lib/widgets/chat_page/sidebar.dart | 53 +------------------ 6 files changed, 83 insertions(+), 90 deletions(-) create mode 100644 lib/helpers/extensions/focus_room.dart create mode 100644 lib/widgets/chat_page/join_dialog.dart diff --git a/lib/helpers/extensions/focus_room.dart b/lib/helpers/extensions/focus_room.dart new file mode 100644 index 0000000..e8b3140 --- /dev/null +++ b/lib/helpers/extensions/focus_room.dart @@ -0,0 +1,27 @@ +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 index eaa0659..4cf1f68 100644 --- a/lib/helpers/extensions/join_room_with_snackbars.dart +++ b/lib/helpers/extensions/join_room_with_snackbars.dart @@ -1,10 +1,8 @@ -import "package:collection/collection.dart"; 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/controllers/key_controller.dart"; -import "package:nexus/controllers/spaces_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"; @@ -14,7 +12,7 @@ extension JoinRoomWithSnackbars on ClientController { String roomAlias, WidgetRef ref, ) async { - final roomIdOrAlias = roomAlias.mention ?? roomAlias; + final roomIdOrAlias = roomAlias.mention; // TODO: Parse vias properly final scaffoldMessenger = ScaffoldMessenger.of(context); @@ -41,33 +39,7 @@ extension JoinRoomWithSnackbars on ClientController { 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); - } - }, + onPressed: () => ref.focusRoom(id), ), ), ); diff --git a/lib/helpers/extensions/link_to_mention.dart b/lib/helpers/extensions/link_to_mention.dart index b0e62aa..289de3f 100644 --- a/lib/helpers/extensions/link_to_mention.dart +++ b/lib/helpers/extensions/link_to_mention.dart @@ -9,7 +9,7 @@ extension LinkToMention on String { /// /// Returns the decoded identifier (e.g. "#room:matrix.org") /// or null if this is not a Matrix link. - String? get mention { + String get mention { final trimmed = trim(); final matrixTo = RegExp( @@ -39,6 +39,6 @@ extension LinkToMention on String { } catch (_) {} } - return null; + return this; } } diff --git a/lib/widgets/chat_page/html/mention_chip.dart b/lib/widgets/chat_page/html/mention_chip.dart index 0f80617..d4b9927 100644 --- a/lib/widgets/chat_page/html/mention_chip.dart +++ b/lib/widgets/chat_page/html/mention_chip.dart @@ -10,11 +10,9 @@ class MentionChip extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final mention = label.mention; - final membership = - mention?.startsWith("@") == true || label.startsWith("@") == true + final membership = label.mention.startsWith("@") == true ? ref - .watch(UserController.provider(mention ?? label)) + .watch(UserController.provider(label.mention)) .whenOrNull(data: (data) => data) : null; @@ -31,8 +29,7 @@ class MentionChip extends ConsumerWidget { child: Chip( label: Text( (membership == null ? null : "@${membership.displayName}") ?? - mention ?? - label, + label.mention, style: TextStyle( fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.onPrimary, diff --git a/lib/widgets/chat_page/join_dialog.dart b/lib/widgets/chat_page/join_dialog.dart new file mode 100644 index 0000000..0128037 --- /dev/null +++ b/lib/widgets/chat_page/join_dialog.dart @@ -0,0 +1,46 @@ +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/widgets/form_text_input.dart"; + +class JoinDialog extends HookConsumerWidget { + const JoinDialog({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final roomAlias = useTextEditingController(); + return AlertDialog( + title: Text("Join a Room"), + content: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("Enter the room alias, ID, or a Matrix.to link."), + SizedBox(height: 12), + FormTextInput( + required: false, + capitalize: true, + controller: roomAlias, + title: "#room:server", + ), + ], + ), + actions: [ + TextButton(onPressed: Navigator.of(context).pop, child: Text("Cancel")), + TextButton( + onPressed: () async { + Navigator.of(context).pop(); + + final client = ref.watch(ClientController.provider.notifier); + if (context.mounted) { + client.joinRoomWithSnackBars(context, roomAlias.text, ref); + } + }, + child: Text("Join"), + ), + ], + ); + } +} diff --git a/lib/widgets/chat_page/sidebar.dart b/lib/widgets/chat_page/sidebar.dart index 18413a0..8534dc3 100644 --- a/lib/widgets/chat_page/sidebar.dart +++ b/lib/widgets/chat_page/sidebar.dart @@ -1,14 +1,11 @@ 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/controllers/key_controller.dart"; import "package:nexus/controllers/selected_space_controller.dart"; import "package:nexus/controllers/spaces_controller.dart"; -import "package:nexus/helpers/extensions/join_room_with_snackbars.dart"; import "package:nexus/widgets/avatar_or_hash.dart"; +import "package:nexus/widgets/chat_page/join_dialog.dart"; import "package:nexus/widgets/chat_page/room_menu.dart"; -import "package:nexus/widgets/form_text_input.dart"; class Sidebar extends HookConsumerWidget { final bool isDesktop; @@ -91,53 +88,7 @@ class Sidebar extends HookConsumerWidget { PopupMenuItem( onTap: () => showDialog( context: context, - builder: (alertContext) => HookBuilder( - builder: (_) { - final roomAlias = useTextEditingController(); - return AlertDialog( - title: Text("Join a Room"), - content: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "Enter the room alias, ID, or a Matrix.to link.", - ), - SizedBox(height: 12), - FormTextInput( - required: false, - capitalize: true, - controller: roomAlias, - title: "#room:server", - ), - ], - ), - actions: [ - TextButton( - onPressed: Navigator.of(context).pop, - child: Text("Cancel"), - ), - TextButton( - onPressed: () async { - Navigator.of(alertContext).pop(); - - final client = ref.watch( - ClientController.provider.notifier, - ); - if (context.mounted) { - client.joinRoomWithSnackBars( - context, - roomAlias.text, - ref, - ); - } - }, - child: Text("Join"), - ), - ], - ); - }, - ), + builder: (_) => JoinDialog(), ), child: ListTile( title: Text("Join an existing room (or space)"),