This commit is contained in:
2026-07-20 17:01:19 +08:00
parent 83c031930b
commit 9e0eddaf4a
3 changed files with 21 additions and 7 deletions
+1
View File
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
@@ -418,9 +418,16 @@ private fun MessagesArea(
}.collect { nearBottom -> autoScroll = nearBottom }
}
// Instant scroll (not animated) so it doesn't fight with user drag gestures
LaunchedEffect(state.streamContent, state.streamReasoning, messages.size, state.isStreaming) {
if (autoScroll && totalItems > 0) {
listState.animateScrollToItem(totalItems - 1)
if (state.streamContent.isNotBlank()) {
// Content phase: scroll to bottom of the streaming message
listState.scrollToItem(totalItems - 1, 100000)
} else {
// Reasoning phase: keep streaming message header visible
listState.scrollToItem(totalItems - 1)
}
}
}
@@ -484,7 +491,7 @@ private fun MessagesArea(
.border(1.dp, c.border, CircleShape)
.clickable {
autoScroll = true
scope.launch { listState.animateScrollToItem(totalItems - 1) }
scope.launch { listState.animateScrollToItem(totalItems - 1, 100000) }
},
contentAlignment = Alignment.Center,
) {
@@ -633,6 +640,13 @@ private fun StreamingMessage(content: String, reasoning: String, onCopy: () -> U
private fun ReasoningCard(reasoning: String, isStreaming: Boolean) {
val c = LocalAppColors.current
var collapsed by remember { mutableStateOf(false) }
val scrollState = rememberScrollState()
// Auto-scroll reasoning text to bottom as new content arrives
LaunchedEffect(reasoning) {
if (isStreaming && !collapsed) {
scrollState.animateScrollTo(scrollState.maxValue)
}
}
Column(
modifier = Modifier
.fillMaxWidth()
@@ -663,7 +677,7 @@ private fun ReasoningCard(reasoning: String, isStreaming: Boolean) {
modifier = Modifier
.fillMaxWidth()
.heightIn(max = 320.dp)
.verticalScroll(rememberScrollState())
.verticalScroll(scrollState)
.padding(horizontal = 12.dp, vertical = 8.dp)
) {
SelectionContainer {
@@ -763,15 +777,14 @@ private fun ComposerBar(state: ChatUiState, onSend: (String) -> Unit, onStop: ()
Box(
modifier = Modifier
.size(44.dp)
.clip(RoundedCornerShape(12.dp))
.shadow(6.dp, RoundedCornerShape(12.dp), clip = true)
.background(c.accentBrush)
.shadow(6.dp, RoundedCornerShape(12.dp), clip = false)
.clickable(enabled = input.isNotBlank()) {
onSend(input); input = ""
},
contentAlignment = Alignment.Center,
) {
Icon(Icons.AutoMirrored.Filled.Send, contentDescription = "发送", tint = Color.White)
Icon(Icons.AutoMirrored.Filled.Send, contentDescription = "发送", tint = Color.White, modifier = Modifier.size(22.dp))
}
}
}