Implement Auto-Scroll During Chat Streaming #87

Closed
opened 2025-09-15 13:32:23 +00:00 by rwachters · 0 comments
rwachters commented 2025-09-15 13:32:23 +00:00 (Migrated from github.com)

Feature Requirement

While streaming a message and the scroll position is at the bottom, keep it at the bottom when new content is added.

Current Architecture

The chat streaming system is already well-established:

  • Server Side: MessageServiceImpl.processNewMessageStreaming() emits streaming events
  • Client Side: DefaultSessionRepository.applyStreamEvent() updates cached session data
  • UI Layer: MessageList component displays messages in a LazyColumn

Implementation Strategy

1. Scroll Position Detection

Add logic to MessageList.kt to detect when user is at the bottom:

val isAtBottom by remember {
    derivedStateOf {
        val layoutInfo = lazyListState.layoutInfo
        val lastVisibleItem = layoutInfo.visibleItemsInfo.lastOrNull()
        lastVisibleItem?.index == layoutInfo.totalItemsCount - 1 &&
        lastVisibleItem.offset + lastVisibleItem.size <= layoutInfo.viewportEndOffset
    }
}

2. Auto-Scroll During Streaming

Add effect to scroll to bottom when new content is added and user was at bottom:

LaunchedEffect(displayedMessages.size, displayedMessages.lastOrNull()?.content) {
    if (isAtBottom) {
        lazyListState.animateScrollToItem(displayedMessages.size - 1)
    }
}

Required Changes

Files to Modify:

  1. app/src/commonMain/kotlin/eu/torvian/chatbot/app/compose/chatarea/MessageList.kt

    • Add scroll position detection logic
    • Add auto-scroll effect based on message changes
  2. app/src/commonMain/kotlin/eu/torvian/chatbot/app/compose/chatarea/ChatAreaState.kt

    • Add isStreaming: Boolean property
  3. app/src/commonMain/kotlin/eu/torvian/chatbot/app/viewmodel/chat/state/ChatState.kt & ChatStateImpl.kt

    • Add streaming state tracking
    • Expose streaming state through StateFlow
  4. app/src/commonMain/kotlin/eu/torvian/chatbot/app/viewmodel/chat/usecase/SendMessageUseCase.kt

    • Update streaming state during message processing

Technical Considerations

Performance

  • Delta Updates: Content changes frequently during streaming
  • Scroll Throttling: May need to throttle scroll operations
  • Recomposition: Ensure scroll detection doesn't cause unnecessary recompositions

User Experience

  • Manual Override: If user scrolls up during streaming, respect their choice
  • Smooth Animations: Use animateScrollToItem() for better UX
  • Platform Compatibility: Ensure works across Desktop/Android/Web

Implementation Priority

  1. High: Basic auto-scroll when at bottom during streaming
  2. Medium: Smooth animations and performance optimization
  3. Low: Advanced UX features like scroll indicators

Testing Strategy

  • Unit tests for scroll position detection logic
  • Integration tests for streaming + scroll behavior
  • Manual testing across platforms
  • Edge case testing (rapid streaming, long messages, user interruption)

Current Status

Architecture analysis complete. Ready for implementation.

# Feature Requirement While streaming a message and the scroll position is at the bottom, keep it at the bottom when new content is added. ## Current Architecture The chat streaming system is already well-established: - **Server Side**: `MessageServiceImpl.processNewMessageStreaming()` emits streaming events - **Client Side**: `DefaultSessionRepository.applyStreamEvent()` updates cached session data - **UI Layer**: `MessageList` component displays messages in a `LazyColumn` ## Implementation Strategy ### 1. Scroll Position Detection Add logic to `MessageList.kt` to detect when user is at the bottom: ```kotlin val isAtBottom by remember { derivedStateOf { val layoutInfo = lazyListState.layoutInfo val lastVisibleItem = layoutInfo.visibleItemsInfo.lastOrNull() lastVisibleItem?.index == layoutInfo.totalItemsCount - 1 && lastVisibleItem.offset + lastVisibleItem.size <= layoutInfo.viewportEndOffset } } ``` ### 2. Auto-Scroll During Streaming Add effect to scroll to bottom when new content is added and user was at bottom: ```kotlin LaunchedEffect(displayedMessages.size, displayedMessages.lastOrNull()?.content) { if (isAtBottom) { lazyListState.animateScrollToItem(displayedMessages.size - 1) } } ``` ## Required Changes ### Files to Modify: 1. `app/src/commonMain/kotlin/eu/torvian/chatbot/app/compose/chatarea/MessageList.kt` - Add scroll position detection logic - Add auto-scroll effect based on message changes 2. `app/src/commonMain/kotlin/eu/torvian/chatbot/app/compose/chatarea/ChatAreaState.kt` - Add `isStreaming: Boolean` property 3. `app/src/commonMain/kotlin/eu/torvian/chatbot/app/viewmodel/chat/state/ChatState.kt` & `ChatStateImpl.kt` - Add streaming state tracking - Expose streaming state through StateFlow 4. `app/src/commonMain/kotlin/eu/torvian/chatbot/app/viewmodel/chat/usecase/SendMessageUseCase.kt` - Update streaming state during message processing ## Technical Considerations ### Performance - **Delta Updates**: Content changes frequently during streaming - **Scroll Throttling**: May need to throttle scroll operations - **Recomposition**: Ensure scroll detection doesn't cause unnecessary recompositions ### User Experience - **Manual Override**: If user scrolls up during streaming, respect their choice - **Smooth Animations**: Use `animateScrollToItem()` for better UX - **Platform Compatibility**: Ensure works across Desktop/Android/Web ## Implementation Priority 1. **High**: Basic auto-scroll when at bottom during streaming 2. **Medium**: Smooth animations and performance optimization 3. **Low**: Advanced UX features like scroll indicators ## Testing Strategy - Unit tests for scroll position detection logic - Integration tests for streaming + scroll behavior - Manual testing across platforms - Edge case testing (rapid streaming, long messages, user interruption) ## Current Status Architecture analysis complete. Ready for implementation.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Torvian.eu/chatbot#87
No description provided.