refactor(#78): extract UI strings for remaining batch 2.3 screens
This commit is contained in:
1 parent
b1950ece34
commit
44e2006434
9 files changed
+207
-65
No files matched your search
@@ -23,10 +23,12 @@ import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.m57.hermescontrol.R
|
||||
import com.m57.hermescontrol.ui.common.EmptyState
|
||||
import com.m57.hermescontrol.ui.common.ErrorState
|
||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||
@@ -45,7 +47,7 @@ fun AchievementsScreen(
|
||||
}
|
||||
|
||||
HermesScaffold(
|
||||
title = { Text("Agent Achievements") },
|
||||
title = { Text(stringResource(R.string.screen_achievements)) },
|
||||
onOpenDrawer = onOpenDrawer,
|
||||
isRefreshing = state.isLoading,
|
||||
onRefresh = { viewModel.loadAchievements() },
|
||||
@@ -65,8 +67,8 @@ fun AchievementsScreen(
|
||||
|
||||
state.achievements.isEmpty() -> {
|
||||
EmptyState(
|
||||
title = "No achievements yet",
|
||||
subtitle = "Complete tasks to unlock achievements.",
|
||||
title = stringResource(R.string.achievements_empty_title),
|
||||
subtitle = stringResource(R.string.achievements_empty_desc),
|
||||
icon = Icons.Filled.Refresh,
|
||||
modifier = Modifier.padding(paddingValues),
|
||||
)
|
||||
@@ -156,8 +158,11 @@ fun AchievementsScreen(
|
||||
) {
|
||||
Text(
|
||||
text =
|
||||
"Progress: ${achievement.progress?.toInt() ?: 0} / " +
|
||||
"${achievement.next_threshold?.toInt() ?: 0}",
|
||||
stringResource(
|
||||
R.string.achievements_label_progress,
|
||||
achievement.progress?.toInt() ?: 0,
|
||||
achievement.next_threshold?.toInt() ?: 0,
|
||||
),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
)
|
||||
Text(
|
||||
|
||||
@@ -29,9 +29,11 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.m57.hermescontrol.R
|
||||
import com.m57.hermescontrol.data.model.MessagingPlatformUpdate
|
||||
import com.m57.hermescontrol.ui.common.EmptyState
|
||||
import com.m57.hermescontrol.ui.common.ErrorState
|
||||
@@ -59,7 +61,7 @@ fun ChannelsScreen(
|
||||
}
|
||||
|
||||
HermesScaffold(
|
||||
title = { Text("Messaging Channels") },
|
||||
title = { Text(stringResource(R.string.screen_channels)) },
|
||||
onOpenDrawer = onOpenDrawer,
|
||||
isRefreshing = state.isLoading,
|
||||
onRefresh = { viewModel.loadPlatforms() },
|
||||
@@ -79,8 +81,8 @@ fun ChannelsScreen(
|
||||
|
||||
state.platforms.isEmpty() -> {
|
||||
EmptyState(
|
||||
title = "No channels configured",
|
||||
subtitle = "Add messaging platforms in Hermes to see them here.",
|
||||
title = stringResource(R.string.channels_empty_title),
|
||||
subtitle = stringResource(R.string.channels_empty_desc),
|
||||
modifier = Modifier.padding(paddingValues),
|
||||
)
|
||||
}
|
||||
@@ -104,7 +106,14 @@ fun ChannelsScreen(
|
||||
Column {
|
||||
Text(text = platform.name, style = MaterialTheme.typography.titleLarge)
|
||||
Text(
|
||||
text = if (platform.enabled) "Active" else "Disabled",
|
||||
text =
|
||||
if (platform.enabled) {
|
||||
stringResource(
|
||||
R.string.channels_status_active,
|
||||
)
|
||||
} else {
|
||||
stringResource(R.string.channels_status_disabled)
|
||||
},
|
||||
color =
|
||||
if (platform.enabled) {
|
||||
MaterialTheme.colorScheme.primary
|
||||
@@ -126,7 +135,15 @@ fun ChannelsScreen(
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Button(onClick = { showConfigureForm = !showConfigureForm }) {
|
||||
Text(if (showConfigureForm) "Cancel" else "Configure")
|
||||
Text(
|
||||
if (showConfigureForm) {
|
||||
stringResource(
|
||||
R.string.action_cancel,
|
||||
)
|
||||
} else {
|
||||
stringResource(R.string.channels_action_configure)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,7 +151,7 @@ fun ChannelsScreen(
|
||||
if (showConfigureForm) {
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Text(
|
||||
text = "Configuration Settings",
|
||||
text = stringResource(R.string.channels_sec_settings),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
)
|
||||
|
||||
@@ -148,7 +165,7 @@ fun ChannelsScreen(
|
||||
label = { Text(field.prompt ?: field.key) },
|
||||
placeholder = {
|
||||
if (field.isSet) {
|
||||
Text("******** (Already Configured)")
|
||||
Text(stringResource(R.string.channels_placeholder_configured))
|
||||
}
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
@@ -169,13 +186,16 @@ fun ChannelsScreen(
|
||||
},
|
||||
modifier = Modifier.align(Alignment.End),
|
||||
) {
|
||||
Text("Save Settings")
|
||||
Text(stringResource(R.string.channels_action_save_settings))
|
||||
}
|
||||
} else {
|
||||
val envFields = platform.envVars.orEmpty()
|
||||
if (envFields.isNotEmpty()) {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Text(text = "Configured Keys:", style = MaterialTheme.typography.titleSmall)
|
||||
Text(
|
||||
text = stringResource(R.string.channels_sec_keys),
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
)
|
||||
envFields.forEach { field ->
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
@@ -187,7 +207,14 @@ fun ChannelsScreen(
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
Text(
|
||||
text = if (field.isSet) "Configured" else "Not set",
|
||||
text =
|
||||
if (field.isSet) {
|
||||
stringResource(
|
||||
R.string.channels_status_configured,
|
||||
)
|
||||
} else {
|
||||
stringResource(R.string.channels_status_not_set)
|
||||
},
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color =
|
||||
if (field.isSet) {
|
||||
|
||||
@@ -24,9 +24,11 @@ import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.m57.hermescontrol.R
|
||||
import com.m57.hermescontrol.theme.LocalSpacing
|
||||
import com.m57.hermescontrol.ui.common.EmptyState
|
||||
import com.m57.hermescontrol.ui.common.ErrorState
|
||||
@@ -60,7 +62,7 @@ fun CronJobsScreen(
|
||||
}
|
||||
|
||||
HermesScaffold(
|
||||
title = { Text("Cron Jobs") },
|
||||
title = { Text(stringResource(R.string.screen_cron)) },
|
||||
onOpenDrawer = onOpenDrawer,
|
||||
isRefreshing = state.isLoading,
|
||||
onRefresh = { viewModel.loadCronJobs() },
|
||||
@@ -79,8 +81,8 @@ fun CronJobsScreen(
|
||||
|
||||
state.jobs.isEmpty() -> {
|
||||
EmptyState(
|
||||
title = "No cron jobs",
|
||||
subtitle = "Scheduled tasks from Hermes will appear here.",
|
||||
title = stringResource(R.string.cron_empty_title),
|
||||
subtitle = stringResource(R.string.cron_empty_desc),
|
||||
icon = Icons.Filled.Schedule,
|
||||
)
|
||||
}
|
||||
@@ -112,7 +114,14 @@ fun CronJobsScreen(
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
StatusBadge(
|
||||
text = if (job.state == "active") "Active" else "Paused",
|
||||
text =
|
||||
if (job.state == "active") {
|
||||
stringResource(
|
||||
R.string.cron_status_active,
|
||||
)
|
||||
} else {
|
||||
stringResource(R.string.cron_status_paused)
|
||||
},
|
||||
status =
|
||||
if (job.state == "active") {
|
||||
StatusBadgeType.SUCCESS
|
||||
@@ -143,21 +152,21 @@ fun CronJobsScreen(
|
||||
onClick = { viewModel.pauseCronJob(job.id) },
|
||||
modifier = Modifier.weight(1f),
|
||||
) {
|
||||
Text("Pause")
|
||||
Text(stringResource(R.string.cron_action_pause))
|
||||
}
|
||||
} else {
|
||||
OutlinedButton(
|
||||
onClick = { viewModel.resumeCronJob(job.id) },
|
||||
modifier = Modifier.weight(1f),
|
||||
) {
|
||||
Text("Resume")
|
||||
Text(stringResource(R.string.cron_action_resume))
|
||||
}
|
||||
}
|
||||
OutlinedButton(
|
||||
onClick = { viewModel.triggerCronJob(job.id) },
|
||||
modifier = Modifier.weight(1f),
|
||||
) {
|
||||
Text("Run")
|
||||
Text(stringResource(R.string.cron_action_run))
|
||||
}
|
||||
Button(
|
||||
onClick = { viewModel.deleteCronJob(job.id) },
|
||||
@@ -167,7 +176,7 @@ fun CronJobsScreen(
|
||||
),
|
||||
modifier = Modifier.weight(1f),
|
||||
) {
|
||||
Text("Delete")
|
||||
Text(stringResource(R.string.action_delete))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,10 +32,12 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.m57.hermescontrol.R
|
||||
import com.m57.hermescontrol.ui.common.ErrorState
|
||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||
import com.m57.hermescontrol.ui.common.LoadingState
|
||||
@@ -62,7 +64,7 @@ fun GatewayScreen(
|
||||
}
|
||||
|
||||
HermesScaffold(
|
||||
title = { Text("Gateway Control") },
|
||||
title = { Text(stringResource(R.string.screen_gateway)) },
|
||||
onOpenDrawer = onOpenDrawer,
|
||||
isRefreshing = state.isLoading,
|
||||
onRefresh = { viewModel.loadStatus() },
|
||||
@@ -96,7 +98,7 @@ fun GatewayScreen(
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Button(onClick = { viewModel.loadStatus() }) {
|
||||
Text("Retry")
|
||||
Text(stringResource(R.string.action_retry))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -132,7 +134,14 @@ fun GatewayScreen(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(
|
||||
text = if (isRunning) "GATEWAY RUNNING" else "GATEWAY STOPPED",
|
||||
text =
|
||||
if (isRunning) {
|
||||
stringResource(
|
||||
R.string.gateway_status_running,
|
||||
)
|
||||
} else {
|
||||
stringResource(R.string.gateway_status_stopped)
|
||||
},
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color =
|
||||
@@ -145,7 +154,7 @@ fun GatewayScreen(
|
||||
status?.version?.let {
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
Text(
|
||||
text = "Version: $it",
|
||||
text = stringResource(R.string.gateway_label_version, it),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color =
|
||||
if (isRunning) {
|
||||
@@ -170,7 +179,7 @@ fun GatewayScreen(
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
Text(
|
||||
text = "Controls",
|
||||
text = stringResource(R.string.gateway_sec_controls),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
)
|
||||
@@ -191,7 +200,7 @@ fun GatewayScreen(
|
||||
) {
|
||||
Icon(imageVector = Icons.Filled.PlayArrow, contentDescription = null)
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
Text("Start")
|
||||
Text(stringResource(R.string.gateway_action_start))
|
||||
}
|
||||
|
||||
Button(
|
||||
@@ -204,7 +213,7 @@ fun GatewayScreen(
|
||||
contentColor = Color.White,
|
||||
),
|
||||
) {
|
||||
Text("Stop")
|
||||
Text(stringResource(R.string.gateway_action_stop))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,7 +228,7 @@ fun GatewayScreen(
|
||||
) {
|
||||
Icon(imageVector = Icons.Filled.Refresh, contentDescription = null)
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
Text("Restart")
|
||||
Text(stringResource(R.string.gateway_action_restart))
|
||||
}
|
||||
|
||||
if (state.isActionRunning) {
|
||||
@@ -245,7 +254,7 @@ fun GatewayScreen(
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
Text(
|
||||
text = "Active Platforms",
|
||||
text = stringResource(R.string.gateway_sec_active_platforms),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
)
|
||||
|
||||
@@ -36,10 +36,12 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.m57.hermescontrol.R
|
||||
import com.m57.hermescontrol.ui.common.EmptyState
|
||||
import com.m57.hermescontrol.ui.common.ErrorState
|
||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||
@@ -67,7 +69,7 @@ fun KeysScreen(
|
||||
}
|
||||
|
||||
HermesScaffold(
|
||||
title = { Text("Keys & Credentials") },
|
||||
title = { Text(stringResource(R.string.screen_keys)) },
|
||||
onOpenDrawer = onOpenDrawer,
|
||||
isRefreshing = state.isLoading,
|
||||
onRefresh = { viewModel.loadKeys() },
|
||||
@@ -87,10 +89,10 @@ fun KeysScreen(
|
||||
|
||||
state.envVars.isEmpty() -> {
|
||||
EmptyState(
|
||||
title = "No environment keys reported",
|
||||
subtitle = "Verify configuration or retry",
|
||||
title = stringResource(R.string.keys_empty_title),
|
||||
subtitle = stringResource(R.string.toolsets_empty_desc),
|
||||
onAction = { viewModel.loadKeys() },
|
||||
actionLabel = "Refresh",
|
||||
actionLabel = stringResource(R.string.content_desc_refresh),
|
||||
modifier = Modifier.padding(paddingValues),
|
||||
)
|
||||
}
|
||||
@@ -123,7 +125,7 @@ fun KeysScreen(
|
||||
} else if (config.isSet) {
|
||||
config.redactedValue ?: "********"
|
||||
} else {
|
||||
"Not configured"
|
||||
stringResource(R.string.keys_label_not_configured)
|
||||
}
|
||||
|
||||
Card(modifier = Modifier.fillMaxWidth()) {
|
||||
@@ -158,13 +160,13 @@ fun KeysScreen(
|
||||
viewModel.updateKey(key, editedValue)
|
||||
isEditing = false
|
||||
}) {
|
||||
Text("Save")
|
||||
Text(stringResource(R.string.action_save))
|
||||
}
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Button(onClick = {
|
||||
isEditing = false
|
||||
}) {
|
||||
Text("Cancel")
|
||||
Text(stringResource(R.string.action_cancel))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -196,7 +198,10 @@ fun KeysScreen(
|
||||
} else {
|
||||
Icons.Filled.Visibility
|
||||
},
|
||||
contentDescription = "Toggle Visibility",
|
||||
contentDescription =
|
||||
stringResource(
|
||||
R.string.keys_action_toggle_visibility,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -206,7 +211,10 @@ fun KeysScreen(
|
||||
}) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Edit,
|
||||
contentDescription = "Edit",
|
||||
contentDescription =
|
||||
stringResource(
|
||||
R.string.nav_drawer_section_converse,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,11 +28,13 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.m57.hermescontrol.R
|
||||
import com.m57.hermescontrol.ui.common.ErrorState
|
||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||
import com.m57.hermescontrol.ui.common.LoadingState
|
||||
@@ -59,7 +61,7 @@ fun McpServersScreen(
|
||||
}
|
||||
|
||||
HermesScaffold(
|
||||
title = { Text("MCP Servers") },
|
||||
title = { Text(stringResource(R.string.screen_mcp_servers)) },
|
||||
onOpenDrawer = onOpenDrawer,
|
||||
isRefreshing = state.isLoading,
|
||||
onRefresh = { viewModel.loadServers() },
|
||||
@@ -89,7 +91,7 @@ fun McpServersScreen(
|
||||
Text(text = state.errorMessage ?: "", color = MaterialTheme.colorScheme.error)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Button(onClick = { viewModel.loadServers() }) {
|
||||
Text("Retry")
|
||||
Text(stringResource(R.string.action_retry))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -129,7 +131,11 @@ fun McpServersScreen(
|
||||
fontWeight = FontWeight.Bold,
|
||||
)
|
||||
Text(
|
||||
text = "Transport: ${server.transport ?: "stdio"}",
|
||||
text =
|
||||
stringResource(
|
||||
R.string.mcp_servers_label_transport,
|
||||
server.transport ?: "stdio",
|
||||
),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -145,7 +151,7 @@ fun McpServersScreen(
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
val fullCmd = "${server.command} ${server.args.orEmpty().joinToString(" ")}"
|
||||
Text(
|
||||
text = "Command:",
|
||||
text = stringResource(R.string.mcp_servers_label_command),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
fontWeight = FontWeight.Bold,
|
||||
)
|
||||
@@ -168,13 +174,13 @@ fun McpServersScreen(
|
||||
onClick = { viewModel.testServer(server.name) },
|
||||
modifier = Modifier.padding(end = 8.dp),
|
||||
) {
|
||||
Text("Test")
|
||||
Text(stringResource(R.string.mcp_servers_action_test))
|
||||
}
|
||||
|
||||
OutlinedButton(
|
||||
onClick = { viewModel.deleteServer(server.name) },
|
||||
) {
|
||||
Text("Delete")
|
||||
Text(stringResource(R.string.action_delete))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,9 +28,11 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.m57.hermescontrol.R
|
||||
import com.m57.hermescontrol.ui.common.EmptyState
|
||||
import com.m57.hermescontrol.ui.common.ErrorState
|
||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||
@@ -58,7 +60,7 @@ fun PluginsScreen(
|
||||
}
|
||||
|
||||
HermesScaffold(
|
||||
title = { Text("Plugins") },
|
||||
title = { Text(stringResource(R.string.screen_plugins)) },
|
||||
onOpenDrawer = onOpenDrawer,
|
||||
isRefreshing = state.isLoading,
|
||||
onRefresh = { viewModel.loadPlugins() },
|
||||
@@ -78,10 +80,10 @@ fun PluginsScreen(
|
||||
|
||||
state.plugins.isEmpty() -> {
|
||||
EmptyState(
|
||||
title = "No plugins found",
|
||||
subtitle = "Verify configuration or retry",
|
||||
title = stringResource(R.string.plugins_empty_title),
|
||||
subtitle = stringResource(R.string.plugins_empty_desc),
|
||||
onAction = { viewModel.loadPlugins() },
|
||||
actionLabel = "Refresh",
|
||||
actionLabel = stringResource(R.string.content_desc_refresh),
|
||||
modifier = Modifier.padding(paddingValues),
|
||||
)
|
||||
}
|
||||
@@ -129,7 +131,7 @@ fun PluginsScreen(
|
||||
}
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
Text(
|
||||
text = plugin.description ?: "No description provided.",
|
||||
text = plugin.description ?: stringResource(R.string.plugins_no_desc),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
@@ -139,7 +141,7 @@ fun PluginsScreen(
|
||||
) {
|
||||
if (plugin.installed) {
|
||||
OutlinedButton(onClick = { viewModel.updatePlugin(plugin.name) }) {
|
||||
Text("Update")
|
||||
Text(stringResource(R.string.plugins_action_update))
|
||||
}
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
OutlinedButton(
|
||||
@@ -149,11 +151,11 @@ fun PluginsScreen(
|
||||
contentColor = MaterialTheme.colorScheme.error,
|
||||
),
|
||||
) {
|
||||
Text("Uninstall")
|
||||
Text(stringResource(R.string.plugins_action_uninstall))
|
||||
}
|
||||
} else {
|
||||
Button(onClick = { viewModel.installPlugin(plugin.name) }) {
|
||||
Text("Install")
|
||||
Text(stringResource(R.string.plugins_action_install))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,10 +35,12 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.m57.hermescontrol.R
|
||||
import com.m57.hermescontrol.ui.common.EmptyState
|
||||
import com.m57.hermescontrol.ui.common.ErrorState
|
||||
import com.m57.hermescontrol.ui.common.HermesScaffold
|
||||
@@ -71,7 +73,7 @@ fun ProfilesScreen(
|
||||
}
|
||||
|
||||
HermesScaffold(
|
||||
title = { Text("Profiles") },
|
||||
title = { Text(stringResource(R.string.screen_profiles)) },
|
||||
onOpenDrawer = onOpenDrawer,
|
||||
isRefreshing = state.isLoading,
|
||||
onRefresh = { viewModel.loadProfiles() },
|
||||
@@ -91,10 +93,10 @@ fun ProfilesScreen(
|
||||
|
||||
state.profiles.isEmpty() -> {
|
||||
EmptyState(
|
||||
title = "No profiles available",
|
||||
subtitle = "Verify configuration or retry",
|
||||
title = stringResource(R.string.profiles_empty_title),
|
||||
subtitle = stringResource(R.string.toolsets_empty_desc),
|
||||
onAction = { viewModel.loadProfiles() },
|
||||
actionLabel = "Refresh",
|
||||
actionLabel = stringResource(R.string.content_desc_refresh),
|
||||
modifier = Modifier.padding(paddingValues),
|
||||
)
|
||||
}
|
||||
@@ -111,7 +113,7 @@ fun ProfilesScreen(
|
||||
Text(text = state.errorMessage ?: "", color = MaterialTheme.colorScheme.error)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Button(onClick = { viewModel.loadProfiles() }) {
|
||||
Text("Retry")
|
||||
Text(stringResource(R.string.action_retry))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -170,7 +172,10 @@ fun ProfilesScreen(
|
||||
if (isActive) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Check,
|
||||
contentDescription = "Active Profile",
|
||||
contentDescription =
|
||||
stringResource(
|
||||
R.string.profiles_content_desc_active,
|
||||
),
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.padding(start = 8.dp),
|
||||
)
|
||||
@@ -186,11 +191,19 @@ fun ProfilesScreen(
|
||||
) {
|
||||
Column {
|
||||
Text(
|
||||
text = "Model: ${profile.model ?: "None"}",
|
||||
text =
|
||||
stringResource(
|
||||
R.string.profiles_label_model,
|
||||
profile.model ?: "None",
|
||||
),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
Text(
|
||||
text = "Provider: ${profile.provider ?: "None"}",
|
||||
text =
|
||||
stringResource(
|
||||
R.string.profiles_label_provider,
|
||||
profile.provider ?: "None",
|
||||
),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
@@ -216,7 +229,7 @@ fun ProfilesScreen(
|
||||
modifier = Modifier.width(16.dp),
|
||||
)
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
Text("Edit Soul")
|
||||
Text(stringResource(R.string.profiles_action_edit_soul))
|
||||
}
|
||||
|
||||
Button(
|
||||
@@ -226,7 +239,7 @@ fun ProfilesScreen(
|
||||
tempModelName = profile.model ?: ""
|
||||
},
|
||||
) {
|
||||
Text("Set Model")
|
||||
Text(stringResource(R.string.profiles_action_set_model))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user