feat(chat): implement ChatArea Compose UI component
This commit is contained in:
parent
62ef1e2c38
commit
e1bb993b09
|
|
@ -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<ChatMessage>,
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue