From 928b7ff1d6b64ac4167faad921ef3732dfadcc8a Mon Sep 17 00:00:00 2001 From: Bohdan Triapitsyn Date: Sun, 14 Jun 2026 23:06:03 +0300 Subject: [PATCH] revert: restore stable chat history scrolling --- packages/ui/src/components/chat/MessageList.tsx | 16 ++++------------ packages/ui/src/hooks/useChatAutoFollow.ts | 4 +--- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/packages/ui/src/components/chat/MessageList.tsx b/packages/ui/src/components/chat/MessageList.tsx index 0ae15742..cc3d58fa 100644 --- a/packages/ui/src/components/chat/MessageList.tsx +++ b/packages/ui/src/components/chat/MessageList.tsx @@ -1372,8 +1372,6 @@ const MessageList = React.forwardRef(({ scrollEl.scrollTop += prependedHeight; }); - const [historyVirtualRows, setHistoryVirtualRows] = React.useState(EMPTY_VIRTUAL_ROWS); - const historyVirtualizer = useVirtualizer({ count: historyEntries.length, getScrollElement: resolveScrollContainer, @@ -1383,9 +1381,6 @@ const MessageList = React.forwardRef(({ useAnimationFrameWithResizeObserver: true, overscan: MESSAGE_LIST_OVERSCAN, enabled: shouldVirtualizeHistory, - onChange: () => { - setHistoryVirtualRows(historyVirtualizer.getVirtualItems()); - }, }); React.useLayoutEffect(() => { @@ -1440,13 +1435,10 @@ const MessageList = React.forwardRef(({ }; }, []); - // Sync virtual rows on initial mount and when virtualization toggles. - // Ongoing updates are handled by the virtualizer's onChange callback. - React.useLayoutEffect(() => { - setHistoryVirtualRows( - shouldVirtualizeHistory ? historyVirtualizer.getVirtualItems() : EMPTY_VIRTUAL_ROWS, - ); - }, [shouldVirtualizeHistory, historyVirtualizer]); + const historyVirtualRows = React.useMemo( + () => (shouldVirtualizeHistory ? historyVirtualizer.getVirtualItems() : EMPTY_VIRTUAL_ROWS), + [historyVirtualizer, shouldVirtualizeHistory], + ); const allEntries = React.useMemo(() => { return trailingStreamingEntry ? [...historyEntries, trailingStreamingEntry] : historyEntries; diff --git a/packages/ui/src/hooks/useChatAutoFollow.ts b/packages/ui/src/hooks/useChatAutoFollow.ts index 7b37e272..59c281bd 100644 --- a/packages/ui/src/hooks/useChatAutoFollow.ts +++ b/packages/ui/src/hooks/useChatAutoFollow.ts @@ -411,9 +411,7 @@ export const useChatAutoFollow = ({ }, [sessionIsWorking, startFollowLoop]); // Replay a deferred restoreSnapshot once ChatViewport mounts. - // useLayoutEffect ensures scroll position is set before the browser paints, - // preventing a visible flash of content at the wrong scroll position. - React.useLayoutEffect(() => { + React.useEffect(() => { if (!containerEl) return; if (pendingInitialRestoreRef.current && pendingInitialRestoreRef.current === currentSessionId) { void restoreSnapshot();