Don't reverse the CustomScrollView #34

Manually merged
Henry-Hiles merged 4 commits from non-reversed-scroll-view into main 2026-06-02 21:10:02 -04:00
Showing only changes of commit cdcc34acaa - Show all commits

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

Henry Hiles 2026-06-02 21:04:23 -04:00
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs

View file

@ -79,11 +79,14 @@ class RoomChat extends HookConsumerWidget {
final scrollController = useScrollController(); final scrollController = useScrollController();
final controllerData = ref.watch(controllerProvider); final controllerData = ref.watch(controllerProvider);
final heightBeforeLoad = useState<double?>(null); final topEventBeforeLoad = useState<String?>(null);
Future<void> loadOlder() async { Future<void> loadOlder() async {
heightBeforeLoad.value = scrollController.position.maxScrollExtent; if (controllerData
await notifier.loadOlder(); case AsyncData(:final value) || AsyncLoading(:final value?)) {
topEventBeforeLoad.value = value.firstOrNull?.eventId;
await notifier.loadOlder();
}
} }
useEffect(() { useEffect(() {
@ -97,26 +100,37 @@ class RoomChat extends HookConsumerWidget {
}, [scrollController.hasClients]); }, [scrollController.hasClients]);
useEffect(() { useEffect(() {
if (!scrollController.hasClients || controllerData is! AsyncData) return; if (controllerData case AsyncData(
:final value,
if (heightBeforeLoad.value != null) { ) when scrollController.hasClients) {
WidgetsBinding.instance.addPostFrameCallback((_) { if (topEventBeforeLoad.value != null) {
if (scrollController.hasClients) { WidgetsBinding.instance.addPostFrameCallback((_) {
scrollController.jumpTo( if (scrollController.hasClients) {
scrollController.position.maxScrollExtent - final index = value.indexWhere(
heightBeforeLoad.value!, (event) => event.eventId == topEventBeforeLoad.value,
); );
} if (index != -1) {
heightBeforeLoad.value = null; listController.value.jumpToItem(
}); index: index,
} else if (scrollController.position.atEdge && scrollController: scrollController,
scrollController.position.pixels != 0) { alignment: 0,
WidgetsBinding.instance.addPostFrameCallback((_) { );
if (scrollController.hasClients) { }
scrollController.jumpTo(scrollController.position.maxScrollExtent); }
} 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; return null;
}, [controllerData]); }, [controllerData]);
@ -142,7 +156,7 @@ class RoomChat extends HookConsumerWidget {
scrollController.addListener(listener); scrollController.addListener(listener);
return () => scrollController.removeListener(listener); return () => scrollController.removeListener(listener);
}, [roomId]); }, [roomId, controllerData]);
final composerNode = useFocusNode( final composerNode = useFocusNode(
onKeyEvent: (_, event) { onKeyEvent: (_, event) {