feat: auto-scroll chat on new messages
Scroll to bottom when sending a message, and conditionally scroll on received messages when the user is already near the latest messages. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d18b7c8a24
commit
96f559abbb
2 changed files with 22 additions and 0 deletions
|
|
@ -8,8 +8,10 @@ import io.picoclaw.android.core.domain.usecase.LoadMoreMessagesUseCase
|
|||
import io.picoclaw.android.core.domain.usecase.ObserveConnectionUseCase
|
||||
import io.picoclaw.android.core.domain.usecase.ObserveMessagesUseCase
|
||||
import io.picoclaw.android.core.domain.usecase.SendMessageUseCase
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asSharedFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -26,6 +28,9 @@ class ChatViewModel(
|
|||
private val _uiState = MutableStateFlow(ChatUiState())
|
||||
val uiState: StateFlow<ChatUiState> = _uiState.asStateFlow()
|
||||
|
||||
private val _scrollToBottom = MutableSharedFlow<Unit>(extraBufferCapacity = 1)
|
||||
val scrollToBottom = _scrollToBottom.asSharedFlow()
|
||||
|
||||
init {
|
||||
connectChat()
|
||||
|
||||
|
|
@ -51,6 +56,7 @@ class ChatViewModel(
|
|||
val state = _uiState.value
|
||||
val text = state.inputText.trim()
|
||||
if (text.isEmpty() && state.pendingImages.isEmpty()) return
|
||||
_scrollToBottom.tryEmit(Unit)
|
||||
_uiState.update { it.copy(inputText = "", pendingImages = emptyList()) }
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -99,6 +99,22 @@ fun ChatScreen(
|
|||
if (shouldLoadMore) viewModel.onEvent(ChatEvent.OnLoadMore)
|
||||
}
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.scrollToBottom.collect {
|
||||
listState.animateScrollToItem(0)
|
||||
}
|
||||
}
|
||||
|
||||
val isNearBottom by remember {
|
||||
derivedStateOf { listState.firstVisibleItemIndex <= 3 }
|
||||
}
|
||||
|
||||
LaunchedEffect(uiState.messages.size) {
|
||||
if (isNearBottom) {
|
||||
listState.animateScrollToItem(0)
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(title = { Text("PicoClaw") })
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue