mirror of https://github.com/openclaw/openclaw.git
fix(android): reduce chat recomposition churn
This commit is contained in:
parent
3009e689bc
commit
56e23a887f
|
|
@ -6,12 +6,14 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
|
@ -34,11 +36,19 @@ fun ChatMessageListCard(
|
|||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val listState = rememberLazyListState()
|
||||
val displayMessages = remember(messages) { messages.asReversed() }
|
||||
val stream = streamingAssistantText?.trim()
|
||||
|
||||
// With reverseLayout the newest item is at index 0 (bottom of screen).
|
||||
LaunchedEffect(messages.size, pendingRunCount, pendingToolCalls.size, streamingAssistantText) {
|
||||
// New list items/tool rows should animate into view, but token streaming should not restart
|
||||
// that animation on every delta.
|
||||
LaunchedEffect(messages.size, pendingRunCount, pendingToolCalls.size) {
|
||||
listState.animateScrollToItem(index = 0)
|
||||
}
|
||||
LaunchedEffect(stream) {
|
||||
if (!stream.isNullOrEmpty()) {
|
||||
listState.scrollToItem(index = 0)
|
||||
}
|
||||
}
|
||||
|
||||
Box(modifier = modifier.fillMaxWidth()) {
|
||||
LazyColumn(
|
||||
|
|
@ -50,8 +60,6 @@ fun ChatMessageListCard(
|
|||
) {
|
||||
// With reverseLayout = true, index 0 renders at the BOTTOM.
|
||||
// So we emit newest items first: streaming → tools → typing → messages (newest→oldest).
|
||||
|
||||
val stream = streamingAssistantText?.trim()
|
||||
if (!stream.isNullOrEmpty()) {
|
||||
item(key = "stream") {
|
||||
ChatStreamingAssistantBubble(text = stream)
|
||||
|
|
@ -70,8 +78,8 @@ fun ChatMessageListCard(
|
|||
}
|
||||
}
|
||||
|
||||
items(count = messages.size, key = { idx -> messages[messages.size - 1 - idx].id }) { idx ->
|
||||
ChatMessageBubble(message = messages[messages.size - 1 - idx])
|
||||
items(items = displayMessages, key = { it.id }) { message ->
|
||||
ChatMessageBubble(message = message)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -160,7 +160,10 @@ private fun ChatThreadSelector(
|
|||
mainSessionKey: String,
|
||||
onSelectSession: (String) -> Unit,
|
||||
) {
|
||||
val sessionOptions = resolveSessionChoices(sessionKey, sessions, mainSessionKey = mainSessionKey)
|
||||
val sessionOptions =
|
||||
remember(sessionKey, sessions, mainSessionKey) {
|
||||
resolveSessionChoices(sessionKey, sessions, mainSessionKey = mainSessionKey)
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().horizontalScroll(rememberScrollState()),
|
||||
|
|
|
|||
Loading…
Reference in New Issue