From a077735bcfa357fe267aae5e0562b4a2f0bcacbc Mon Sep 17 00:00:00 2001 From: Bohdan Triapitsyn Date: Fri, 1 May 2026 14:13:18 +0300 Subject: [PATCH] fix: keep chat pinned during delayed rendering Keeps long historical sessions scrolled to the bottom after load Preserves bottom follow while assistant responses grow --- packages/ui/src/hooks/useChatScrollManager.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/ui/src/hooks/useChatScrollManager.ts b/packages/ui/src/hooks/useChatScrollManager.ts index ce373b7c..6573a845 100644 --- a/packages/ui/src/hooks/useChatScrollManager.ts +++ b/packages/ui/src/hooks/useChatScrollManager.ts @@ -85,6 +85,7 @@ export const useChatScrollManager = ({ }: UseChatScrollManagerOptions): UseChatScrollManagerResult => { const scrollRef = React.useRef(null); const scrollEngine = useScrollEngine({ containerRef: scrollRef, isMobile }); + const cancelScrollFollow = scrollEngine.cancelFollow; const getPinThreshold = React.useCallback(() => { const container = scrollRef.current; @@ -196,9 +197,9 @@ export const useChatScrollManager = ({ markAutoScroll(Math.max(0, bottom)); scrollEngine.scrollToPosition(Math.max(0, bottom), { ...options, - persistFollow: Boolean(options?.followBottom && sessionIsWorking), + persistFollow: Boolean(options?.followBottom), }); - }, [markAutoScroll, scrollEngine, sessionIsWorking]); + }, [markAutoScroll, scrollEngine]); const scrollPinnedToBottom = React.useCallback((distanceFromBottom: number) => { if (sessionIsWorking) { @@ -571,10 +572,10 @@ export const useChatScrollManager = ({ // Maintain pin-to-bottom when content changes React.useEffect(() => { if (!sessionIsWorking) { - scrollEngine.cancelFollow(); + cancelScrollFollow(); setFollowMode('none'); } - }, [scrollEngine, sessionIsWorking, setFollowMode]); + }, [cancelScrollFollow, sessionIsWorking, setFollowMode]); React.useEffect(() => { if (isSyncing) {