From d5b359090138e76f02eb6beb38d3d377de27aea3 Mon Sep 17 00:00:00 2001 From: Bohdan Triapitsyn Date: Thu, 7 May 2026 23:02:58 +0300 Subject: [PATCH] fix: prevent live chat from snapping to latest Keeps manual scroll position during active sessions Avoids forced resume after missing chat data recovery --- packages/ui/src/components/chat/ChatContainer.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/ui/src/components/chat/ChatContainer.tsx b/packages/ui/src/components/chat/ChatContainer.tsx index fdbb7f76..3c23483d 100644 --- a/packages/ui/src/components/chat/ChatContainer.tsx +++ b/packages/ui/src/components/chat/ChatContainer.tsx @@ -787,7 +787,9 @@ export const ChatContainer: React.FC = () => { const statusType = sessionStatusForCurrent.type ?? 'idle'; const isActivePhase = statusType === 'busy' || statusType === 'retry'; const hasHashTarget = typeof window !== 'undefined' && window.location.hash.length > 0; - const shouldSkipScroll = hasHashTarget || (isActivePhase && isPinned); + // Active sessions are already followed by the scroll manager when pinned. + // If the user scrolled away, a materialization retry must not force-resume. + const shouldSkipScroll = hasHashTarget || isActivePhase; if (!shouldSkipScroll) { if (typeof window === 'undefined') { @@ -802,7 +804,7 @@ export const ChatContainer: React.FC = () => { }; void load(); - }, [currentSessionId, ensureSessionRenderable, hasRenderableSessionSnapshot, isPinned, resumeToLatestInstant, sessionStatusForCurrent.type]); + }, [currentSessionId, ensureSessionRenderable, hasRenderableSessionSnapshot, resumeToLatestInstant, sessionStatusForCurrent.type]); if (!currentSessionId && !draftOpen) { return (