From e1bb993b09beb5eb3b172ba3b8b949e10f94067a Mon Sep 17 00:00:00 2001 From: "844143714@qq,com" <844143714@qq,com> Date: Tue, 19 May 2026 21:22:59 +0800 Subject: [PATCH] feat(chat): implement ChatArea Compose UI component --- .../standapp/ui/chat/components/ChatArea.kt | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 app/src/main/java/com/stand/standapp/ui/chat/components/ChatArea.kt diff --git a/app/src/main/java/com/stand/standapp/ui/chat/components/ChatArea.kt b/app/src/main/java/com/stand/standapp/ui/chat/components/ChatArea.kt new file mode 100644 index 0000000..9ac9402 --- /dev/null +++ b/app/src/main/java/com/stand/standapp/ui/chat/components/ChatArea.kt @@ -0,0 +1,101 @@ +package com.stand.standapp.ui.chat.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Menu +import androidx.compose.material.icons.filled.Send +import androidx.compose.material3.* +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import com.stand.standapp.ui.chat.model.ChatMessage + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun ChatArea( + messages: List, + onSendMessage: (String) -> Unit, + onOpenDrawer: () -> Unit, + onClose: () -> Unit +) { + var inputText by remember { mutableStateOf("") } + + Column(modifier = Modifier.fillMaxSize().background(Color.White)) { + // 顶部栏 + TopAppBar( + title = { Text("AI 助手", style = MaterialTheme.typography.titleMedium) }, + navigationIcon = { + IconButton(onClick = onOpenDrawer) { + Icon(Icons.Default.Menu, contentDescription = "Menu") + } + }, + actions = { + TextButton(onClick = onClose) { Text("关闭") } + }, + colors = TopAppBarDefaults.topAppBarColors(containerColor = Color(0xFFF3F4F6)) + ) + + // 消息列表 + LazyColumn( + modifier = Modifier.weight(1f).fillMaxWidth().padding(horizontal = 12.dp), + contentPadding = PaddingValues(vertical = 12.dp), + verticalArrangement = Arrangement.spacedBy(8.dp) + ) { + items(messages) { msg -> + val isUser = msg.role == ChatMessage.Role.USER + Box( + modifier = Modifier.fillMaxWidth(), + contentAlignment = if (isUser) Alignment.CenterEnd else Alignment.CenterStart + ) { + Surface( + shape = RoundedCornerShape(12.dp), + color = if (isUser) Color(0xFF10B981) else Color(0xFFE5E7EB), + contentColor = if (isUser) Color.White else Color.Black + ) { + Text( + text = msg.content + if (msg.isStreaming) " █" else "", + modifier = Modifier.padding(12.dp), + style = MaterialTheme.typography.bodyMedium + ) + } + } + } + } + + // 输入区 + Row( + modifier = Modifier + .fillMaxWidth() + .padding(8.dp) + .navigationBarsPadding() // 处理底部内边距 + .imePadding(), // 键盘避让 + verticalAlignment = Alignment.CenterVertically + ) { + OutlinedTextField( + value = inputText, + onValueChange = { inputText = it }, + modifier = Modifier.weight(1f), + placeholder = { Text("输入你想问的问题...") }, + shape = RoundedCornerShape(20.dp) + ) + Spacer(modifier = Modifier.width(8.dp)) + IconButton( + onClick = { + if (inputText.isNotBlank()) { + onSendMessage(inputText) + inputText = "" + } + }, + modifier = Modifier.background(Color(0xFF10B981), RoundedCornerShape(50)) + ) { + Icon(Icons.Default.Send, contentDescription = "Send", tint = Color.White) + } + } + } +}