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