feat(chat): implement ChatScaffold container with sidebar drawer
This commit is contained in:
parent
e1bb993b09
commit
21750acd2c
|
|
@ -0,0 +1,86 @@
|
||||||
|
package com.stand.standapp.ui.chat.components
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
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.Add
|
||||||
|
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 androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
|
import com.stand.standapp.ui.chat.ChatViewModel
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ChatScaffold(
|
||||||
|
viewModel: ChatViewModel = viewModel(),
|
||||||
|
onClose: () -> Unit
|
||||||
|
) {
|
||||||
|
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
val sessions by viewModel.sessions.collectAsState()
|
||||||
|
val currentSessionId by viewModel.currentSessionId.collectAsState()
|
||||||
|
val messages by viewModel.messages.collectAsState()
|
||||||
|
|
||||||
|
// 筛选当前会话的消息
|
||||||
|
val currentMessages = messages.filter { it.sessionId == currentSessionId }
|
||||||
|
|
||||||
|
ModalNavigationDrawer(
|
||||||
|
drawerState = drawerState,
|
||||||
|
drawerContent = {
|
||||||
|
ModalDrawerSheet(modifier = Modifier.fillMaxWidth(0.7f)) { // 抽屉宽度为 70%
|
||||||
|
Column(Modifier.fillMaxSize().padding(16.dp)) {
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
viewModel.createNewSession()
|
||||||
|
scope.launch { drawerState.close() }
|
||||||
|
},
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Icon(Icons.Default.Add, contentDescription = null)
|
||||||
|
Spacer(Modifier.width(8.dp))
|
||||||
|
Text("新建话题")
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(Modifier.height(16.dp))
|
||||||
|
|
||||||
|
LazyColumn {
|
||||||
|
items(sessions) { session ->
|
||||||
|
val isSelected = session.id == currentSessionId
|
||||||
|
Surface(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 4.dp)
|
||||||
|
.clickable {
|
||||||
|
viewModel.switchSession(session.id)
|
||||||
|
scope.launch { drawerState.close() }
|
||||||
|
},
|
||||||
|
color = if (isSelected) Color(0xFFE5E7EB) else Color.Transparent,
|
||||||
|
shape = RoundedCornerShape(8.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = session.title,
|
||||||
|
modifier = Modifier.padding(12.dp),
|
||||||
|
maxLines = 1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
ChatArea(
|
||||||
|
messages = currentMessages,
|
||||||
|
onSendMessage = { viewModel.sendMessage(it) },
|
||||||
|
onOpenDrawer = { scope.launch { drawerState.open() } },
|
||||||
|
onClose = onClose
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue