UI: show corresponding system metrics detailed info upon tapping RAM / storage / temperature indicator
This commit is contained in:
parent
50cea70de3
commit
2e9de7c99c
|
|
@ -413,6 +413,7 @@ fun AppContent(
|
|||
AppScaffold(
|
||||
topBarconfig = scaffoldConfig.topBarConfig,
|
||||
bottomBarConfig = scaffoldConfig.bottomBarConfig,
|
||||
onScaffoldEvent = handleScaffoldEvent,
|
||||
snackbarHostState = snackbarHostState,
|
||||
) { paddingValues ->
|
||||
// AnimatedNavHost inside the scaffold content
|
||||
|
|
|
|||
|
|
@ -71,8 +71,8 @@ class PerformanceMonitor(@ApplicationContext private val context: Context) {
|
|||
availableMem = availableMem,
|
||||
totalMem = totalMem,
|
||||
percentUsed = percentUsed,
|
||||
availableGb = availableGb,
|
||||
totalGb = totalGb
|
||||
availableGB = availableGb,
|
||||
totalGB = totalGb
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ data class MemoryMetrics(
|
|||
val availableMem: Long,
|
||||
val totalMem: Long,
|
||||
val percentUsed: Int,
|
||||
val availableGb: Float,
|
||||
val totalGb: Float
|
||||
val availableGB: Float,
|
||||
val totalGB: Float
|
||||
)
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ sealed class ScaffoldEvent {
|
|||
fun AppScaffold(
|
||||
topBarconfig: TopBarConfig,
|
||||
bottomBarConfig: BottomBarConfig = BottomBarConfig.None,
|
||||
onScaffoldEvent: (ScaffoldEvent) -> Unit,
|
||||
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
|
||||
content: @Composable (PaddingValues) -> Unit
|
||||
) {
|
||||
|
|
@ -68,6 +69,7 @@ fun AppScaffold(
|
|||
title = topBarconfig.title,
|
||||
memoryMetrics = topBarconfig.memoryMetrics,
|
||||
temperatureDisplay = topBarconfig.temperatureInfo,
|
||||
onScaffoldEvent = onScaffoldEvent,
|
||||
onNavigateBack = topBarconfig.navigationIcon.backAction,
|
||||
onMenuOpen = topBarconfig.navigationIcon.menuAction,
|
||||
)
|
||||
|
|
@ -75,6 +77,7 @@ fun AppScaffold(
|
|||
is TopBarConfig.Storage -> StorageTopBar(
|
||||
title = topBarconfig.title,
|
||||
storageMetrics = topBarconfig.storageMetrics,
|
||||
onScaffoldEvent = onScaffoldEvent,
|
||||
onNavigateBack = topBarconfig.navigationIcon.backAction,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.example.llama.ui.scaffold.topbar
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
|
|
@ -20,10 +21,12 @@ import androidx.compose.material3.TopAppBarDefaults
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.semantics.Role
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.example.llama.monitoring.MemoryMetrics
|
||||
import com.example.llama.monitoring.TemperatureMetrics
|
||||
import com.example.llama.monitoring.TemperatureWarningLevel
|
||||
import com.example.llama.ui.scaffold.ScaffoldEvent
|
||||
import java.util.Locale
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
|
|
@ -32,6 +35,7 @@ fun PerformanceTopBar(
|
|||
title: String,
|
||||
memoryMetrics: MemoryMetrics?,
|
||||
temperatureDisplay: Pair<TemperatureMetrics, Boolean>?,
|
||||
onScaffoldEvent: (ScaffoldEvent) -> Unit,
|
||||
onNavigateBack: (() -> Unit)? = null,
|
||||
onMenuOpen: (() -> Unit)? = null,
|
||||
) {
|
||||
|
|
@ -63,7 +67,8 @@ fun PerformanceTopBar(
|
|||
temperatureDisplay?.let { (temperatureMetrics, useFahrenheit) ->
|
||||
TemperatureIndicator(
|
||||
temperatureMetrics = temperatureMetrics,
|
||||
useFahrenheit = useFahrenheit
|
||||
useFahrenheit = useFahrenheit,
|
||||
onScaffoldEvent = onScaffoldEvent,
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
|
|
@ -71,7 +76,7 @@ fun PerformanceTopBar(
|
|||
|
||||
// Memory indicator
|
||||
memoryMetrics?.let {
|
||||
MemoryIndicator(memoryUsage = it)
|
||||
MemoryIndicator(memoryUsage = it, onScaffoldEvent = onScaffoldEvent)
|
||||
}
|
||||
},
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
|
|
@ -82,17 +87,28 @@ fun PerformanceTopBar(
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun MemoryIndicator(memoryUsage: MemoryMetrics) {
|
||||
private fun MemoryIndicator(
|
||||
memoryUsage: MemoryMetrics,
|
||||
onScaffoldEvent: (ScaffoldEvent) -> Unit,
|
||||
) {
|
||||
val availableGB = String.format(Locale.getDefault(), "%.1f", memoryUsage.availableGB)
|
||||
val totalGB = String.format(Locale.getDefault(), "%.1f", memoryUsage.totalGB)
|
||||
|
||||
Row(
|
||||
modifier = Modifier.padding(end = 8.dp),
|
||||
modifier = Modifier.padding(end = 8.dp).clickable(role = Role.Button) {
|
||||
onScaffoldEvent(ScaffoldEvent.ShowSnackbar(
|
||||
message = "Free RAM available: $availableGB GB\nTotal RAM on your device: $totalGB GB",
|
||||
withDismissAction = true,
|
||||
))
|
||||
},
|
||||
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
|
||||
memoryUsage.availableGB < 1 -> MaterialTheme.colorScheme.error
|
||||
memoryUsage.availableGB < 3 -> MaterialTheme.colorScheme.tertiary
|
||||
else -> MaterialTheme.colorScheme.onSurface
|
||||
}
|
||||
)
|
||||
|
|
@ -100,17 +116,35 @@ private fun MemoryIndicator(memoryUsage: MemoryMetrics) {
|
|||
Spacer(modifier = Modifier.width(4.dp))
|
||||
|
||||
Text(
|
||||
text = String.format(
|
||||
Locale.getDefault(), "%.1f / %.1f GB", memoryUsage.availableGb, memoryUsage.totalGb
|
||||
),
|
||||
text = "$availableGB / $totalGB GB",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TemperatureIndicator(temperatureMetrics: TemperatureMetrics, useFahrenheit: Boolean) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
private fun TemperatureIndicator(
|
||||
temperatureMetrics: TemperatureMetrics,
|
||||
useFahrenheit: Boolean,
|
||||
onScaffoldEvent: (ScaffoldEvent) -> Unit,
|
||||
) {
|
||||
val temperatureDisplay = temperatureMetrics.getDisplay(useFahrenheit)
|
||||
|
||||
val temperatureWarning = when (temperatureMetrics.warningLevel) {
|
||||
TemperatureWarningLevel.HIGH -> "Your device is HEATED UP to $temperatureDisplay, please cool it down before continue using the app."
|
||||
TemperatureWarningLevel.MEDIUM -> "Your device is warming up to $temperatureDisplay."
|
||||
else -> "Your device's temperature is $temperatureDisplay."
|
||||
}
|
||||
val warningDismissible = temperatureMetrics.warningLevel == TemperatureWarningLevel.HIGH
|
||||
|
||||
Row(
|
||||
modifier = Modifier.clickable(role = Role.Button) {
|
||||
onScaffoldEvent(ScaffoldEvent.ShowSnackbar(
|
||||
message = temperatureWarning,
|
||||
withDismissAction = warningDismissible,
|
||||
))
|
||||
},
|
||||
verticalAlignment = Alignment.CenterVertically) {
|
||||
Icon(
|
||||
imageVector = when (temperatureMetrics.warningLevel) {
|
||||
TemperatureWarningLevel.HIGH -> Icons.Default.WarningAmber
|
||||
|
|
@ -127,7 +161,7 @@ private fun TemperatureIndicator(temperatureMetrics: TemperatureMetrics, useFahr
|
|||
Spacer(modifier = Modifier.width(2.dp))
|
||||
|
||||
Text(
|
||||
text = temperatureMetrics.getDisplay(useFahrenheit),
|
||||
text = temperatureDisplay,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = when (temperatureMetrics.warningLevel) {
|
||||
TemperatureWarningLevel.HIGH -> MaterialTheme.colorScheme.error
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.example.llama.ui.scaffold.topbar
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
|
|
@ -17,8 +18,10 @@ import androidx.compose.material3.TopAppBarDefaults
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.semantics.Role
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.example.llama.monitoring.StorageMetrics
|
||||
import com.example.llama.ui.scaffold.ScaffoldEvent
|
||||
import java.util.Locale
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
|
|
@ -26,6 +29,7 @@ import java.util.Locale
|
|||
fun StorageTopBar(
|
||||
title: String,
|
||||
storageMetrics: StorageMetrics?,
|
||||
onScaffoldEvent: (ScaffoldEvent) -> Unit,
|
||||
onNavigateBack: (() -> Unit)? = null,
|
||||
) {
|
||||
TopAppBar(
|
||||
|
|
@ -42,7 +46,7 @@ fun StorageTopBar(
|
|||
},
|
||||
actions = {
|
||||
storageMetrics?.let {
|
||||
StorageIndicator(storageMetrics = it)
|
||||
StorageIndicator(storageMetrics = it, onScaffoldEvent = onScaffoldEvent)
|
||||
}
|
||||
},
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
|
|
@ -53,20 +57,29 @@ fun StorageTopBar(
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun StorageIndicator(storageMetrics: StorageMetrics) {
|
||||
val usedGb = storageMetrics.usedGB
|
||||
val availableGb = storageMetrics.availableGB
|
||||
private fun StorageIndicator(
|
||||
storageMetrics: StorageMetrics,
|
||||
onScaffoldEvent: (ScaffoldEvent) -> Unit,
|
||||
) {
|
||||
|
||||
val usedGb = String.format(Locale.getDefault(), "%.1f", storageMetrics.usedGB)
|
||||
val availableGb = String.format(Locale.getDefault(), "%.1f", storageMetrics.availableGB)
|
||||
|
||||
Row(
|
||||
modifier = Modifier.padding(end = 8.dp),
|
||||
modifier = Modifier.padding(end = 8.dp).clickable(role = Role.Button) {
|
||||
onScaffoldEvent(ScaffoldEvent.ShowSnackbar(
|
||||
message = "Your models occupy $usedGb GB storage\nRemaining free space available: $availableGb GB",
|
||||
withDismissAction = true,
|
||||
))
|
||||
},
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.SdStorage,
|
||||
contentDescription = "Storage",
|
||||
tint = when {
|
||||
availableGb < 5.0f -> MaterialTheme.colorScheme.error
|
||||
availableGb < 10.0f -> MaterialTheme.colorScheme.tertiary
|
||||
storageMetrics.availableGB < 5.0f -> MaterialTheme.colorScheme.error
|
||||
storageMetrics.availableGB < 10.0f -> MaterialTheme.colorScheme.tertiary
|
||||
else -> MaterialTheme.colorScheme.onSurface
|
||||
}
|
||||
)
|
||||
|
|
@ -74,12 +87,7 @@ private fun StorageIndicator(storageMetrics: StorageMetrics) {
|
|||
Spacer(modifier = Modifier.width(2.dp))
|
||||
|
||||
Text(
|
||||
text = String.format(
|
||||
Locale.getDefault(),
|
||||
"%.1f / %.1f GB",
|
||||
usedGb,
|
||||
availableGb
|
||||
),
|
||||
text = "$usedGb / $availableGb GB",
|
||||
style = MaterialTheme.typography.bodySmall
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue