feat(#11): make HermesScaffold title a @Composable slot, convert ChatScreen (#12)

- HermesScaffold: title now @Composable () -> Unit (M3-idiomatic)
- HermesScaffold: added modifier and snackbarHost parameters
- Updated all 18 callers from title="X" to title={Text("X")}
- ChatScreen: converted from raw Scaffold to HermesScaffold
- Removed unused Menu icon import (ktlint fix)
This commit is contained in:
M57 authored and GitHub committed 2026-06-18 18:43:45 +03:00
1 parent 7c27ca624c
commit d37de1d223
20 files changed
+37 -57

No files matched your search

@@ -45,7 +45,7 @@ fun AchievementsScreen(
} }
HermesScaffold( HermesScaffold(
title = "Agent Achievements", title = { Text("Agent Achievements") },
onOpenDrawer = onOpenDrawer, onOpenDrawer = onOpenDrawer,
onRefresh = { viewModel.loadAchievements() }, onRefresh = { viewModel.loadAchievements() },
) { paddingValues -> ) { paddingValues ->
@@ -59,7 +59,7 @@ fun ChannelsScreen(
} }
HermesScaffold( HermesScaffold(
title = "Messaging Channels", title = { Text("Messaging Channels") },
onOpenDrawer = onOpenDrawer, onOpenDrawer = onOpenDrawer,
onRefresh = { viewModel.loadPlatforms() }, onRefresh = { viewModel.loadPlatforms() },
) { paddingValues -> ) { paddingValues ->
@@ -40,7 +40,6 @@ import androidx.compose.material.icons.automirrored.filled.Send
import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.ArrowDropDown import androidx.compose.material.icons.filled.ArrowDropDown
import androidx.compose.material.icons.filled.History import androidx.compose.material.icons.filled.History
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material.icons.filled.Settings import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.filled.Stop import androidx.compose.material.icons.filled.Stop
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
@@ -49,7 +48,6 @@ import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FilledTonalButton import androidx.compose.material3.FilledTonalButton
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
@@ -57,14 +55,11 @@ import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.OutlinedTextFieldDefaults import androidx.compose.material3.OutlinedTextFieldDefaults
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Snackbar import androidx.compose.material3.Snackbar
import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
@@ -88,8 +83,8 @@ import com.m57.hermescontrol.notification.NotificationHelper
import com.m57.hermescontrol.theme.StatusGreen import com.m57.hermescontrol.theme.StatusGreen
import com.m57.hermescontrol.theme.StatusRed import com.m57.hermescontrol.theme.StatusRed
import com.m57.hermescontrol.ui.common.EmptyState import com.m57.hermescontrol.ui.common.EmptyState
import com.m57.hermescontrol.ui.common.HermesScaffold
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun ChatScreen( fun ChatScreen(
onNavigateToSettings: () -> Unit, onNavigateToSettings: () -> Unit,
@@ -165,20 +160,8 @@ fun ChatScreen(
), ),
) )
Scaffold( HermesScaffold(
modifier = modifier.fillMaxSize(), modifier = modifier,
topBar = {
TopAppBar(
navigationIcon = {
if (onOpenDrawer != null) {
IconButton(onClick = onOpenDrawer) {
Icon(
imageVector = androidx.compose.material.icons.Icons.Filled.Menu,
contentDescription = "Open Drawer",
)
}
}
},
title = { title = {
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
Text( Text(
@@ -199,6 +182,16 @@ fun ChatScreen(
) )
} }
}, },
onOpenDrawer = onOpenDrawer,
snackbarHost = {
SnackbarHost(snackbarHostState) { data ->
Snackbar(
snackbarData = data,
containerColor = MaterialTheme.colorScheme.errorContainer,
contentColor = MaterialTheme.colorScheme.onErrorContainer,
)
}
},
actions = { actions = {
IconButton(onClick = { viewModel.createNewSession() }) { IconButton(onClick = { viewModel.createNewSession() }) {
Icon( Icon(
@@ -285,21 +278,6 @@ fun ChatScreen(
) )
} }
}, },
colors =
TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.surface,
),
)
},
snackbarHost = {
SnackbarHost(snackbarHostState) { data ->
Snackbar(
snackbarData = data,
containerColor = MaterialTheme.colorScheme.errorContainer,
contentColor = MaterialTheme.colorScheme.onErrorContainer,
)
}
},
) { paddingValues -> ) { paddingValues ->
Column( Column(
modifier = modifier =
@@ -13,7 +13,6 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@@ -35,21 +34,24 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun HermesScaffold( fun HermesScaffold(
title: String, modifier: Modifier = Modifier,
title: @Composable () -> Unit,
onOpenDrawer: (() -> Unit)? = null, onOpenDrawer: (() -> Unit)? = null,
onRefresh: (() -> Unit)? = null, onRefresh: (() -> Unit)? = null,
onBack: (() -> Unit)? = null, onBack: (() -> Unit)? = null,
showBack: Boolean = false, showBack: Boolean = false,
snackbarHost: @Composable () -> Unit = {},
actions: @Composable () -> Unit = {}, actions: @Composable () -> Unit = {},
content: @Composable (PaddingValues) -> Unit, content: @Composable (PaddingValues) -> Unit,
) { ) {
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
Scaffold( Scaffold(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
snackbarHost = { snackbarHost() },
topBar = { topBar = {
TopAppBar( TopAppBar(
title = { Text(title) }, title = title,
navigationIcon = { navigationIcon = {
when { when {
showBack && onBack != null -> { showBack && onBack != null -> {
@@ -57,7 +57,7 @@ fun ConfigScreen(
} }
HermesScaffold( HermesScaffold(
title = "Configuration", title = { Text("Configuration") },
onOpenDrawer = onOpenDrawer, onOpenDrawer = onOpenDrawer,
onRefresh = { viewModel.loadRawConfig() }, onRefresh = { viewModel.loadRawConfig() },
) { paddingValues -> ) { paddingValues ->
@@ -59,7 +59,7 @@ fun CronJobsScreen(
} }
HermesScaffold( HermesScaffold(
title = "Cron Jobs", title = { Text("Cron Jobs") },
onOpenDrawer = onOpenDrawer, onOpenDrawer = onOpenDrawer,
onRefresh = { viewModel.loadCronJobs() }, onRefresh = { viewModel.loadCronJobs() },
) { ) {
@@ -62,7 +62,7 @@ fun GatewayScreen(
} }
HermesScaffold( HermesScaffold(
title = "Gateway Control", title = { Text("Gateway Control") },
onOpenDrawer = onOpenDrawer, onOpenDrawer = onOpenDrawer,
onRefresh = { viewModel.loadStatus() }, onRefresh = { viewModel.loadStatus() },
) { paddingValues -> ) { paddingValues ->
@@ -71,7 +71,7 @@ fun KanbanScreen(
} }
HermesScaffold( HermesScaffold(
title = "Kanban Board", title = { Text("Kanban Board") },
onOpenDrawer = onOpenDrawer, onOpenDrawer = onOpenDrawer,
onRefresh = { viewModel.loadBoards() }, onRefresh = { viewModel.loadBoards() },
) { paddingValues -> ) { paddingValues ->
@@ -66,7 +66,7 @@ fun KeysScreen(
} }
HermesScaffold( HermesScaffold(
title = "Keys & Credentials", title = { Text("Keys & Credentials") },
onOpenDrawer = onOpenDrawer, onOpenDrawer = onOpenDrawer,
onRefresh = { viewModel.loadKeys() }, onRefresh = { viewModel.loadKeys() },
) { paddingValues -> ) { paddingValues ->
@@ -59,7 +59,7 @@ fun LogsScreen(
} }
HermesScaffold( HermesScaffold(
title = "Logs", title = { Text("Logs") },
onOpenDrawer = onOpenDrawer, onOpenDrawer = onOpenDrawer,
onRefresh = { viewModel.loadLogs() }, onRefresh = { viewModel.loadLogs() },
) { ) {
@@ -59,7 +59,7 @@ fun McpServersScreen(
} }
HermesScaffold( HermesScaffold(
title = "MCP Servers", title = { Text("MCP Servers") },
onOpenDrawer = onOpenDrawer, onOpenDrawer = onOpenDrawer,
onRefresh = { viewModel.loadServers() }, onRefresh = { viewModel.loadServers() },
) { paddingValues -> ) { paddingValues ->
@@ -66,7 +66,7 @@ fun ModelScreen(
} }
HermesScaffold( HermesScaffold(
title = "Models", title = { Text("Models") },
onOpenDrawer = onOpenDrawer, onOpenDrawer = onOpenDrawer,
onRefresh = { viewModel.loadModelOptions() }, onRefresh = { viewModel.loadModelOptions() },
) { paddingValues -> ) { paddingValues ->
@@ -58,7 +58,7 @@ fun PairingScreen(
} }
HermesScaffold( HermesScaffold(
title = "Device Pairing", title = { Text("Device Pairing") },
onOpenDrawer = onOpenDrawer, onOpenDrawer = onOpenDrawer,
onRefresh = { viewModel.loadPairing() }, onRefresh = { viewModel.loadPairing() },
) { paddingValues -> ) { paddingValues ->
@@ -57,7 +57,7 @@ fun PluginsScreen(
} }
HermesScaffold( HermesScaffold(
title = "Plugins", title = { Text("Plugins") },
onOpenDrawer = onOpenDrawer, onOpenDrawer = onOpenDrawer,
onRefresh = { viewModel.loadPlugins() }, onRefresh = { viewModel.loadPlugins() },
) { paddingValues -> ) { paddingValues ->
@@ -70,7 +70,7 @@ fun ProfilesScreen(
} }
HermesScaffold( HermesScaffold(
title = "Profiles", title = { Text("Profiles") },
onOpenDrawer = onOpenDrawer, onOpenDrawer = onOpenDrawer,
onRefresh = { viewModel.loadProfiles() }, onRefresh = { viewModel.loadProfiles() },
) { paddingValues -> ) { paddingValues ->
@@ -67,7 +67,7 @@ fun SettingsScreen(
BackHandler(onBack = onBack) BackHandler(onBack = onBack)
HermesScaffold( HermesScaffold(
title = "Settings", title = { Text("Settings") },
showBack = true, showBack = true,
onBack = onBack, onBack = onBack,
) { ) {
@@ -72,7 +72,7 @@ fun SkillsScreen(
} }
HermesScaffold( HermesScaffold(
title = "Skills", title = { Text("Skills") },
onOpenDrawer = onOpenDrawer, onOpenDrawer = onOpenDrawer,
onRefresh = { viewModel.loadSkills() }, onRefresh = { viewModel.loadSkills() },
) { ) {
@@ -65,7 +65,7 @@ fun SystemScreen(
} }
HermesScaffold( HermesScaffold(
title = "System", title = { Text("System") },
onOpenDrawer = onOpenDrawer, onOpenDrawer = onOpenDrawer,
onRefresh = { viewModel.loadSystemData() }, onRefresh = { viewModel.loadSystemData() },
) { ) {
@@ -62,7 +62,7 @@ fun ToolsetsScreen(
} }
HermesScaffold( HermesScaffold(
title = "Toolsets", title = { Text("Toolsets") },
onOpenDrawer = onOpenDrawer, onOpenDrawer = onOpenDrawer,
onRefresh = { viewModel.loadToolsets() }, onRefresh = { viewModel.loadToolsets() },
) { paddingValues -> ) { paddingValues ->
@@ -60,7 +60,7 @@ fun WebhooksScreen(
} }
HermesScaffold( HermesScaffold(
title = "Webhooks", title = { Text("Webhooks") },
onOpenDrawer = onOpenDrawer, onOpenDrawer = onOpenDrawer,
onRefresh = { viewModel.loadWebhooks() }, onRefresh = { viewModel.loadWebhooks() },
) { paddingValues -> ) { paddingValues ->