Skip to content

fix(web): prevent near-bottom chat scroll jump - #1358

Merged
tiann merged 2 commits into
tiann:mainfrom
teekalpha:fix/chat-near-bottom-scroll-jump
Aug 7, 2026
Merged

fix(web): prevent near-bottom chat scroll jump#1358
tiann merged 2 commits into
tiann:mainfrom
teekalpha:fix/chat-near-bottom-scroll-jump

Conversation

@teekalpha

Copy link
Copy Markdown
Contributor

Summary

  • resume tail-following only after the viewport actually reaches the bottom
  • prevent downward readers from being snapped past the final content
  • add regression coverage for downward scrolling near the bottom

Tests

  • cd web && bun run test -- HappyThread.test.tsx
  • cd web && bun run typecheck

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Review mode: initial

  • One Major issue: the 1px resume cutoff can cancel an explicit smooth scroll to the tail and leave an actively streaming conversation in history mode.
  • Residual testing gap: the added helper test does not exercise the component scroll handler, smooth-scroll intermediate events, or content growth during the animation.

Testing

  • Not run (automation; PR code was not executed under the review security policy).
  • Add a component regression test that clicks the new-messages control, emits an intermediate downward scroll event, increases scrollHeight, and verifies the final mode remains tail.

HAPI Bot

return {
distanceFromBottom,
isNearBottom: distanceFromBottom < thresholdPx,
isNearBottom: distanceFromBottom <= thresholdPx,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MAJOR] Preserve explicit tail-follow during smooth scrolling

scrollToBottom() starts a smooth animation and immediately sets both tail-follow refs (HappyThread.tsx:889-899). Every intermediate animation frame then enters handleScroll; with this new 1px cutoff, those frames are not near the bottom, so the unchanged fallback at HappyThread.tsx:720-721 disables auto-scroll and switches to history. If the active assistant message grows during the animation, the smooth-scroll target is the old bottom; the ResizeObserver no longer follows because auto-scroll was disabled, and the viewport never returns to tail mode. This directly affects the new-messages button during streaming.

Suggested fix:

if (intent.isScrollingUp && intent.distanceFromBottom > MANUAL_SCROLL_EPSILON_PX) {
    setAutoScrollMode(false)
    setAtBottomMode(false)
    return
}

if (intent.isNearBottom) {
    setAutoScrollMode(true)
    setAtBottomMode(true)
}
// Preserve the current mode for downward/programmatic movement.
// A history-mode reader still resumes only after reaching the bottom.

Please also cover the full handler path with a component test: begin a smooth scroll from history, fire an intermediate downward scroll, grow scrollHeight, and assert that tail-follow is retained.

@teekalpha

Copy link
Copy Markdown
Contributor Author

Addressed the review concern in 587aba4:

  • latch explicit jump-to-tail intent across intermediate native smooth-scroll events
  • cancel the latch when the user reverses upward
  • clear it once the viewport reaches the actual bottom
  • add a component regression test covering jump-to-tail, intermediate downward scroll events, and scrollHeight growth

Validated with HappyThread.test.tsx, HappyThread.mobile-scroll.test.tsx (26 tests), and web typecheck.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Findings

  • None.

Summary

Review mode: follow-up after new commits

  • No issues found on added or modified lines at the current head.
  • The prior Major is addressed: explicit tail scrolling remains armed through downward smooth-scroll progress and clears when the viewport reaches the bottom or reverses upward.
  • Residual risk: the component regression test mocks native scrolling, so real-browser smooth-scroll and ResizeObserver scheduling are not exercised.

Testing

  • Not run (automation; PR code was not executed under the review security policy).
  • git diff --check passed.
  • The GitHub test check currently fails typecheck at web/src/router.tsx:773 because deliveryMode is missing. The same failure exists on the base commit and this PR does not modify that file, so it is not attributed to this diff.

HAPI Bot

@teekalpha
teekalpha force-pushed the fix/chat-near-bottom-scroll-jump branch from 587aba4 to 9cc4fd5 Compare August 5, 2026 01:32

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Findings

  • None.

Summary

Review mode: follow-up after new commits

  • No issues found on added or modified lines at the current head.
  • The latest update rebases the branch; the three reviewed files remain content-identical to the prior HAPI Bot pass.
  • Residual risk: the component regression test mocks native scrolling, so real-browser smooth-scroll interruption and ResizeObserver scheduling are not exercised.

Testing

  • Not run (automation; PR code was not executed under the review security policy).
  • git diff --check passed.
  • GitHub test and pr-review checks were still pending when reviewed.

HAPI Bot

@teekalpha
teekalpha force-pushed the fix/chat-near-bottom-scroll-jump branch from 9cc4fd5 to aa39028 Compare August 6, 2026 01:17

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Findings

  • None.

Summary

Review mode: follow-up after new commits

  • No issues found on added or modified lines at the current head.
  • The full current PR diff was reviewed; the post-review branch update is a rebase, and the PR remains scoped to the same three chat-scroll files.
  • Residual risk: jsdom does not exercise real-browser smooth-scroll interruption or ResizeObserver scheduling.

Testing

  • Not run (automation; PR code was not executed under the review security policy).
  • git diff --check passed for the three changed files.
  • GitHub test and pr-review checks were pending at review time.

HAPI Bot

@tiann
tiann merged commit cfca9d2 into tiann:main Aug 7, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants