• Mohamed Aziz Mejri's avatar
    Fixing scrolling behavior in the chat panel (#2040) · d91f9953
    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 -->
    d91f9953
名称
最后提交
最后更新
..
__tests__ 正在载入提交数据...
app 正在载入提交数据...
atoms 正在载入提交数据...
client_logic 正在载入提交数据...
components 正在载入提交数据...
constants 正在载入提交数据...
contexts 正在载入提交数据...
db 正在载入提交数据...
hooks 正在载入提交数据...
ipc 正在载入提交数据...
lib 正在载入提交数据...
main 正在载入提交数据...
neon_admin 正在载入提交数据...
pages 正在载入提交数据...
paths 正在载入提交数据...
pro 正在载入提交数据...
prompts 正在载入提交数据...
routes 正在载入提交数据...
shared 正在载入提交数据...
store 正在载入提交数据...
styles 正在载入提交数据...
supabase_admin 正在载入提交数据...
utils 正在载入提交数据...
backup_manager.ts 正在载入提交数据...
main.ts 正在载入提交数据...
preload.ts 正在载入提交数据...
renderer.tsx 正在载入提交数据...
router.ts 正在载入提交数据...