refactor(#78): extract UI strings for chat, settings, connect, kanban, and skills screens

This commit is contained in:
Hy4ri committed 2026-06-21 11:38:33 +03:00
1 parent acd6cbf751
commit cdad31b555
9 files changed
+348 -149

No files matched your search

@@ -54,6 +54,7 @@ import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
@@ -64,6 +65,7 @@ import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.m57.hermescontrol.R
import com.m57.hermescontrol.theme.AssistantBubble
import com.m57.hermescontrol.theme.AssistantBubbleLight
import com.m57.hermescontrol.theme.StatusGreen
@@ -232,7 +234,7 @@ private fun UserBubble(
) {
Icon(
Icons.Filled.ContentCopy,
contentDescription = "Copy",
contentDescription = stringResource(R.string.content_desc_copy),
modifier = Modifier.size(16.dp),
tint = MaterialTheme.colorScheme.onSurface,
)
@@ -347,7 +349,7 @@ private fun AssistantBubble(
) {
Icon(
Icons.Filled.ContentCopy,
contentDescription = "Copy",
contentDescription = stringResource(R.string.content_desc_copy),
modifier = Modifier.size(16.dp),
tint = MaterialTheme.colorScheme.onSurface,
)
@@ -489,7 +491,7 @@ private fun ParsedToolContent(
}
parsed.stderr?.let {
Text(
text = "Error Output (stderr):\n$it",
text = stringResource(R.string.chat_tool_stderr, it),
style =
MaterialTheme.typography.bodySmall.copy(
color = StatusRed.copy(alpha = 0.9f),
@@ -500,7 +502,7 @@ private fun ParsedToolContent(
}
parsed.error?.let {
Text(
text = "Execution Error: $it",
text = stringResource(R.string.chat_tool_execution_error, it),
style =
MaterialTheme.typography.bodySmall.copy(
color = StatusRed,
@@ -513,7 +515,7 @@ private fun ParsedToolContent(
parsed.exitCode?.let { code ->
if (code != 0) {
Text(
text = "Exit Code: $code",
text = stringResource(R.string.chat_tool_exit_code, code),
style =
MaterialTheme.typography.labelSmall.copy(
color = StatusRed,
@@ -619,7 +621,7 @@ private fun ToolBubble(
}
Text(
text = message.toolName ?: "Tool",
text = message.toolName ?: stringResource(R.string.chat_tool_fallback),
style =
MaterialTheme.typography.labelMedium.copy(
color = contentColor,
@@ -635,7 +637,7 @@ private fun ToolBubble(
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "Show Raw JSON",
text = stringResource(R.string.chat_tool_show_raw),
style =
MaterialTheme.typography.labelSmall.copy(
color = MaterialTheme.colorScheme.primary,
@@ -660,7 +662,7 @@ private fun ToolBubble(
if (parsedOutput != null) {
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "Show Parsed Output",
text = stringResource(R.string.chat_tool_show_parsed),
style =
MaterialTheme.typography.labelSmall.copy(
color = MaterialTheme.colorScheme.primary,
@@ -293,14 +293,20 @@ fun ChatScreen(
imageVector =
if (state.isSearchActive) Icons.Filled.Close else Icons.Filled.Search,
contentDescription =
if (state.isSearchActive) "Close search" else "Search",
if (state.isSearchActive) {
stringResource(
R.string.chat_action_close_search,
)
} else {
stringResource(R.string.chat_action_search)
},
)
}
IconButton(onClick = { viewModel.createNewSession() }) {
Icon(
imageVector = Icons.Filled.Add,
contentDescription = "New Chat",
contentDescription = stringResource(R.string.content_desc_new_chat),
)
}
},
@@ -335,9 +341,9 @@ fun ChatScreen(
Text(
text =
if (state.connectionStatus == ConnectionStatus.RECONNECTING) {
"Reconnecting to Hermes…"
stringResource(R.string.chat_status_reconnecting)
} else {
"Disconnected from Hermes"
stringResource(R.string.chat_status_disconnected)
},
style = MaterialTheme.typography.bodyMedium,
)
@@ -349,7 +355,7 @@ fun ChatScreen(
contentColor = MaterialTheme.colorScheme.onErrorContainer,
),
) {
Text("Reconnect")
Text(stringResource(R.string.chat_action_reconnect))
}
}
}
@@ -393,8 +399,8 @@ fun ChatScreen(
) {
if (state.messages.isEmpty() && !state.isLoading) {
EmptyState(
title = "Ready to chat",
subtitle = "Send a message to start a conversation",
title = stringResource(R.string.chat_empty_title),
subtitle = stringResource(R.string.chat_empty_subtitle),
)
}
@@ -482,7 +488,7 @@ fun ChatScreen(
)
Spacer(modifier = Modifier.height(16.dp))
Text(
text = "Connecting to Hermes…",
text = stringResource(R.string.chat_status_connecting),
style = MaterialTheme.typography.bodyMedium,
)
}
@@ -512,7 +518,7 @@ fun ChatScreen(
) {
Icon(
imageVector = Icons.Filled.KeyboardArrowDown,
contentDescription = "Scroll to bottom",
contentDescription = stringResource(R.string.content_desc_scroll_to_bottom),
)
}
}
@@ -584,9 +590,9 @@ private fun ThinkingIndicator(thinkingText: String) {
text =
if (thinkingText.isNotBlank()) {
val display = thinkingText.takeLast(100)
"Thinking: $display…"
stringResource(R.string.chat_thinking_param, display)
} else {
"Thinking…"
stringResource(R.string.chat_thinking)
},
style =
MaterialTheme.typography.bodySmall.copy(
@@ -671,14 +677,14 @@ private fun ChatInputBar(
items(filteredCommands) { cmd ->
val description =
when (cmd) {
"/help" -> "Show help menu"
"/status" -> "Check gateway and platform status"
"/sessions" -> "List all chat sessions"
"/stats" -> "Check system resource usage (stats)"
"/system" -> "Check system resource usage (system)"
"/new" -> "Create a new chat session"
"/stop" -> "Interrupt the active run"
"/interrupt" -> "Interrupt the active run"
"/help" -> stringResource(R.string.command_help_desc)
"/status" -> stringResource(R.string.command_status_desc)
"/sessions" -> stringResource(R.string.command_sessions_desc)
"/stats" -> stringResource(R.string.command_stats_desc)
"/system" -> stringResource(R.string.command_system_desc)
"/new" -> stringResource(R.string.command_new_desc)
"/stop" -> stringResource(R.string.command_stop_desc)
"/interrupt" -> stringResource(R.string.command_stop_desc)
else -> ""
}
DropdownMenuItem(
@@ -725,11 +731,11 @@ private fun ChatInputBar(
placeholder = {
Text(
if (!isConnected) {
"Not connected…"
stringResource(R.string.chat_input_placeholder_not_connected)
} else if (isAgentTyping) {
"Waiting for response…"
stringResource(R.string.chat_input_placeholder_waiting)
} else {
"Type a message…"
stringResource(R.string.chat_input_placeholder_type_message)
},
)
},
@@ -759,7 +765,7 @@ private fun ChatInputBar(
) {
Icon(
imageVector = Icons.Filled.Stop,
contentDescription = "Interrupt",
contentDescription = stringResource(R.string.content_desc_interrupt),
tint = MaterialTheme.colorScheme.error,
)
}