feat(ui): add New Chat to History (#1124)
This commit is contained in:
4 files changed
+50
-1
No files matched your search
@@ -12,6 +12,10 @@ data class PendingChatNavigation(
|
||||
val requestId: Long,
|
||||
)
|
||||
|
||||
data class PendingNewChatNavigation(
|
||||
val requestId: Long,
|
||||
)
|
||||
|
||||
/**
|
||||
* Central navigation controller with deduplication guard.
|
||||
*
|
||||
@@ -27,9 +31,12 @@ object NavigationController {
|
||||
var backStack: NavBackStack<NavKey>? = null
|
||||
var pendingChatNavigation: PendingChatNavigation? by mutableStateOf(null)
|
||||
private set
|
||||
var pendingNewChatNavigation: PendingNewChatNavigation? by mutableStateOf(null)
|
||||
private set
|
||||
val pendingSessionId: String? get() = pendingChatNavigation?.sessionId
|
||||
|
||||
private var nextChatNavigationRequestId = 0L
|
||||
private var nextNewChatNavigationRequestId = 0L
|
||||
|
||||
/**
|
||||
* Top-level primary screens (all drawer-accessible screens).
|
||||
@@ -73,6 +80,14 @@ object NavigationController {
|
||||
queueChatNavigation(sessionId, scrollToBottom = true)
|
||||
}
|
||||
|
||||
fun openNewChat() {
|
||||
pendingNewChatNavigation =
|
||||
PendingNewChatNavigation(
|
||||
requestId = ++nextNewChatNavigationRequestId,
|
||||
)
|
||||
navigateTo(ChatScreen)
|
||||
}
|
||||
|
||||
private fun queueChatNavigation(
|
||||
sessionId: String,
|
||||
scrollToBottom: Boolean,
|
||||
@@ -90,6 +105,9 @@ object NavigationController {
|
||||
fun consumePendingChatNavigation(): PendingChatNavigation? =
|
||||
pendingChatNavigation.also { pendingChatNavigation = null }
|
||||
|
||||
fun consumePendingNewChatNavigation(): PendingNewChatNavigation? =
|
||||
pendingNewChatNavigation.also { pendingNewChatNavigation = null }
|
||||
|
||||
fun consumePendingSessionId(): String? = consumePendingChatNavigation()?.sessionId
|
||||
|
||||
/** Clear the stack and navigate to the given screen atomically. */
|
||||
|
||||
@@ -45,9 +45,15 @@ fun ChatLifecycleEffects(
|
||||
|
||||
// Switch to session from notification/history
|
||||
val pendingNavigation = NavigationController.pendingChatNavigation
|
||||
LaunchedEffect(sessionId, pendingNavigation, connectionStatus) {
|
||||
val pendingNewChatNavigation = NavigationController.pendingNewChatNavigation
|
||||
LaunchedEffect(sessionId, pendingNavigation, pendingNewChatNavigation, connectionStatus) {
|
||||
if (connectionStatus != ConnectionStatus.CONNECTED) return@LaunchedEffect
|
||||
val newChatRequest = NavigationController.consumePendingNewChatNavigation()
|
||||
val request = NavigationController.consumePendingChatNavigation()
|
||||
if (newChatRequest != null) {
|
||||
viewModel.createNewSession()
|
||||
return@LaunchedEffect
|
||||
}
|
||||
val target = request?.sessionId ?: sessionId
|
||||
if (!target.isNullOrBlank()) {
|
||||
viewModel.switchSession(target)
|
||||
|
||||
@@ -34,6 +34,7 @@ import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.CallSplit
|
||||
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
|
||||
import androidx.compose.material.icons.automirrored.filled.Send
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.CheckCircle
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material.icons.filled.Code
|
||||
@@ -466,6 +467,15 @@ fun SessionsScreen(
|
||||
isRefreshing = state.isLoading,
|
||||
onRefresh = { viewModel.loadSessions() },
|
||||
actions = {
|
||||
IconButton(
|
||||
onClick = { NavigationController.openNewChat() },
|
||||
modifier = Modifier.testTag("sessions_action_new_chat"),
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Add,
|
||||
contentDescription = stringResource(R.string.content_desc_new_chat),
|
||||
)
|
||||
}
|
||||
if (state.hasHiddenSessions) {
|
||||
IconButton(
|
||||
onClick = { viewModel.toggleShowHidden() },
|
||||
|
||||
Reference in new issue
Block a user