remember position on load older based on event id instead of scroll progress

This commit is contained in:
Henry Hiles 2026-06-02 21:04:23 -04:00
commit cdcc34acaa
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs

View file

@ -79,11 +79,14 @@ class RoomChat extends HookConsumerWidget {
final scrollController = useScrollController();
final controllerData = ref.watch(controllerProvider);
final heightBeforeLoad = useState<double?>(null);
final topEventBeforeLoad = useState<String?>(null);
Future<void> 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) {