refactor(web): the timeline minimap lives in its own file#22662
MessagesTimeline.tsx is ~5,800 lines. It holds the list, scroll machinery and every row renderer, which makes it hard to read and review. This stack splits it into focused files without changing behavior.
This layer moves the timeline minimap (TimelineMinimap, its navigation button and the pointer-release helper) into TimelineMinimap.tsx.
| File | Before | After |
|---|---|---|
| MessagesTimeline.tsx | 5,772 | 5,441 |
| TimelineMinimap.tsx | – | 335 |
Measurements
Dev app on a seeded copy of real data, median of 3, React renders counted by the commit-root counter (only fibers React actually rendered). "Before" is main at 6a6c84f990; "after" is the top of this stack. Nested update peak comes from a probe in react-dom's getRootForUpdatedFiber.
| Interaction | Before: commits / renders / timeline renders / nested peak | After |
|---|---|---|
| Scroll an 8.5k-item thread up 40 × 150px | 43 / 1,656 / 70 / 0 | 44 / 1,670 / 70 / 0 |
| Load earlier turns, then scroll up 60 × 300px | 107 / 5,316 / 356 / 0 | 104 / 5,275 / 356 / 0 |
| Agent streams a 20-line reply (561-item thread) | 63 / 3,092 / 164 / 1 | 55 / 2,728 / 139 / 0 |
The extractions keep every component, context, and hook boundary unchanged, so render counts match within run-to-run noise. Streaming numbers vary with reply length. The win is readability: each row family is now a file you can read on its own, and the React Compiler caches each one independently. The legend-list wiring is unchanged. That covers getItemType with its length buckets (#21269), TimelineRowCtx inside renderItem with extraData carrying sharedState (#21123), and scroll restore. No update loops appeared while loading earlier turns.
Tests
vp test runMessagesTimeline logic, active-tools, and browser tests, plustimelineScrollAnchoringreactCompilerCoveragefor every touched and new file (0 bailouts)tsc-rs --noEmitfor apps/web,vp linton changed files
🤖 Generated with Claude Code
Checks
- SuccessfulCodeRabbitGitHub
Review completed
- Successful
Skipped - Not affected
- Skipped
- Skipped
- Skipped
- SuccessfulRemove preview downloadGitHub
- SuccessfulLabel PR 22662GitHub
- Skipped
- SuccessfulLabel PR sizeGitHub
- Successful
- Successful
- Successful
- SuccessfulCollect PR targetsGitHub
- SuccessfulPrepare PR size configGitHub
- SuccessfulNative fingerprint diffGitHub
- SuccessfulCheckGitHub
- SkippedRelease SmokeGitHub
- SkippedRustGitHub
- Skipped
- SuccessfulBuild and TypecheckGitHub
- SuccessfulTestGitHub
- SuccessfulTest WebGitHub
- SuccessfulLabel PR 22662GitHub
- Skipped
- SuccessfulLabel PR sizeGitHub
- SuccessfulPrepare PR size configGitHub
- SuccessfulCollect PR targetsGitHub
- SkippedEAS PreviewGitHub
- SuccessfulNative fingerprint diffGitHub
- SuccessfulLintGitHub
- SuccessfulTest Server 7GitHub
- SuccessfulTest Server 3GitHub
- SuccessfulTest Server 5GitHub
- SuccessfulTest Server 8GitHub
- SuccessfulTest Server 1GitHub
- SuccessfulTest Server 4GitHub
- SuccessfulTest Server 2GitHub
- SuccessfulTest Server 6GitHub
- SuccessfulChangesGitHub
Added 1 commit
- refactor(web): the timeline minimap lives in its own file60e3181
Approvability
Verdict: Approved at 60e3181
Macroscope's review found this PR approvable — This PR extracts the existing timeline minimap into its own file without changing its props, rendering logic, event handling, or parent wiring. The runtime effect is limited to reorganizing production UI code across a module boundary.
You can add or adjust custom eligibility rules. Learn more.
No actionable comments were generated in the recent review. 🎉
ℹ️ Recent review info
⚙️ Run configuration
- Configuration used: Path: .coderabbit.config.ts
- Review profile: CHILL
- Plan: Team
- Run ID:
a287d102-6479-463c-9be6-9ea012e43e82
📥 Commits
Reviewing files that changed from the base of the PR and between 6a6c84f9906cbdfa7f533fecfc39ce18c2f4c273 and 60e318155ef80a03a4d28cb4857a994e755d829f.
📒 Files selected for processing: 2
apps/web/src/components/chat/MessagesTimeline.tsxapps/web/src/components/chat/TimelineMinimap.tsx
Limit details: You’ve used all 10 included reviews currently available.
📝 Walkthrough
The minimap implementation moved from
MessagesTimeline.tsxintoTimelineMinimap.tsx.MessagesTimeline.tsximports the component and retains the minimap item derivation and integration.Changes: Timeline minimap
Layer / File(s) Summary Minimap behavior and rendering
apps/web/src/components/chat/TimelineMinimap.tsxThe new component implements minimap state, pointer and keyboard navigation, previous/next controls, timeline strips, and hover previews. Timeline component integration
apps/web/src/components/chat/MessagesTimeline.tsxThe timeline imports the new component and retains the minimap utilities used by the container. The inline minimap implementation and unused imports were removed. Priority: ⬇️ Low
Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Refactor
Suggested reviewers:
t3dotgg
Merge Risk: ⚪ Minimal · up to 60e31
This is a behavior-preserving file extraction with no identified defects. It looks safe to merge after the normal checks.
Pre-merge checks: Passed 3 · Failed 1
Failed Failed checks: 1 warning
Check name Status Explanation Resolution Description check Warning The description explains the extraction, scope, performance measurements, and validation. It does not use the required section headings and omits the required Scope and approval information. It also o… Reformat the description with Problem, Change, Scope and approval, and Verification sections. Add the triaged issue or explicit maintainer approval, explain why the change is within scope, and include before-and-after screenshots. State any… Passed Passed checks: 3 passed
Check name Status Explanation Title check Passed The title clearly describes the primary change: moving the timeline minimap into its own file. Linked Issues check Passed Check skipped because no linked issues were found for this pull request. Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check
Explanation
The description explains the extraction, scope, performance measurements, and validation. It does not use the required section headings and omits the required Scope and approval information. It also omits before-and-after screenshots for this UI change.
Resolution
Reformat the description with Problem, Change, Scope and approval, and Verification sections. Add the triaged issue or explicit maintainer approval, explain why the change is within scope, and include before-and-after screenshots. State any verification that could not be completed.
✨ Finishing Touches
📝 Generate docstrings
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
- Commit to this branch
- Create a new PR
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Usage-based review receipt
- Mode: Continue automatically
- Reviewed files: 2
- Charged: $0.50
- View usage details
Note
This review was completed with usage-based billing: files reviewed beyond your plan's included limits are billed at $0.25/file. View usage-based billing.
Comment @coderabbitai help to get the list of available commands.