← Back to PRs

#19783: fix(ui): prevent chat auto-scroll from fighting user scroll during streaming

by aleiby open 2026-02-18 05:06 View on GitHub →
app: web-ui size: S
## Summary - Replaces the `chatScrollPending` boolean guard with a dual-threshold approach that cleanly separates auto-scroll re-engage (50px) from the "new messages below" indicator (450px) - Removes the `distanceFromBottom` fallback from `shouldStick` in `scheduleChatScroll` — `chatUserNearBottom` is now the sole authority for whether to auto-scroll - Adds `skipLoading` option to `loadChatHistory` so post-stream history refresh doesn't flash a loading indicator ## Problem During agent streaming responses, each token update triggers `scheduleChatScroll` → `scrollTo()` → browser fires scroll event → `handleChatScroll` resets `chatUserNearBottom = true` (using the same 450px threshold as the "should we auto-scroll?" check) → next `scheduleChatScroll` sees user as "near bottom" and scrolls again. This creates a feedback loop that prevents users from scrolling up while a response is streaming. ## Approach Use two separate thresholds in `handleChatScroll`: - **`SCROLL_LOCK_THRESHOLD` (50px)**: Controls `chatUserNearBottom`. Kept tight so any deliberate upward scroll immediately disengages auto-scroll, while the browser's own programmatic-scroll events (which land at distance ≈ 0) keep it active. - **`NEAR_BOTTOM_THRESHOLD` (450px)**: Only controls dismissal of the "new messages below" indicator. In `scheduleChatScroll`, `shouldStick` is simplified to `effectiveForce || host.chatUserNearBottom` — no distance fallback. This means `handleChatScroll`'s 50px threshold is the single source of truth for auto-scroll behavior. The `chatScrollPending` flag is removed entirely — it's no longer needed because the tight 50px threshold naturally distinguishes programmatic scrolls (distance ≈ 0) from user scrolls (distance > 50px). ## Test plan - [ ] Open chat, start a long agent response streaming - [ ] Scroll up while streaming — viewport should stay where user scrolled - [ ] "New messages below" indicator should appear - [ ] Scroll back to bottom — auto-scroll resumes - [ ] Initial page load still auto-scrolls to bottom - [ ] Unit tests updated with dual-threshold coverage --- 🤖 [Tackled](https://github.com/aleiby/claude-skills/tree/main/tackle) with [Claude Code](https://claude.com/claude-code)

Most Similar PRs