-
由 Mohamed Aziz Mejri 提交于
closes #2038 #2055 <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Fixes chat panel scrolling (issue #2038). Auto-scroll only runs while streaming and when you’re near the bottom, and a “scroll to bottom” button appears when you scroll away. - **Bug Fixes** - Use Virtuoso scrollerRef and a conditional followOutput to control auto-scroll based on streaming state and distance from bottom. - Track distance and user scrolling to show/hide the button; clean up listeners on unmount. - Add overflow-y-auto to the messages list and a test-mode fallback that uses the container’s scroll events. <sup>Written for commit 2307453c7f1ad721d6eca9cfc5a9a24224f5da26. Summary will update on new commits.</sup> <!-- End of auto-generated description by cubic. --> <!-- greptile_comment --> <h3>Greptile Summary</h3> Replaced custom scroll tracking logic with Virtuoso's native scroll state management to fix the issue where users couldn't scroll up during streaming. **Key Changes:** - Removed manual scroll event listeners, timeout refs, and distance calculations from `ChatPanel.tsx` - Delegated scroll state to Virtuoso's `atBottomStateChange` callback which detects when user is within 150px of bottom - Converted `followOutput` from always `"smooth"` to a function that returns `"smooth"` only when `isStreaming && isAtBottom`, otherwise returns `false` to prevent forced scrolling - This allows users to scroll up and read earlier messages while the AI generates a response, restoring the behavior that existed before PR #1993 <h3>Confidence Score: 5/5</h3> - This PR is safe to merge with minimal risk - The changes are well-architected and leverage Virtuoso's built-in functionality instead of reinventing scroll tracking logic. The fix directly addresses the reported issue by making `followOutput` conditional on user position, which is the correct approach for this library. - No files require special attention <h3>Important Files Changed</h3> | Filename | Overview | |----------|----------| | src/components/ChatPanel.tsx | Refactored scroll handling to delegate to Virtuoso's native `atBottomStateChange`, removed custom scroll tracking logic and manual scroll event listeners | | src/components/chat/MessagesList.tsx | Added `atBottomStateChange` and conditional `followOutput` to Virtuoso, allowing users to scroll up while streaming without forced auto-scroll | </details> <h3>Sequence Diagram</h3> ```mermaid sequenceDiagram participant User participant ChatPanel participant MessagesList participant Virtuoso Note over User,Virtuoso: Streaming Scenario User->>MessagesList: Scrolls to read earlier messages Virtuoso->>Virtuoso: Detects scroll position > 150px from bottom Virtuoso->>MessagesList: atBottomStateChange(false) MessagesList->>ChatPanel: onScrollStateChange(false) ChatPanel->>ChatPanel: setShowScrollButton(true) Note over Virtuoso: New message chunk arrives Virtuoso->>Virtuoso: followOutput((isAtBottom) => isAtBottom && isStreaming ? "smooth" : false) Virtuoso->>Virtuoso: Returns false (user scrolled away) Virtuoso->>Virtuoso: Does NOT auto-scroll Note over User,Virtuoso: User Returns to Bottom User->>ChatPanel: Clicks scroll-to-bottom button ChatPanel->>MessagesList: scrollToBottom("smooth") MessagesList->>Virtuoso: scrollIntoView on messagesEndRef Virtuoso->>Virtuoso: Scrolls to bottom Virtuoso->>MessagesList: atBottomStateChange(true) MessagesList->>ChatPanel: onScrollStateChange(true) ChatPanel->>ChatPanel: setShowScrollButton(false) Note over Virtuoso: Subsequent message chunks Virtuoso->>Virtuoso: followOutput returns "smooth" (isAtBottom = true) Virtuoso->>Virtuoso: Auto-scrolls smoothly ``` <!-- greptile_other_comments_section --> <!-- /greptile_comment --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Improves chat scrolling reliability across production (Virtuoso) and test modes. > > - Integrates `MessagesList` with Virtuoso `scrollerRef` and conditional `followOutput` (auto-scroll only when `isStreaming` and within ~280px of bottom), with proper listener cleanup > - Centralizes scroll tracking in `ChatPanel` using `distanceFromBottomRef` and a timeout to debounce user scrolling; toggles a "scroll to bottom" button when scrolled away > - Adds test-mode behavior: non-virtualized rendering, container scroll listeners, and manual auto-scroll near bottom > - Ensures smooth scroll-to-bottom after streaming completes; applies `overflow-y-auto` and passes new props (`onScrollerRef`, `distanceFromBottomRef`, `isUserScrolling`) between components > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 2307453c7f1ad721d6eca9cfc5a9a24224f5da26. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->