From f6da59ad40c58f1b03d131098e7e9f8af32b9076 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 14 Jul 2026 23:00:48 +0000 Subject: [PATCH] jump to pinned events in view --- lib/widgets/pinned_events_drawer.dart | 25 +++++++++---- lib/widgets/room_chat.dart | 53 ++++++++++++++------------- 2 files changed, 45 insertions(+), 33 deletions(-) diff --git a/lib/widgets/pinned_events_drawer.dart b/lib/widgets/pinned_events_drawer.dart index 8873a45..818417e 100644 --- a/lib/widgets/pinned_events_drawer.dart +++ b/lib/widgets/pinned_events_drawer.dart @@ -9,8 +9,14 @@ import "package:nexus/widgets/renderers/event.dart"; class PinnedEventsDrawer extends HookConsumerWidget { final String roomId; - final IList Function(Event event)? getEventOptions; - const PinnedEventsDrawer(this.roomId, {this.getEventOptions, super.key}); + final IList Function(Event event) getEventOptions; + final Future Function(String eventId) jumpToId; + const PinnedEventsDrawer( + this.roomId, { + required this.getEventOptions, + required this.jumpToId, + super.key, + }); @override Widget build(BuildContext context, WidgetRef ref) { @@ -60,13 +66,16 @@ class PinnedEventsDrawer extends HookConsumerWidget { borderRadius: .circular(12), onTap: () { Navigator.pop(context); - // TODO: // Close drawer, then scroll to the message + jumpToId(event.eventId); }, - child: EventRenderer( - event, - maxLines: 2, - isGrouped: false, - getEventOptions: getEventOptions, + child: Padding( + padding: .symmetric(vertical: 4), + child: EventRenderer( + event, + maxLines: 2, + isGrouped: false, + getEventOptions: getEventOptions, + ), ), ); }, diff --git a/lib/widgets/room_chat.dart b/lib/widgets/room_chat.dart index c0c76b4..7c6facf 100644 --- a/lib/widgets/room_chat.dart +++ b/lib/widgets/room_chat.dart @@ -81,6 +81,27 @@ class RoomChat extends HookConsumerWidget { final topEventBeforeLoad = useState(null); + Future jumpToId(String eventId) async { + final index = controllerData.value?.indexWhere( + (element) => element.eventId == eventId, + ); + if (index == null) return; + + listController.value.animateToItem( + index: index, + scrollController: scrollController, + alignment: 0.5, + duration: (_) => .new(milliseconds: 700), + curve: (_) => Curves.easeInOut, + ); + highlightedEvent.value = eventId; + await Future.delayed(.new(seconds: 1), () { + if (highlightedEvent.value == eventId) { + highlightedEvent.value = null; + } + }); + } + Future loadOlder() async { if (controllerData case AsyncData(:final value?)) { topEventBeforeLoad.value = value.firstOrNull?.eventId; @@ -414,7 +435,11 @@ class RoomChat extends HookConsumerWidget { } return Scaffold( - endDrawer: PinnedEventsDrawer(roomId, getEventOptions: getEventOptions), + endDrawer: PinnedEventsDrawer( + roomId, + getEventOptions: getEventOptions, + jumpToId: jumpToId, + ), body: Builder( builder: (middleContext) => Scaffold( endDrawer: showMembersByDefault ? null : MemberList(roomId), @@ -468,30 +493,8 @@ class RoomChat extends HookConsumerWidget { return HighlightWrapper( EventRenderer( event, - onTapReply: () async { - final replyId = event.replyTo; - listController.value.animateToItem( - index: value.indexWhere( - (element) => - element.eventId == replyId, - ), - scrollController: scrollController, - alignment: 0.5, - duration: (_) => - .new(milliseconds: 700), - curve: (_) => Curves.easeInOut, - ); - highlightedEvent.value = replyId; - await Future.delayed( - .new(seconds: 1), - () { - if (highlightedEvent.value == - replyId) { - highlightedEvent.value = null; - } - }, - ); - }, + onTapReply: () => + jumpToId(event.replyTo!), getEventOptions: getEventOptions, isGrouped: previousEvent?.content