diff --git a/lib/controllers/contextual_event.dart b/lib/controllers/contextual_event.dart deleted file mode 100644 index e17c0a4..0000000 --- a/lib/controllers/contextual_event.dart +++ /dev/null @@ -1,16 +0,0 @@ -import "package:flutter_riverpod/flutter_riverpod.dart"; - -class ContextualEventController(String? _) extends Notifier { - @override - int? build() => null; - - void set(int? event) => state = event; - - @override - bool updateShouldNotify(_, _) => true; - - static final provider = - NotifierProvider.family( - ContextualEventController.new, - ); -} diff --git a/lib/controllers/jump_request.dart b/lib/controllers/jump_request.dart new file mode 100644 index 0000000..fc21ab2 --- /dev/null +++ b/lib/controllers/jump_request.dart @@ -0,0 +1,17 @@ +import "package:flutter_riverpod/flutter_riverpod.dart"; + +typedef JumpRequest = ({String roomId, int rowId}); + +class JumpRequestController extends Notifier { + @override + JumpRequest? build() => null; + + void request(String roomId, int rowId) => + state = (roomId: roomId, rowId: rowId); + + void consume() => state = null; + + static final provider = NotifierProvider( + JumpRequestController.new, + ); +} diff --git a/lib/helpers/extensions/focus_room.dart b/lib/helpers/extensions/focus_room.dart index 64ddb7f..18c1be4 100644 --- a/lib/helpers/extensions/focus_room.dart +++ b/lib/helpers/extensions/focus_room.dart @@ -1,6 +1,6 @@ import "package:collection/collection.dart"; import "package:flutter_riverpod/experimental/mutation.dart"; -import "package:nexus/controllers/contextual_event.dart"; +import "package:nexus/controllers/jump_request.dart"; import "package:nexus/controllers/key.dart"; import "package:nexus/controllers/spaces.dart"; import "package:nexus/models/space.dart"; @@ -31,16 +31,16 @@ extension FocusRoom on MutationTarget { .read(KeyController.provider(KeyController.spaceKey).notifier) .set(parent.id); + if (eventRowId != null) { + container + .read(JumpRequestController.provider.notifier) + .request(roomId, eventRowId); + } + await container .read(KeyController.provider(KeyController.roomKey).notifier) .set(roomId); - if (eventRowId != null) { - container - .read(ContextualEventController.provider(roomId).notifier) - .set(eventRowId); - } - return true; } } diff --git a/lib/widgets/pages/chat.dart b/lib/widgets/pages/chat.dart index 0a57351..74aea14 100644 --- a/lib/widgets/pages/chat.dart +++ b/lib/widgets/pages/chat.dart @@ -1,7 +1,6 @@ import "package:material_ui/material_ui.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/controllers/init_complete.dart"; -import "package:nexus/controllers/contextual_event.dart"; import "package:nexus/controllers/key.dart"; import "package:nexus/widgets/appbar.dart"; import "package:nexus/widgets/sidebar.dart"; @@ -27,19 +26,11 @@ class const ChatPage({super.key}) extends HookConsumerWidget { children: [ if (isDesktop) Sidebar(), Expanded( - child: Consumer( - builder: (context, ref, _) { - final initialHighlight = ref.watch( - ContextualEventController.provider(roomId), - ); - return RoomChat( - key: ValueKey((roomId, initialHighlight)), - roomId: roomId, - isDesktop: isDesktop, - initialHighlight: initialHighlight, - showMembersByDefault: showMembersByDefault, - ); - }, + child: RoomChat( + key: ValueKey(roomId), + roomId: roomId, + isDesktop: isDesktop, + showMembersByDefault: showMembersByDefault, ), ), ], diff --git a/lib/widgets/room_chat/room_chat.dart b/lib/widgets/room_chat/room_chat.dart index 2473708..2aa3f8f 100644 --- a/lib/widgets/room_chat/room_chat.dart +++ b/lib/widgets/room_chat/room_chat.dart @@ -21,19 +21,24 @@ import "package:nexus/widgets/room_appbar.dart"; import "package:nexus/main.dart"; import "package:nexus/widgets/room_chat/chat_timeline.dart"; import "package:nexus/helpers/extensions/build_event_options.dart"; +import "package:nexus/controllers/jump_request.dart"; final class const RoomChat({ required final String? roomId, required final bool isDesktop, required final bool showMembersByDefault, - final int? initialHighlight, super.key, }) extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final relatedEvent = useState(null); final relationType = useState(RelationType.reply); - final contextualEvent = useState(initialHighlight); + final pendingJump = ref.read(JumpRequestController.provider); + final contextualEvent = useState( + pendingJump != null && pendingJump.roomId == this.roomId + ? pendingJump.rowId + : null, + ); final highlightedEvent = useState(null); final composerSize = useState(64); @@ -110,23 +115,23 @@ final class const RoomChat({ }); } - useEffect(() { - if (initialHighlight == null) return null; + ref.listen(JumpRequestController.provider, (_, request) { + if (request == null || request.roomId != roomId) return; - void check() { + void tryJump() { if (!context.mounted) return; + if (ref.read(JumpRequestController.provider) != request) return; if (scroll.scrollController.hasClients) { - jumpToEvent(initialHighlight!); + ref.read(JumpRequestController.provider.notifier).consume(); + jumpToEvent(request.rowId); } else { - WidgetsBinding.instance.addPostFrameCallback((_) => check()); + WidgetsBinding.instance.addPostFrameCallback((_) => tryJump()); } } - check(); - - return null; - }, [initialHighlight]); + WidgetsBinding.instance.addPostFrameCallback((_) => tryJump()); + }); IList getEventOptions(Event event) => event.buildEventOptions(