refactor: 优化前端聊天UI组件
- 优化MessageBubble消息气泡组件 - 优化MessageList消息列表组件
This commit is contained in:
@@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user