mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
refactor(android): distill companion shell cleanup
This commit is contained in:
@@ -793,10 +793,8 @@ private fun ChatShellScreen(
|
||||
) {
|
||||
ChatScreen(
|
||||
viewModel = viewModel,
|
||||
onBack = {},
|
||||
onVoice = onVoice,
|
||||
onOpenSessions = onOpenSessions,
|
||||
showBackButton = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.automirrored.filled.Send
|
||||
import androidx.compose.material.icons.filled.AttachFile
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
@@ -80,10 +79,8 @@ import java.util.Locale
|
||||
@Composable
|
||||
fun ChatScreen(
|
||||
viewModel: MainViewModel,
|
||||
onBack: () -> Unit,
|
||||
onVoice: () -> Unit,
|
||||
onOpenSessions: (() -> Unit)? = null,
|
||||
showBackButton: Boolean = true,
|
||||
onOpenSessions: () -> Unit,
|
||||
) {
|
||||
val messages by viewModel.chatMessages.collectAsState()
|
||||
val historyLoading by viewModel.chatHistoryLoading.collectAsState()
|
||||
@@ -162,12 +159,10 @@ fun ChatScreen(
|
||||
thinkingLevel = thinkingLevel,
|
||||
healthOk = healthOk,
|
||||
pendingRunCount = pendingRunCount,
|
||||
onBack = onBack,
|
||||
onMore = {
|
||||
viewModel.refreshChat()
|
||||
viewModel.refreshChatSessions(limit = 100)
|
||||
},
|
||||
showBackButton = showBackButton,
|
||||
)
|
||||
|
||||
ChatSessionSwitcher(
|
||||
@@ -236,7 +231,7 @@ private fun ChatSessionSwitcher(
|
||||
sessions: List<ChatSessionEntry>,
|
||||
mainSessionKey: String,
|
||||
onSelectSession: (String) -> Unit,
|
||||
onOpenSessions: (() -> Unit)?,
|
||||
onOpenSessions: () -> Unit,
|
||||
) {
|
||||
val choices =
|
||||
remember(sessionKey, sessions, mainSessionKey) {
|
||||
@@ -260,7 +255,7 @@ private fun ChatSessionSwitcher(
|
||||
onClick = { onSelectSession(entry.key) },
|
||||
)
|
||||
}
|
||||
if (onOpenSessions != null && sessions.size > choices.size) {
|
||||
if (sessions.size > choices.size) {
|
||||
Surface(
|
||||
onClick = onOpenSessions,
|
||||
modifier = Modifier.heightIn(min = 36.dp),
|
||||
@@ -312,20 +307,14 @@ private fun ChatHeader(
|
||||
thinkingLevel: String,
|
||||
healthOk: Boolean,
|
||||
pendingRunCount: Int,
|
||||
onBack: () -> Unit,
|
||||
onMore: () -> Unit,
|
||||
showBackButton: Boolean,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(6.dp),
|
||||
) {
|
||||
if (showBackButton) {
|
||||
HeaderIcon(icon = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back", onClick = onBack)
|
||||
} else {
|
||||
Box(modifier = Modifier.size(ClawTheme.spacing.touchTarget))
|
||||
}
|
||||
Box(modifier = Modifier.size(ClawTheme.spacing.touchTarget))
|
||||
|
||||
Column(
|
||||
modifier = Modifier.weight(1f),
|
||||
|
||||
@@ -4,22 +4,9 @@ import ai.openclaw.app.chat.ChatSessionEntry
|
||||
|
||||
private const val RECENT_WINDOW_MS = 24 * 60 * 60 * 1000L
|
||||
|
||||
/**
|
||||
* Derive a human-friendly label from a raw session key.
|
||||
* Examples:
|
||||
* "telegram:g-agent-main-main" -> "Main"
|
||||
* "agent:main:main" -> "Main"
|
||||
* "discord:g-server-channel" -> "Server Channel"
|
||||
* "my-custom-session" -> "My Custom Session"
|
||||
*/
|
||||
fun friendlySessionName(key: String): String {
|
||||
// Strip common prefixes like "telegram:", "agent:", "discord:" etc.
|
||||
val stripped = key.substringAfterLast(":")
|
||||
|
||||
// Remove leading "g-" prefix (gateway artifact)
|
||||
val cleaned = if (stripped.startsWith("g-")) stripped.removePrefix("g-") else stripped
|
||||
|
||||
// Split on hyphens/underscores, title-case each word, collapse "main main" -> "Main"
|
||||
val words =
|
||||
cleaned
|
||||
.split('-', '_')
|
||||
@@ -79,7 +66,6 @@ fun resolveSessionChoices(
|
||||
return result
|
||||
}
|
||||
|
||||
/** Builds the compact top-of-chat session switcher without dropping main or the active session. */
|
||||
fun resolveCompactSessionChoices(
|
||||
currentSessionKey: String,
|
||||
sessions: List<ChatSessionEntry>,
|
||||
@@ -94,24 +80,14 @@ fun resolveCompactSessionChoices(
|
||||
mainSessionKey = mainSessionKey,
|
||||
nowMs = nowMs,
|
||||
)
|
||||
if (allChoices.size <= maxOptions) return allChoices
|
||||
|
||||
val mainKey = mainSessionKey.trim().ifEmpty { "main" }
|
||||
val current = currentSessionKey.trim().let { if (it == "main" && mainKey != "main") mainKey else it }
|
||||
val pinnedKeys = listOf(mainKey, current).filter { it.isNotBlank() }
|
||||
val result = mutableListOf<ChatSessionEntry>()
|
||||
val seen = mutableSetOf<String>()
|
||||
val pinnedRank = listOf(mainKey, current).filter { it.isNotBlank() }.distinct().withIndex().associate { it.value to it.index }
|
||||
val unpinnedRank = pinnedRank.size
|
||||
|
||||
pinnedKeys.forEach { key ->
|
||||
allChoices.firstOrNull { it.key == key }?.let { entry ->
|
||||
if (seen.add(entry.key)) result.add(entry)
|
||||
}
|
||||
}
|
||||
|
||||
allChoices.forEach { entry ->
|
||||
if (result.size >= maxOptions) return@forEach
|
||||
if (seen.add(entry.key)) result.add(entry)
|
||||
}
|
||||
|
||||
return result
|
||||
return allChoices
|
||||
.withIndex()
|
||||
.sortedWith(compareBy({ pinnedRank[it.value.key] ?: unpinnedRank }, { it.index }))
|
||||
.take(maxOptions)
|
||||
.map { it.value }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user