From 1215be0b21fc18eb39886ea27cfcbdc813ab3d29 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 2 Jun 2026 20:42:04 -0400 Subject: [PATCH] attempt to remember position when loading history --- lib/controllers/room_chat_controller.dart | 4 ++- lib/widgets/room_chat.dart | 32 +++++++++++++++++++---- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/lib/controllers/room_chat_controller.dart b/lib/controllers/room_chat_controller.dart index 7e7eebc..84ac7b0 100644 --- a/lib/controllers/room_chat_controller.dart +++ b/lib/controllers/room_chat_controller.dart @@ -39,7 +39,9 @@ class RoomChatController extends AsyncNotifier> { } return room.timeline - .toValueIList(sort: true, compare: (a, b) => (a ?? 0).compareTo(b ?? 0)) + .toEntryIList(compare: (a, b) => (a?.key ?? 0).compareTo(b?.key ?? 0)) + .map((element) => element.value) + .toIList() .addAll(room.sticky) .map((entry) { final foundEvent = entry == null ? null : room.events[entry]; diff --git a/lib/widgets/room_chat.dart b/lib/widgets/room_chat.dart index 92aa95a..61fd3f8 100644 --- a/lib/widgets/room_chat.dart +++ b/lib/widgets/room_chat.dart @@ -79,6 +79,13 @@ class RoomChat extends HookConsumerWidget { final scrollController = useScrollController(); final controllerData = ref.watch(controllerProvider); + final heightBeforeLoad = useState(null); + + Future loadOlder() async { + heightBeforeLoad.value = scrollController.position.maxScrollExtent; + await notifier.loadOlder(); + } + useEffect(() { WidgetsBinding.instance.addPostFrameCallback((_) { if (scrollController.hasClients) { @@ -90,8 +97,19 @@ class RoomChat extends HookConsumerWidget { }, [scrollController.hasClients]); useEffect(() { - if (scrollController.hasClients && - scrollController.position.atEdge && + 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) { @@ -104,7 +122,9 @@ class RoomChat extends HookConsumerWidget { useEffect(() { Future listener() async { - if (!scrollController.position.atEdge) return; + if (!scrollController.hasClients || !scrollController.position.atEdge) { + return; + } final room = ref.watch( RoomsController.provider.select((value) => value[roomId]), @@ -112,7 +132,9 @@ class RoomChat extends HookConsumerWidget { if (room == null) return; if (scrollController.position.pixels == 0) { - if (room.hasMore) await notifier.loadOlder(); + if (room.hasMore) { + await loadOlder(); + } } else { await client.markRead(room); } @@ -369,7 +391,7 @@ class RoomChat extends HookConsumerWidget { child: Center( child: ElevatedButton( onPressed: controllerData is AsyncData - ? notifier.loadOlder + ? loadOlder : null, child: Text("Load More"), ),