From 856072e0b0ceb20b7de337211467dee656b2a5c5 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Thu, 24 Sep 2026 20:22:30 -0400 Subject: [PATCH] fixup! refactor chatview to have two sliver lists --- lib/helpers/hooks/chat_scroll.dart | 76 ++++++++++-------------- lib/widgets/room_chat/chat_timeline.dart | 2 +- 2 files changed, 32 insertions(+), 46 deletions(-) diff --git a/lib/helpers/hooks/chat_scroll.dart b/lib/helpers/hooks/chat_scroll.dart index 1a27974..15a5add 100644 --- a/lib/helpers/hooks/chat_scroll.dart +++ b/lib/helpers/hooks/chat_scroll.dart @@ -11,9 +11,6 @@ final class ChatScroll({ required final ListController historyListController, required final ListController liveListController, required final ScrollController scrollController, - required final bool hasMore, - required final bool isLoadingOlder, - required final Future Function() loadOlder, required final Future Function(String id) jumpToId, }) { static ChatScroll use({ @@ -28,8 +25,6 @@ final class ChatScroll({ final centerKey = useMemoized(GlobalKey.new); final anchorId = useState(null); - final hasMore = useState(true); - final isLoadingOlder = useState(false); final anchorIdValue = anchorId.value; @@ -65,17 +60,40 @@ final class ChatScroll({ }, [controllerData, anchorIdValue]); Future loadOlderItems() async { - if (!hasMore.value || isLoadingOlder.value) return; + if (controllerData.isLoading) return; - isLoadingOlder.value = true; - - try { - hasMore.value = await loadOlder(); - } finally { - isLoadingOlder.value = false; - } + await loadOlder(); } + useEffect(() { + const loadThreshold = 500.0; + const bottomThreshold = 50.0; + + void checkPosition() { + if (!scrollController.hasClients) return; + + final position = scrollController.position; + + if (position.extentAfter <= loadThreshold) { + loadOlderItems(); + } + + if (position.extentBefore <= bottomThreshold) { + onReachedBottom(); + } + } + + scrollController.addListener(checkPosition); + + WidgetsBinding.instance.addPostFrameCallback((_) { + checkPosition(); + }); + + return () { + scrollController.removeListener(checkPosition); + }; + }, [scrollController, controllerData, loadOlder, onReachedBottom]); + Future jumpToId(String itemId) async { if (!scrollController.hasClients) return; @@ -108,35 +126,6 @@ final class ChatScroll({ } } - useEffect(() { - const loadThreshold = 500.0; - const bottomThreshold = 50.0; - - void checkPosition() { - if (!scrollController.hasClients) { - return; - } - - final position = scrollController.position; - - if (position.extentAfter <= loadThreshold) { - if (hasMore.value && !isLoadingOlder.value) { - loadOlderItems(); - } - } - - if (position.extentBefore <= bottomThreshold) { - onReachedBottom(); - } - } - - scrollController.addListener(checkPosition); - - WidgetsBinding.instance.addPostFrameCallback((_) => checkPosition()); - - return () => scrollController.removeListener(checkPosition); - }, [scrollController, onReachedBottom]); - return .new( historyItems: split.history, liveItems: split.live, @@ -144,9 +133,6 @@ final class ChatScroll({ historyListController: historyListController.value, liveListController: liveListController.value, scrollController: scrollController, - hasMore: hasMore.value, - isLoadingOlder: isLoadingOlder.value, - loadOlder: loadOlderItems, jumpToId: jumpToId, ); } diff --git a/lib/widgets/room_chat/chat_timeline.dart b/lib/widgets/room_chat/chat_timeline.dart index 09fcaf8..434145c 100644 --- a/lib/widgets/room_chat/chat_timeline.dart +++ b/lib/widgets/room_chat/chat_timeline.dart @@ -68,7 +68,7 @@ class const ChatTimeline({ itemCount: scroll.historyItems.length, itemBuilder: (_, index) => eventRow( scroll.historyItems[index], - scroll.historyItems.getOrNull(index), + scroll.historyItems.getOrNull(index + 1), jumpToId: jumpToId, getEventOptions: getEventOptions, highlightedEvent: highlightedEvent,