Chat Flicker Scroll Snap - #524
Conversation
The latest updates on your projects. Learn more about Vercel for GitHub. |
📝 WalkthroughWalkthroughThis PR improves chat rendering during streaming and snapshot recovery by introducing dual-threshold scroll stickiness with explicit user-gesture release, and updating snapshot merging to preserve object identity for deduplicated events. ChangesChat Streaming and Snapshot Recovery
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
arul28
commented
Jun 3, 2026
@copilot review but do not make fixes |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Summary
Describe the change.
What Changed
Key files and behaviors.
Validation
How you tested.
Risks
Anything to watch.
Summary by CodeRabbit
Greptile Summary
This PR improves the auto-scroll experience in the chat view by detecting user scroll intent (wheel and touch events) before new streaming content arrives and triggers an auto-snap. It also refines
mergeChatHistorySnapshotto preserve object identity for unchanged events, enabling React to skip unnecessary re-renders.handleWheelandhandleTouchMovecallreleaseBottomStickinessForUserScrollbefore the RAF-based auto-scroll fires, so upward gestures during streaming reliably break free.shouldStickToBottomAfterScrollintroduces hysteresis: re-sticking only happens when the user returns to within 24 px of the bottom.mergeChatHistorySnapshotnow builds a key→entry map overexistingand substitutes matching parsed entries with their original object references, short-circuiting to return the same array when nothing changed.Confidence Score: 4/5
Safe to merge with the pinch-to-zoom guard applied; without it, zooming in during streaming silently disables auto-scroll for the rest of the session.
The wheel handler releases auto-scroll stickiness on any negative deltaY without checking ctrlKey. Trackpad pinch-to-zoom delivers exactly those events (negative deltaY, ctrlKey true) but does not move scrollTop, so handleScroll never fires to re-engage stickiness — leaving auto-scroll permanently disabled for the conversation. Everything else in the PR (touch handling, hysteresis logic, history merge) looks correct and is well-covered by tests.
apps/desktop/src/renderer/components/chat/AgentChatMessageList.tsx — specifically the handleWheel callback
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[User wheel / touch event] --> B{Event type} B -->|onWheel deltaY < 0| C{ctrlKey?} C -->|No - scroll up| D[releaseBottomStickinessForUserScroll] C -->|Yes - pinch-to-zoom| E[⚠ Bug: also releases stickiness] B -->|onTouchMove nextY - prevY > 2px| D D --> F[stickToBottomRef = false\ncancel RAF] F --> G[Streaming content grows\nResizeObserver fires] G --> H{stickToBottomRef?} H -->|true| I[scrollToBottomSoon RAF] H -->|false| J[No auto-scroll ✓] K[onScroll] --> L[shouldStickToBottomAfterScroll] L --> M{wasStuckToBottom?} M -->|true| N[stick if dist < 160 px] M -->|false| O[stick if dist ≤ 24 px]Prompt To Fix All With AI
Reviews (2): Last reviewed commit: "Address chat scroll review note" | Re-trigger Greptile