UI: refactor top app bars

This commit is contained in:
Han Yin 2025-04-13 14:43:57 -07:00
parent 2a41c0e354
commit 5e4972e93e
11 changed files with 346 additions and 250 deletions

View File

@ -245,8 +245,6 @@ fun AppContent() {
// Need to unload model before going back
handleBackWithModelCheck()
},
drawerState = drawerState,
navigationActions = navigationActions,
viewModel = viewModel
)
}
@ -284,9 +282,6 @@ fun AppContent() {
composable(AppDestinations.MODELS_MANAGEMENT_ROUTE) {
ModelsManagementScreen(
onBackPressed = { navController.popBackStack() },
drawerState = drawerState,
navigationActions = navigationActions,
onMenuClicked = openDrawer
)
}
}

View File

@ -106,13 +106,13 @@ class PerformanceMonitor(private val context: Context) {
val tempC = tempTenthsC / 10.0f
val warningLevel = when {
tempC >= 45.0f -> TemperatureWarningLevel.HIGH
tempC >= 40.0f -> TemperatureWarningLevel.MEDIUM
tempC >= 40.0f -> TemperatureWarningLevel.HIGH
tempC >= 35.0f -> TemperatureWarningLevel.MEDIUM
else -> TemperatureWarningLevel.NORMAL
}
return TemperatureMetrics(
temperature = tempC,
tempCelsiusValue = tempC,
warningLevel = warningLevel
)
}
@ -162,6 +162,15 @@ enum class TemperatureWarningLevel {
* Data class containing temperature information.
*/
data class TemperatureMetrics(
val temperature: Float,
private val tempCelsiusValue: Float,
val warningLevel: TemperatureWarningLevel
)
) {
val celsiusDisplay: String
get() = "${tempCelsiusValue.toInt()}°C"
val fahrenheitDisplay: String
get() = "${(tempCelsiusValue * 9/5 + 32).toInt()}°F"
fun getDisplay(useFahrenheit: Boolean) =
if (useFahrenheit) fahrenheitDisplay else celsiusDisplay
}

View File

@ -1,13 +1,10 @@
package com.example.llama.revamp.ui.components
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.material3.DrawerState
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.foundation.layout.RowScope
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
@ -16,25 +13,41 @@ import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.llama.revamp.data.preferences.UserPreferences
import com.example.llama.revamp.monitoring.PerformanceMonitor
import com.example.llama.revamp.navigation.NavigationActions
import com.example.llama.revamp.util.ViewModelFactoryProvider
import com.example.llama.revamp.viewmodel.PerformanceViewModel
/**
* Main scaffold for the app that provides the top bar with system status
* and wraps content in a consistent layout.
*/
@OptIn(ExperimentalMaterial3Api::class)
// DefaultAppScaffold.kt
@Composable
fun AppScaffold(
fun DefaultAppScaffold(
title: String,
navigationActions: NavigationActions,
drawerState: DrawerState = rememberDrawerState(initialValue = DrawerValue.Closed),
onNavigateBack: (() -> Unit)? = null,
onMenuOpen: (() -> Unit)? = null,
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
content: @Composable (PaddingValues) -> Unit
) {
Scaffold(
topBar = {
DefaultTopBar(
title = title,
onNavigateBack = onNavigateBack,
onMenuOpen = onMenuOpen
)
},
snackbarHost = {
SnackbarHost(hostState = snackbarHostState)
},
content = content
)
}
// PerformanceAppScaffold.kt
@Composable
fun PerformanceAppScaffold(
title: String,
onNavigateBack: (() -> Unit)? = null,
onMenuOpen: (() -> Unit)? = null,
showTemperature: Boolean = false,
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
onBackPressed: (() -> Unit)? = null,
onMenuPressed: (() -> Unit)? = null,
onRerunPressed: (() -> Unit)? = null,
onSharePressed: (() -> Unit)? = null,
content: @Composable (PaddingValues) -> Unit
) {
// Create dependencies for PerformanceViewModel
@ -50,22 +63,45 @@ fun AppScaffold(
// Collect performance metrics
val memoryUsage by performanceViewModel.memoryUsage.collectAsState()
val batteryInfo by performanceViewModel.batteryInfo.collectAsState()
val temperatureInfo by performanceViewModel.temperatureInfo.collectAsState()
val useFahrenheit by performanceViewModel.useFahrenheitUnit.collectAsState()
Scaffold(
topBar = {
SystemStatusTopBar(
PerformanceTopBar(
title = title,
memoryUsage = memoryUsage,
batteryLevel = batteryInfo.level,
temperature = temperatureInfo.temperature,
memoryMetrics = memoryUsage,
temperatureMetrics = temperatureInfo,
onNavigateBack = onNavigateBack,
onMenuOpen = onMenuOpen,
showTemperature = showTemperature,
useFahrenheit = useFahrenheit,
onBackPressed = onBackPressed,
onMenuPressed = onMenuPressed,
onRerunPressed = onRerunPressed,
onSharePressed = onSharePressed
)
},
snackbarHost = {
SnackbarHost(hostState = snackbarHostState)
},
content = content
)
}
// StorageAppScaffold.kt
@Composable
fun StorageAppScaffold(
title: String,
storageUsed: Float,
storageTotal: Float,
onNavigateBack: (() -> Unit)? = null,
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
content: @Composable (PaddingValues) -> Unit
) {
Scaffold(
topBar = {
StorageTopBar(
title = title,
storageUsed = storageUsed,
storageTotal = storageTotal,
onNavigateBack = onNavigateBack,
)
},
snackbarHost = {

View File

@ -1,169 +0,0 @@
package com.example.llama.revamp.ui.components
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.BatteryAlert
import androidx.compose.material.icons.filled.BatteryFull
import androidx.compose.material.icons.filled.BatteryStd
import androidx.compose.material.icons.filled.Memory
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material.icons.filled.Share
import androidx.compose.material.icons.filled.Thermostat
import androidx.compose.material.icons.filled.WarningAmber
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.example.llama.revamp.monitoring.MemoryMetrics
/**
* Top app bar that displays system status information and navigation controls.
*/
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SystemStatusTopBar(
title: String,
memoryUsage: MemoryMetrics,
batteryLevel: Int,
temperature: Float,
useFahrenheit: Boolean = false,
onBackPressed: (() -> Unit)? = null,
onMenuPressed: (() -> Unit)? = null,
onRerunPressed: (() -> Unit)? = null,
onSharePressed: (() -> Unit)? = null
) {
TopAppBar(
title = { Text(title) },
navigationIcon = {
when {
onBackPressed != null -> {
IconButton(onClick = onBackPressed) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = "Back"
)
}
}
onMenuPressed != null -> {
IconButton(onClick = onMenuPressed) {
Icon(
imageVector = Icons.Default.Menu,
contentDescription = "Menu"
)
}
}
}
},
actions = {
Row(verticalAlignment = Alignment.CenterVertically) {
// Memory usage
Icon(
imageVector = Icons.Default.Memory,
contentDescription = "RAM space",
tint = when {
memoryUsage.availableGb < 1 -> MaterialTheme.colorScheme.error
memoryUsage.availableGb < 3 -> MaterialTheme.colorScheme.tertiary
else -> MaterialTheme.colorScheme.onSurface
}
)
Spacer(modifier = Modifier.width(2.dp))
val memoryText = String.format("%.1f / %.1f GB", memoryUsage.availableGb, memoryUsage.totalGb)
Text(
text = memoryText,
style = MaterialTheme.typography.bodySmall,
modifier = Modifier.padding(end = 8.dp)
)
// Battery icon and percentage
Icon(
imageVector = when {
batteryLevel > 70 -> Icons.Default.BatteryFull
batteryLevel > 30 -> Icons.Default.BatteryStd
else -> Icons.Default.BatteryAlert
},
contentDescription = "Battery level",
tint = when {
batteryLevel <= 15 -> MaterialTheme.colorScheme.error
else -> MaterialTheme.colorScheme.onSurface
}
)
Text(
text = "$batteryLevel%",
style = MaterialTheme.typography.bodySmall
)
Spacer(modifier = Modifier.width(2.dp))
// Temperature icon and display
Icon(
imageVector = when {
temperature > 40 -> Icons.Default.WarningAmber
else -> Icons.Default.Thermostat
},
contentDescription = "Device temperature",
tint = when {
temperature > 40 -> MaterialTheme.colorScheme.error
else -> MaterialTheme.colorScheme.onSurface
}
)
val tempDisplay = if (useFahrenheit) {
"${(temperature * 9/5 + 32).toInt()}°F"
} else {
"${temperature.toInt()}°C"
}
val tempTint = when {
temperature >= 45 -> MaterialTheme.colorScheme.error
temperature >= 35 -> MaterialTheme.colorScheme.tertiary
else -> MaterialTheme.colorScheme.onSurface
}
Text(
text = tempDisplay,
style = MaterialTheme.typography.bodySmall,
color = tempTint
)
}
// Optional action buttons
onRerunPressed?.let {
IconButton(onClick = it) {
Icon(
imageVector = Icons.Default.Refresh,
contentDescription = "Rerun benchmark"
)
}
}
onSharePressed?.let {
IconButton(onClick = it) {
Icon(
imageVector = Icons.Default.Share,
contentDescription = "Share results"
)
}
}
},
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(
containerColor = MaterialTheme.colorScheme.surface,
titleContentColor = MaterialTheme.colorScheme.onSurface
)
)
}

View File

@ -0,0 +1,228 @@
package com.example.llama.revamp.ui.components
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Memory
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material.icons.filled.SdStorage
import androidx.compose.material.icons.filled.Storage
import androidx.compose.material.icons.filled.Thermostat
import androidx.compose.material.icons.filled.WarningAmber
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.example.llama.revamp.monitoring.MemoryMetrics
import com.example.llama.revamp.monitoring.TemperatureMetrics
import com.example.llama.revamp.monitoring.TemperatureWarningLevel
// TopAppBars.kt
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun DefaultTopBar(
title: String,
onNavigateBack: (() -> Unit)? = null,
onMenuOpen: (() -> Unit)? = null
) {
TopAppBar(
title = { Text(title) },
navigationIcon = {
when {
onNavigateBack != null -> {
IconButton(onClick = onNavigateBack) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = "Back"
)
}
}
onMenuOpen != null -> {
IconButton(onClick = onMenuOpen) {
Icon(
imageVector = Icons.Default.Menu,
contentDescription = "Menu"
)
}
}
}
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.surface,
titleContentColor = MaterialTheme.colorScheme.onSurface
)
)
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PerformanceTopBar(
title: String,
memoryMetrics: MemoryMetrics,
temperatureMetrics: TemperatureMetrics,
onNavigateBack: (() -> Unit)? = null,
onMenuOpen: (() -> Unit)? = null,
showTemperature: Boolean = false,
useFahrenheit: Boolean = false,
) {
TopAppBar(
title = { Text(title) },
navigationIcon = {
when {
onNavigateBack != null -> {
IconButton(onClick = onNavigateBack) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = "Back"
)
}
}
onMenuOpen != null -> {
IconButton(onClick = onMenuOpen) {
Icon(
imageVector = Icons.Default.Menu,
contentDescription = "Menu"
)
}
}
}
},
actions = {
// Temperature indicator (optional)
if (showTemperature) {
TemperatureIndicator(
temperature = temperatureMetrics,
useFahrenheit = useFahrenheit
)
Spacer(modifier = Modifier.width(8.dp))
}
// Memory indicator
MemoryIndicator(memoryUsage = memoryMetrics)
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.surface,
titleContentColor = MaterialTheme.colorScheme.onSurface
)
)
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun StorageTopBar(
title: String,
storageUsed: Float,
storageTotal: Float,
onNavigateBack: (() -> Unit)? = null,
) {
TopAppBar(
title = { Text(title) },
navigationIcon = {
if (onNavigateBack != null) {
IconButton(onClick = onNavigateBack) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = "Back"
)
}
}
},
actions = {
StorageIndicator(usedGB = storageUsed, totalGB = storageTotal)
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.surface,
titleContentColor = MaterialTheme.colorScheme.onSurface
)
)
}
@Composable
fun MemoryIndicator(memoryUsage: MemoryMetrics) {
Row(modifier = Modifier.padding(end = 8.dp), verticalAlignment = Alignment.CenterVertically) {
Icon(
imageVector = Icons.Default.Memory,
contentDescription = "RAM usage",
tint = when {
memoryUsage.availableGb < 1 -> MaterialTheme.colorScheme.error
memoryUsage.availableGb < 3 -> MaterialTheme.colorScheme.tertiary
else -> MaterialTheme.colorScheme.onSurface
}
)
Spacer(modifier = Modifier.width(4.dp))
val memoryText = String.format("%.1f / %.1f GB", memoryUsage.availableGb, memoryUsage.totalGb)
Text(
text = memoryText,
style = MaterialTheme.typography.bodySmall,
)
}
}
@Composable
fun TemperatureIndicator(temperature: TemperatureMetrics, useFahrenheit: Boolean) {
Row(verticalAlignment = Alignment.CenterVertically) {
Icon(
imageVector = when (temperature.warningLevel) {
TemperatureWarningLevel.HIGH -> Icons.Default.WarningAmber
else -> Icons.Default.Thermostat
},
contentDescription = "Device temperature",
tint = when (temperature.warningLevel) {
TemperatureWarningLevel.HIGH -> MaterialTheme.colorScheme.error
TemperatureWarningLevel.MEDIUM -> MaterialTheme.colorScheme.tertiary
else -> MaterialTheme.colorScheme.onSurface
}
)
Spacer(modifier = Modifier.width(2.dp))
val tempDisplay = if (useFahrenheit) temperature.fahrenheitDisplay else temperature.celsiusDisplay
Text(
text = tempDisplay,
style = MaterialTheme.typography.bodySmall,
color = when (temperature.warningLevel) {
TemperatureWarningLevel.HIGH -> MaterialTheme.colorScheme.error
TemperatureWarningLevel.MEDIUM -> MaterialTheme.colorScheme.tertiary
else -> MaterialTheme.colorScheme.onSurface
}
)
}
}
@Composable
fun StorageIndicator(usedGB: Float, totalGB: Float) {
Row(modifier = Modifier.padding(end = 8.dp), verticalAlignment = Alignment.CenterVertically) {
Icon(
imageVector = Icons.Default.SdStorage,
contentDescription = "Storage",
tint = when {
usedGB / totalGB > 0.9f -> MaterialTheme.colorScheme.error
usedGB / totalGB > 0.7f -> MaterialTheme.colorScheme.tertiary
else -> MaterialTheme.colorScheme.onSurface
}
)
Spacer(modifier = Modifier.width(2.dp))
Text(
text = String.format("%.1f / %.1f GB", usedGB, totalGB),
style = MaterialTheme.typography.bodySmall
)
}
}

View File

@ -25,7 +25,7 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.llama.revamp.engine.InferenceEngine
import com.example.llama.revamp.navigation.NavigationActions
import com.example.llama.revamp.ui.components.AppScaffold
import com.example.llama.revamp.ui.components.PerformanceAppScaffold
import com.example.llama.revamp.ui.theme.MonospacedTextStyle
import com.example.llama.revamp.viewmodel.MainViewModel
@ -42,13 +42,10 @@ fun BenchmarkScreen(
val benchmarkResults by viewModel.benchmarkResults.collectAsState()
val selectedModel by viewModel.selectedModel.collectAsState()
AppScaffold(
title = "Benchmark Results",
drawerState = drawerState,
navigationActions = navigationActions,
onBackPressed = onBackPressed,
onRerunPressed = onRerunPressed,
onSharePressed = onSharePressed
PerformanceAppScaffold(
title = "Chat",
onNavigateBack = onBackPressed,
showTemperature = true
) { paddingValues ->
Column(
modifier = Modifier

View File

@ -33,7 +33,6 @@ import androidx.compose.material.icons.filled.Send
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.DrawerState
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
@ -61,11 +60,9 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import com.example.llama.revamp.engine.InferenceEngine
import com.example.llama.revamp.navigation.NavigationActions
import com.example.llama.revamp.ui.components.AppScaffold
import com.example.llama.revamp.ui.components.PerformanceAppScaffold
import com.example.llama.revamp.viewmodel.MainViewModel
import com.example.llama.revamp.viewmodel.Message
import com.example.llama.revamp.viewmodel.TokenMetrics
import kotlinx.coroutines.launch
/**
@ -74,8 +71,6 @@ import kotlinx.coroutines.launch
@Composable
fun ConversationScreen(
onBackPressed: () -> Unit,
drawerState: DrawerState,
navigationActions: NavigationActions,
viewModel: MainViewModel
) {
val engineState by viewModel.engineState.collectAsState()
@ -121,11 +116,10 @@ fun ConversationScreen(
}
}
AppScaffold(
PerformanceAppScaffold(
title = "Chat",
drawerState = drawerState,
navigationActions = navigationActions,
onBackPressed = onBackPressed
onNavigateBack = onBackPressed,
showTemperature = true
) { paddingValues ->
Column(
modifier = Modifier

View File

@ -53,7 +53,7 @@ import com.example.llama.revamp.data.model.SystemPrompt
import com.example.llama.revamp.data.repository.SystemPromptRepository
import com.example.llama.revamp.engine.InferenceEngine
import com.example.llama.revamp.navigation.NavigationActions
import com.example.llama.revamp.ui.components.AppScaffold
import com.example.llama.revamp.ui.components.PerformanceAppScaffold
import com.example.llama.revamp.util.ViewModelFactoryProvider
import com.example.llama.revamp.viewmodel.SystemPromptViewModel
@ -108,11 +108,10 @@ fun ModelLoadingScreen(
engineState !is InferenceEngine.State.LibraryLoaded &&
engineState !is InferenceEngine.State.AwaitingUserPrompt
AppScaffold(
title = "Select Mode",
drawerState = drawerState,
navigationActions = navigationActions,
onBackPressed = onBackPressed
PerformanceAppScaffold(
title = "Load Model",
onNavigateBack = onBackPressed,
showTemperature = false
) { paddingValues ->
Column(
modifier = Modifier

View File

@ -28,7 +28,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.example.llama.revamp.data.model.ModelInfo
import com.example.llama.revamp.navigation.NavigationActions
import com.example.llama.revamp.ui.components.AppScaffold
import com.example.llama.revamp.ui.components.PerformanceAppScaffold
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
@ -45,11 +45,10 @@ fun ModelSelectionScreen(
// For demo purposes, we'll use sample models
val models = remember { ModelInfo.getSampleModels() }
AppScaffold(
PerformanceAppScaffold(
title = "Models",
drawerState = drawerState,
navigationActions = navigationActions,
onMenuPressed = onMenuClicked
onMenuOpen = onMenuClicked,
showTemperature = false
) { paddingValues ->
Column(
modifier = Modifier

View File

@ -10,11 +10,14 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.CloudDownload
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Done
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.FileOpen
import androidx.compose.material.icons.filled.Info
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.DrawerState
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
@ -23,15 +26,17 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.example.llama.revamp.data.model.ModelInfo
import com.example.llama.revamp.navigation.NavigationActions
import com.example.llama.revamp.ui.components.AppScaffold
import com.example.llama.revamp.ui.components.StorageAppScaffold
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
@ -42,18 +47,22 @@ import java.util.Locale
@Composable
fun ModelsManagementScreen(
onBackPressed: () -> Unit,
drawerState: DrawerState,
navigationActions: NavigationActions,
onMenuClicked: () -> Unit
) {
// For demo purposes, we'll use sample models
val installedModels = remember { ModelInfo.getSampleModels() }
AppScaffold(
title = "Models",
navigationActions = navigationActions,
onBackPressed = onBackPressed,
onMenuPressed = onMenuClicked
// Edit mode for models' batch deletion
var isEditMode by remember { mutableStateOf(false) }
// Calculate storage info
val storageUsed = 14.6f // This would be calculated from actual models
val storageTotal = 32.0f // This would be from device storage info
StorageAppScaffold(
title = "Models Management",
storageUsed = storageUsed,
storageTotal = storageTotal,
onNavigateBack = onBackPressed,
) { paddingValues ->
Column(
modifier = Modifier

View File

@ -27,7 +27,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.llama.revamp.data.preferences.UserPreferences
import com.example.llama.revamp.monitoring.PerformanceMonitor
import com.example.llama.revamp.navigation.NavigationActions
import com.example.llama.revamp.ui.components.AppScaffold
import com.example.llama.revamp.ui.components.DefaultAppScaffold
import com.example.llama.revamp.util.ViewModelFactoryProvider
import com.example.llama.revamp.viewmodel.PerformanceViewModel
@ -56,11 +56,10 @@ fun SettingsGeneralScreen(
val isMonitoringEnabled by performanceViewModel.isMonitoringEnabled.collectAsState()
val useFahrenheit by performanceViewModel.useFahrenheitUnit.collectAsState()
AppScaffold(
DefaultAppScaffold(
title = "Settings",
navigationActions = navigationActions,
onBackPressed = onBackPressed,
onMenuPressed = onMenuClicked
onNavigateBack = onBackPressed,
onMenuOpen = onMenuClicked
) { paddingValues ->
Column(
modifier = Modifier