refactor: 优化前端聊天UI组件

- 优化MessageBubble消息气泡组件
- 优化MessageList消息列表组件
This commit is contained in:
iammm0
2026-01-26 11:54:11 +08:00
parent 06a616bc83
commit a18bb83c5e
2 changed files with 85 additions and 9 deletions

View File

@@ -8,6 +8,11 @@ import androidx.compose.material3.CardDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.shadow
@@ -38,14 +43,14 @@ fun UserMessageBubble(
.shadow(2.dp, RoundedCornerShape(12.dp)),
shape = RoundedCornerShape(12.dp),
colors = CardDefaults.cardColors(
containerColor = LightPurple.copy(alpha = 0.2f)
containerColor = LightPurple // 使用完整的紫色,不再使用透明度
)
) {
Text(
text = text,
modifier = Modifier.padding(12.dp),
fontSize = 14.sp,
color = MaterialTheme.colorScheme.onSurface,
color = Color.White, // 使用白色文字,确保在紫色背景上清晰可见
lineHeight = 20.sp
)
}
@@ -87,3 +92,65 @@ fun AIMessageBubble(
}
}
}
/**
* 流式AI消息气泡带光标闪烁效果
*/
@Composable
fun StreamingAIMessageBubble(
text: String,
modifier: Modifier = Modifier
) {
var showCursor by remember { mutableStateOf(true) }
// 光标闪烁动画
LaunchedEffect(Unit) {
while (true) {
showCursor = true
kotlinx.coroutines.delay(500)
showCursor = false
kotlinx.coroutines.delay(500)
}
}
Row(
modifier = modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp),
horizontalArrangement = androidx.compose.foundation.layout.Arrangement.Start
) {
Card(
modifier = Modifier
.weight(1f)
.shadow(2.dp, RoundedCornerShape(12.dp)),
shape = RoundedCornerShape(12.dp),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surface
)
) {
Row(
modifier = Modifier.padding(12.dp),
verticalAlignment = androidx.compose.ui.Alignment.CenterVertically
) {
Text(
text = text,
fontSize = 14.sp,
color = MaterialTheme.colorScheme.onSurface,
lineHeight = 20.sp
)
// 光标闪烁效果
if (showCursor) {
Text(
text = "",
fontSize = 14.sp,
color = MaterialTheme.colorScheme.primary,
fontWeight = FontWeight.Bold,
modifier = Modifier.padding(start = 2.dp)
)
} else {
Spacer(modifier = Modifier.width(8.dp))
}
}
}
}
}

View File

@@ -20,6 +20,7 @@ import androidx.compose.ui.unit.sp
import com.huaga.life_echo.network.models.MessageDto
import com.huaga.life_echo.ui.theme.LightPurple
import com.huaga.life_echo.utils.TimeUtils
import kotlinx.coroutines.delay
/**
* 消息列表组件
@@ -35,10 +36,18 @@ fun MessageList(
) {
val listState = rememberLazyListState()
// 自动滚动到底部
LaunchedEffect(messages.size, isStreaming) {
if (messages.isNotEmpty() || isStreaming) {
listState.animateScrollToItem(messages.size)
// 自动滚动到底部 - 改进:流式输出时实时滚动
LaunchedEffect(messages.size, isStreaming, streamingText) {
val targetIndex = messages.size + if (isStreaming) 1 else 0
if (targetIndex > 0) {
// 流式输出时使用平滑滚动,其他情况使用动画滚动
if (isStreaming && streamingText.isNotEmpty()) {
// 流式输出时,每次文本更新都滚动到底部
kotlinx.coroutines.delay(50) // 短暂延迟确保内容已渲染
listState.animateScrollToItem(targetIndex)
} else {
listState.animateScrollToItem(targetIndex)
}
}
}
@@ -78,10 +87,10 @@ fun MessageList(
lastDate = currentDate
}
// 流式消息显示
// 流式消息显示 - 使用专门的流式消息气泡组件
if (isStreaming) {
item {
AIMessageBubble(
item(key = "streaming_message") {
StreamingAIMessageBubble(
text = streamingText
)
}