Skip to content

fix(web): stabilize chat timeline positioning - #5449

Draft
jmeistrich wants to merge 5 commits into
pingdotgg:mainfrom
jmeistrich:fix/web-legend-list-3.3.3
Draft

fix(web): stabilize chat timeline positioning#5449
jmeistrich wants to merge 5 commits into
pingdotgg:mainfrom
jmeistrich:fix/web-legend-list-3.3.3

Conversation

@jmeistrich

@jmeistrich jmeistrich commented Aug 5, 2026

Copy link
Copy Markdown

What Changed

Fixed some usage of LegendList to make the chat smoother. This mostly removes app code in favor of using LegendList's internal behavior.

Why

Chat was not as smooth as it could be.

UI Changes

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Note

Medium Risk
Large removal of scroll state in a core chat UI with behavior changes during streaming, send anchoring, and expand/collapse; risk is regressions in scroll position rather than data/security.

Overview
Bumps @legendapp/list from 3.2.0 to 3.3.3 and shifts chat timeline scroll behavior onto the list’s built-in maintainScrollAtEnd / maintainVisibleContentPosition instead of custom logic.

Removes the manual scroll system in ChatView (scroll modes, live-follow refs, wheel/touch/pointer opt-out, rAF follow loops, anchor size restore) and deletes timelineScrollAnchoring.ts and its tests. Send/scroll-to-bottom still set timelineAnchor and call scrollToIndex / scrollToEnd, but no longer drive anchoring metrics or manual navigation cancellation.

In MessagesTimeline, maintainScrollAtEnd stays on (non-animated, on data/layout changes) even when anchoredEndSpace is active—previously it was disabled during anchoring. Fold/expand for turns and work groups briefly turns off end maintenance and uses shouldRestorePosition scoped to the toggled row; the old flushSync + DOM scroll delta compensation on work-group toggles is gone. onAnchorSizeChanged and onManualNavigation are dropped from the timeline API.

Reviewed by Cursor Bugbot for commit 8cf8708. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Stabilize chat timeline scroll positioning by replacing manual anchor logic with maintainScrollAtEnd

  • Removes the custom TimelineScrollMode anchoring system and all associated refs, state, and scroll-restore logic from ChatView.tsx and MessagesTimeline.tsx, deleting timelineScrollAnchoring.ts entirely.
  • Introduces a TIMELINE_MAINTAIN_SCROLL_AT_END config in MessagesTimeline using @legendapp/list v3.3.3's maintainScrollAtEnd (bumped from 3.2.0), with animated=false and all layout change hooks enabled.
  • When a workgroup row is folded/unfolded, maintainScrollAtEnd is briefly suspended via suspendEndScrollMaintenanceForDisclosure to let the layout settle, with maintainVisibleContentPosition scoped to the toggled row via shouldRestorePosition.
  • WorkGroupToggleTimelineRow no longer performs manual DOM measurement or scroll delta compensation on click — position maintenance is fully delegated to the list.
  • Behavioral Change: onAnchorSizeChanged and onManualNavigation props are removed from MessagesTimeline's public API.

Macroscope summarized 8cf8708.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 19197044-85e4-4bfa-9486-d019b4808ea2

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 5, 2026

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 221222ccb8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/web/src/components/ChatView.tsx Outdated
Comment on lines +3678 to +3680
if (timelineScrollModeRef.current !== "anchoring-new-turn") {
return;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Restore end-follow while an anchor remains

When a sent message remains as anchorMessageId, MessagesTimeline still passes maintainScrollAtEnd={false} whenever anchoredEndSpace is truthy, so this effect is the only fallback that keeps an at-end timeline pinned during later streaming/final timeline updates. If onIsAtEndChange flips timelineScrollModeRef back to following-end while that anchor is still present, this new guard skips the old scrollToEnd path and subsequent rows/size changes can stop following even though the user never manually navigated away.

Useful? React with 👍 / 👎.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 221222c. Configure here.

Comment thread apps/web/src/components/ChatView.tsx Outdated
@macroscopeapp

macroscopeapp Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR refactors the chat timeline scroll anchoring system, removing ~600 lines of custom logic in favor of library features. This constitutes a significant behavioral change to a core UX element. An unresolved review comment also flags a potential bug where scroll-following may stop working when an anchor is present.

You can customize Macroscope's approvability policy. Learn more.

@github-actions github-actions Bot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Aug 5, 2026
Keep maintainScrollAtEnd active alongside anchored end space so streaming updates follow the list threshold. Remove the manual navigation detection and scroll correction state that competed with the list.
@jmeistrich
jmeistrich force-pushed the fix/web-legend-list-3.3.3 branch from c446547 to 8cf8708 Compare August 5, 2026 21:52
@jmeistrich
jmeistrich marked this pull request as draft August 5, 2026 21:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant