fix(mobile): stop streaming scroll follow from shifting the document layer - #715
Merged
Merged
Conversation
…layer On mobile, invoking the keyboard while the agent is streaming made the whole app visibly flash/jump. scrollIntoView on the messages-end sentinel propagates to every scrollable ancestor; when the keyboard has shifted the document layer, each streamed chunk scrolled that layer too, so the page visibly jumped on every live-follow tick (on top of the composer riding the keyboard animation). Scroll the chat container directly via container.scrollTo instead, and drop the now-unused messages-end sentinel. Live-follow attach/detach logic, the prompt anchor, and scroll-position restoration are unchanged. Verified on a real device (iOS Safari + PWA): keyboard invocation during streaming no longer flashes the app.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #714
Summary
On mobile, invoking the keyboard while the agent is streaming made the whole app visibly flash/jump (roughly on every streamed chunk). The live-follow scroll used
scrollIntoView()on themessagesEndRefsentinel, which propagates to every scrollable ancestor — including the keyboard-shifted document layer that mobile browsers (WebKit in particular) keep moving while the keyboard is up. This change scrolls the chat container directly, so programmatic follow-scrolls can never touch the document layer.What changed
hooks/useAgentSession.ts:scrollToBottomnow callscontainer.scrollTo({ top: container.scrollHeight, behavior })on the chat container itself instead ofscrollIntoView()on the sentinel; also returns early when the container is missing. Live-follow attach/detach logic, the prompt anchor, and scroll-position restoration are unchanged.components/ChatWindow.tsx: removed the now-unusedmessagesEndRefsentinel<div>and its destructured ref.hooks/useAgentSession.test.mjs: updated the three structural assertions that matched the old implementation (container-scroll assertions + adoesNotMatchguard against re-introducingscrollIntoViewhere).Testing
node --experimental-strip-types --test hooks/useAgentSession.test.mjs lib/chat-lazy-load.test.mjs: 37/37 passChatWindow.notices,ChatWindow.process-details,MobilePwaLayout,model-scope-startup,model-switching): 15/15 passlib/worktree.test.mjs"main and linked worktrees share one canonical project root") also fails on unmodifiedmainin this environment and is unrelated to this changetsc --noEmit: clean;npm run lint: clean