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 // Need to unload model before going back
handleBackWithModelCheck() handleBackWithModelCheck()
}, },
drawerState = drawerState,
navigationActions = navigationActions,
viewModel = viewModel viewModel = viewModel
) )
} }
@ -284,9 +282,6 @@ fun AppContent() {
composable(AppDestinations.MODELS_MANAGEMENT_ROUTE) { composable(AppDestinations.MODELS_MANAGEMENT_ROUTE) {
ModelsManagementScreen( ModelsManagementScreen(
onBackPressed = { navController.popBackStack() }, 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 tempC = tempTenthsC / 10.0f
val warningLevel = when { val warningLevel = when {
tempC >= 45.0f -> TemperatureWarningLevel.HIGH tempC >= 40.0f -> TemperatureWarningLevel.HIGH
tempC >= 40.0f -> TemperatureWarningLevel.MEDIUM tempC >= 35.0f -> TemperatureWarningLevel.MEDIUM
else -> TemperatureWarningLevel.NORMAL else -> TemperatureWarningLevel.NORMAL
} }
return TemperatureMetrics( return TemperatureMetrics(
temperature = tempC, tempCelsiusValue = tempC,
warningLevel = warningLevel warningLevel = warningLevel
) )
} }
@ -162,6 +162,15 @@ enum class TemperatureWarningLevel {
* Data class containing temperature information. * Data class containing temperature information.
*/ */
data class TemperatureMetrics( data class TemperatureMetrics(
val temperature: Float, private val tempCelsiusValue: Float,
val warningLevel: TemperatureWarningLevel 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 package com.example.llama.revamp.ui.components
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.material3.DrawerState import androidx.compose.foundation.layout.RowScope
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
@ -16,25 +13,41 @@ import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.llama.revamp.data.preferences.UserPreferences import com.example.llama.revamp.data.preferences.UserPreferences
import com.example.llama.revamp.monitoring.PerformanceMonitor 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.util.ViewModelFactoryProvider
import com.example.llama.revamp.viewmodel.PerformanceViewModel import com.example.llama.revamp.viewmodel.PerformanceViewModel
/** // DefaultAppScaffold.kt
* Main scaffold for the app that provides the top bar with system status
* and wraps content in a consistent layout.
*/
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun AppScaffold( fun DefaultAppScaffold(
title: String, title: String,
navigationActions: NavigationActions, onNavigateBack: (() -> Unit)? = null,
drawerState: DrawerState = rememberDrawerState(initialValue = DrawerValue.Closed), 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() }, snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
onBackPressed: (() -> Unit)? = null,
onMenuPressed: (() -> Unit)? = null,
onRerunPressed: (() -> Unit)? = null,
onSharePressed: (() -> Unit)? = null,
content: @Composable (PaddingValues) -> Unit content: @Composable (PaddingValues) -> Unit
) { ) {
// Create dependencies for PerformanceViewModel // Create dependencies for PerformanceViewModel
@ -50,22 +63,45 @@ fun AppScaffold(
// Collect performance metrics // Collect performance metrics
val memoryUsage by performanceViewModel.memoryUsage.collectAsState() val memoryUsage by performanceViewModel.memoryUsage.collectAsState()
val batteryInfo by performanceViewModel.batteryInfo.collectAsState()
val temperatureInfo by performanceViewModel.temperatureInfo.collectAsState() val temperatureInfo by performanceViewModel.temperatureInfo.collectAsState()
val useFahrenheit by performanceViewModel.useFahrenheitUnit.collectAsState() val useFahrenheit by performanceViewModel.useFahrenheitUnit.collectAsState()
Scaffold( Scaffold(
topBar = { topBar = {
SystemStatusTopBar( PerformanceTopBar(
title = title, title = title,
memoryUsage = memoryUsage, memoryMetrics = memoryUsage,
batteryLevel = batteryInfo.level, temperatureMetrics = temperatureInfo,
temperature = temperatureInfo.temperature, onNavigateBack = onNavigateBack,
onMenuOpen = onMenuOpen,
showTemperature = showTemperature,
useFahrenheit = useFahrenheit, useFahrenheit = useFahrenheit,
onBackPressed = onBackPressed, )
onMenuPressed = onMenuPressed, },
onRerunPressed = onRerunPressed, snackbarHost = {
onSharePressed = onSharePressed 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 = { 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 androidx.lifecycle.viewmodel.compose.viewModel
import com.example.llama.revamp.engine.InferenceEngine import com.example.llama.revamp.engine.InferenceEngine
import com.example.llama.revamp.navigation.NavigationActions 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.ui.theme.MonospacedTextStyle
import com.example.llama.revamp.viewmodel.MainViewModel import com.example.llama.revamp.viewmodel.MainViewModel
@ -42,13 +42,10 @@ fun BenchmarkScreen(
val benchmarkResults by viewModel.benchmarkResults.collectAsState() val benchmarkResults by viewModel.benchmarkResults.collectAsState()
val selectedModel by viewModel.selectedModel.collectAsState() val selectedModel by viewModel.selectedModel.collectAsState()
AppScaffold( PerformanceAppScaffold(
title = "Benchmark Results", title = "Chat",
drawerState = drawerState, onNavigateBack = onBackPressed,
navigationActions = navigationActions, showTemperature = true
onBackPressed = onBackPressed,
onRerunPressed = onRerunPressed,
onSharePressed = onSharePressed
) { paddingValues -> ) { paddingValues ->
Column( Column(
modifier = Modifier modifier = Modifier

View File

@ -33,7 +33,6 @@ import androidx.compose.material.icons.filled.Send
import androidx.compose.material3.Card import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.DrawerState
import androidx.compose.material3.Icon 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
@ -61,11 +60,9 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleEventObserver
import com.example.llama.revamp.engine.InferenceEngine import com.example.llama.revamp.engine.InferenceEngine
import com.example.llama.revamp.navigation.NavigationActions import com.example.llama.revamp.ui.components.PerformanceAppScaffold
import com.example.llama.revamp.ui.components.AppScaffold
import com.example.llama.revamp.viewmodel.MainViewModel import com.example.llama.revamp.viewmodel.MainViewModel
import com.example.llama.revamp.viewmodel.Message import com.example.llama.revamp.viewmodel.Message
import com.example.llama.revamp.viewmodel.TokenMetrics
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
/** /**
@ -74,8 +71,6 @@ import kotlinx.coroutines.launch
@Composable @Composable
fun ConversationScreen( fun ConversationScreen(
onBackPressed: () -> Unit, onBackPressed: () -> Unit,
drawerState: DrawerState,
navigationActions: NavigationActions,
viewModel: MainViewModel viewModel: MainViewModel
) { ) {
val engineState by viewModel.engineState.collectAsState() val engineState by viewModel.engineState.collectAsState()
@ -121,11 +116,10 @@ fun ConversationScreen(
} }
} }
AppScaffold( PerformanceAppScaffold(
title = "Chat", title = "Chat",
drawerState = drawerState, onNavigateBack = onBackPressed,
navigationActions = navigationActions, showTemperature = true
onBackPressed = onBackPressed
) { paddingValues -> ) { paddingValues ->
Column( Column(
modifier = Modifier 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.data.repository.SystemPromptRepository
import com.example.llama.revamp.engine.InferenceEngine import com.example.llama.revamp.engine.InferenceEngine
import com.example.llama.revamp.navigation.NavigationActions 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.util.ViewModelFactoryProvider
import com.example.llama.revamp.viewmodel.SystemPromptViewModel import com.example.llama.revamp.viewmodel.SystemPromptViewModel
@ -108,11 +108,10 @@ fun ModelLoadingScreen(
engineState !is InferenceEngine.State.LibraryLoaded && engineState !is InferenceEngine.State.LibraryLoaded &&
engineState !is InferenceEngine.State.AwaitingUserPrompt engineState !is InferenceEngine.State.AwaitingUserPrompt
AppScaffold( PerformanceAppScaffold(
title = "Select Mode", title = "Load Model",
drawerState = drawerState, onNavigateBack = onBackPressed,
navigationActions = navigationActions, showTemperature = false
onBackPressed = onBackPressed
) { paddingValues -> ) { paddingValues ->
Column( Column(
modifier = Modifier modifier = Modifier

View File

@ -28,7 +28,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.example.llama.revamp.data.model.ModelInfo import com.example.llama.revamp.data.model.ModelInfo
import com.example.llama.revamp.navigation.NavigationActions 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.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
@ -45,11 +45,10 @@ fun ModelSelectionScreen(
// For demo purposes, we'll use sample models // For demo purposes, we'll use sample models
val models = remember { ModelInfo.getSampleModels() } val models = remember { ModelInfo.getSampleModels() }
AppScaffold( PerformanceAppScaffold(
title = "Models", title = "Models",
drawerState = drawerState, onMenuOpen = onMenuClicked,
navigationActions = navigationActions, showTemperature = false
onMenuPressed = onMenuClicked
) { paddingValues -> ) { paddingValues ->
Column( Column(
modifier = Modifier 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.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons 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.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.material.icons.filled.Info
import androidx.compose.material3.Card import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults import androidx.compose.material3.CardDefaults
import androidx.compose.material3.DrawerState
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
@ -23,15 +26,17 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.example.llama.revamp.data.model.ModelInfo import com.example.llama.revamp.data.model.ModelInfo
import com.example.llama.revamp.navigation.NavigationActions import com.example.llama.revamp.ui.components.StorageAppScaffold
import com.example.llama.revamp.ui.components.AppScaffold
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
@ -42,18 +47,22 @@ import java.util.Locale
@Composable @Composable
fun ModelsManagementScreen( fun ModelsManagementScreen(
onBackPressed: () -> Unit, onBackPressed: () -> Unit,
drawerState: DrawerState,
navigationActions: NavigationActions,
onMenuClicked: () -> Unit
) { ) {
// For demo purposes, we'll use sample models // For demo purposes, we'll use sample models
val installedModels = remember { ModelInfo.getSampleModels() } val installedModels = remember { ModelInfo.getSampleModels() }
AppScaffold( // Edit mode for models' batch deletion
title = "Models", var isEditMode by remember { mutableStateOf(false) }
navigationActions = navigationActions,
onBackPressed = onBackPressed, // Calculate storage info
onMenuPressed = onMenuClicked 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 -> ) { paddingValues ->
Column( Column(
modifier = Modifier 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.data.preferences.UserPreferences
import com.example.llama.revamp.monitoring.PerformanceMonitor import com.example.llama.revamp.monitoring.PerformanceMonitor
import com.example.llama.revamp.navigation.NavigationActions 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.util.ViewModelFactoryProvider
import com.example.llama.revamp.viewmodel.PerformanceViewModel import com.example.llama.revamp.viewmodel.PerformanceViewModel
@ -56,11 +56,10 @@ fun SettingsGeneralScreen(
val isMonitoringEnabled by performanceViewModel.isMonitoringEnabled.collectAsState() val isMonitoringEnabled by performanceViewModel.isMonitoringEnabled.collectAsState()
val useFahrenheit by performanceViewModel.useFahrenheitUnit.collectAsState() val useFahrenheit by performanceViewModel.useFahrenheitUnit.collectAsState()
AppScaffold( DefaultAppScaffold(
title = "Settings", title = "Settings",
navigationActions = navigationActions, onNavigateBack = onBackPressed,
onBackPressed = onBackPressed, onMenuOpen = onMenuClicked
onMenuPressed = onMenuClicked
) { paddingValues -> ) { paddingValues ->
Column( Column(
modifier = Modifier modifier = Modifier