From cdcc34acaac4150662d34f3577ccbaf39119cd09 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 2 Jun 2026 21:04:23 -0400 Subject: [PATCH] remember position on load older based on event id instead of scroll progress --- lib/widgets/room_chat.dart | 60 +++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/lib/widgets/room_chat.dart b/lib/widgets/room_chat.dart index 61fd3f8..2d98ced 100644 --- a/lib/widgets/room_chat.dart +++ b/lib/widgets/room_chat.dart @@ -79,11 +79,14 @@ class RoomChat extends HookConsumerWidget { final scrollController = useScrollController(); final controllerData = ref.watch(controllerProvider); - final heightBeforeLoad = useState(null); + final topEventBeforeLoad = useState(null); Future loadOlder() async { - heightBeforeLoad.value = scrollController.position.maxScrollExtent; - await notifier.loadOlder(); + if (controllerData + case AsyncData(:final value) || AsyncLoading(:final value?)) { + topEventBeforeLoad.value = value.firstOrNull?.eventId; + await notifier.loadOlder(); + } } useEffect(() { @@ -97,26 +100,37 @@ class RoomChat extends HookConsumerWidget { }, [scrollController.hasClients]); useEffect(() { - if (!scrollController.hasClients || controllerData is! AsyncData) return; - - if (heightBeforeLoad.value != null) { - WidgetsBinding.instance.addPostFrameCallback((_) { - if (scrollController.hasClients) { - scrollController.jumpTo( - scrollController.position.maxScrollExtent - - heightBeforeLoad.value!, - ); - } - heightBeforeLoad.value = null; - }); - } else if (scrollController.position.atEdge && - scrollController.position.pixels != 0) { - WidgetsBinding.instance.addPostFrameCallback((_) { - if (scrollController.hasClients) { - scrollController.jumpTo(scrollController.position.maxScrollExtent); - } - }); + if (controllerData case AsyncData( + :final value, + ) when scrollController.hasClients) { + if (topEventBeforeLoad.value != null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + if (scrollController.hasClients) { + final index = value.indexWhere( + (event) => event.eventId == topEventBeforeLoad.value, + ); + if (index != -1) { + listController.value.jumpToItem( + index: index, + scrollController: scrollController, + alignment: 0, + ); + } + } + topEventBeforeLoad.value = null; + }); + } else if (scrollController.position.atEdge && + scrollController.position.pixels != 0) { + WidgetsBinding.instance.addPostFrameCallback((_) { + if (scrollController.hasClients) { + scrollController.jumpTo( + scrollController.position.maxScrollExtent, + ); + } + }); + } } + return null; }, [controllerData]); @@ -142,7 +156,7 @@ class RoomChat extends HookConsumerWidget { scrollController.addListener(listener); return () => scrollController.removeListener(listener); - }, [roomId]); + }, [roomId, controllerData]); final composerNode = useFocusNode( onKeyEvent: (_, event) {