From 4dd519456bcecd195e22c2438b4ba0977a3ba2d5 Mon Sep 17 00:00:00 2001 From: Dane Evans Date: Sat, 6 Sep 2025 15:03:15 +1000 Subject: [PATCH] Revert "align strategies for display, add missing entries, clean up display when everything is present," This reverts commit 2f1a3fabb925a06df36fc14a6c9d3764493bd523. --- .../mesh/ui/metrics/EnvironmentMetrics.kt | 204 ++++++------------ 1 file changed, 70 insertions(+), 134 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/ui/metrics/EnvironmentMetrics.kt b/app/src/main/java/com/geeksville/mesh/ui/metrics/EnvironmentMetrics.kt index 7d7db006a..3a4308998 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/metrics/EnvironmentMetrics.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/metrics/EnvironmentMetrics.kt @@ -24,6 +24,7 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn @@ -44,7 +45,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -120,45 +120,35 @@ fun EnvironmentMetricsScreen(viewModel: MetricsViewModel = hiltViewModel()) { } @Composable -private fun TemperatureDisplay(envMetrics: TelemetryProtos.EnvironmentMetrics, environmentDisplayFahrenheit: Boolean) { - envMetrics.temperature?.let { temperature -> - if (!temperature.isNaN()) { - val textFormat = if (environmentDisplayFahrenheit) "%s %.1f°F" else "%s %.1f°C" - Text( - text = textFormat.format(stringResource(id = R.string.temperature), temperature), - color = MaterialTheme.colorScheme.onSurface, - fontSize = MaterialTheme.typography.labelLarge.fontSize, - ) - } +private fun TemperatureDisplay(temperature: Float, environmentDisplayFahrenheit: Boolean) { + if (!temperature.isNaN()) { + val textFormat = if (environmentDisplayFahrenheit) "%s %.1f°F" else "%s %.1f°C" + Text( + text = textFormat.format(stringResource(id = R.string.temperature), temperature), + color = MaterialTheme.colorScheme.onSurface, + fontSize = MaterialTheme.typography.labelLarge.fontSize, + ) } } @Composable private fun HumidityAndBarometricPressureDisplay(envMetrics: TelemetryProtos.EnvironmentMetrics) { - val hasHumidity = envMetrics.relativeHumidity?.let { !it.isNaN() } == true - val hasPressure = envMetrics.barometricPressure?.let { !it.isNaN() && it > 0 } == true - - if (hasHumidity || hasPressure) { - Row( - modifier = Modifier.fillMaxWidth().padding(vertical = 0.dp), - horizontalArrangement = Arrangement.SpaceBetween, - ) { - if (hasHumidity) { - val humidity = envMetrics.relativeHumidity!! + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { + envMetrics.relativeHumidity?.let { humidity -> + if (!humidity.isNaN()) { Text( text = "%s %.2f%%".format(stringResource(id = R.string.humidity), humidity), color = MaterialTheme.colorScheme.onSurface, fontSize = MaterialTheme.typography.labelLarge.fontSize, - modifier = Modifier.padding(vertical = 0.dp), ) } - if (hasPressure) { - val pressure = envMetrics.barometricPressure!! + } + envMetrics.barometricPressure?.let { pressure -> + if (!pressure.isNaN() && pressure > 0) { // Keep pressure > 0 check Text( text = "%.2f hPa".format(pressure), color = MaterialTheme.colorScheme.onSurface, fontSize = MaterialTheme.typography.labelLarge.fontSize, - modifier = Modifier.padding(vertical = 0.dp), ) } } @@ -171,6 +161,7 @@ private fun SoilMetricsDisplay(envMetrics: TelemetryProtos.EnvironmentMetrics, e envMetrics.soilTemperature != null || (envMetrics.soilMoisture != null && envMetrics.soilMoisture != Int.MIN_VALUE) ) { + Spacer(modifier = Modifier.height(4.dp)) Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { val soilTemperatureTextFormat = if (environmentDisplayFahrenheit) "%s %.1f°F" else "%s %.1f°C" val soilMoistureTextFormat = "%s %d%%" @@ -201,22 +192,40 @@ private fun SoilMetricsDisplay(envMetrics: TelemetryProtos.EnvironmentMetrics, e } @Composable -private fun LuxUVLuxDisplay(envMetrics: TelemetryProtos.EnvironmentMetrics) { - val hasLux = envMetrics.lux != null && !envMetrics.lux.isNaN() - val hasUvLux = envMetrics.uvLux != null && !envMetrics.uvLux.isNaN() +private fun IaqDisplay(iaqValue: Int) { + if (iaqValue != Int.MIN_VALUE) { + Spacer(modifier = Modifier.height(4.dp)) + /* Air Quality */ + Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) { + Text( + text = stringResource(R.string.iaq), + color = MaterialTheme.colorScheme.onSurface, + fontSize = MaterialTheme.typography.labelLarge.fontSize, + ) + Spacer(modifier = Modifier.width(4.dp)) + IndoorAirQuality(iaq = iaqValue, displayMode = IaqDisplayMode.Dot) + } + } +} - if (hasLux || hasUvLux) { - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { - if (hasLux) { - val luxValue = envMetrics.lux!! +@Composable +private fun LuxUVLuxDisplay(envMetrics: TelemetryProtos.EnvironmentMetrics) { + envMetrics.lux?.let { luxValue -> + if (!luxValue.isNaN()) { + Spacer(modifier = Modifier.height(4.dp)) + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { Text( text = "%s %.0f lx".format(stringResource(R.string.lux), luxValue), color = MaterialTheme.colorScheme.onSurface, fontSize = MaterialTheme.typography.labelLarge.fontSize, ) } - if (hasUvLux) { - val uvLuxValue = envMetrics.uvLux!! + } + } + envMetrics.uvLux?.let { uvLuxValue -> + if (!uvLuxValue.isNaN()) { + Spacer(modifier = Modifier.height(4.dp)) + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { Text( text = "%s %.0f UVlx".format(stringResource(R.string.uv_lux), uvLuxValue), color = MaterialTheme.colorScheme.onSurface, @@ -229,21 +238,23 @@ private fun LuxUVLuxDisplay(envMetrics: TelemetryProtos.EnvironmentMetrics) { @Composable private fun VoltageCurrentDisplay(envMetrics: TelemetryProtos.EnvironmentMetrics) { - val hasVoltage = envMetrics.voltage != null && !envMetrics.voltage.isNaN() - val hasCurrent = envMetrics.current != null && !envMetrics.current.isNaN() - - if (hasVoltage || hasCurrent) { - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { - if (hasVoltage) { - val voltage = envMetrics.voltage!! + envMetrics.voltage?.let { voltage -> + if (!voltage.isNaN()) { + Spacer(modifier = Modifier.height(4.dp)) + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { Text( text = "%s %.2f V".format(stringResource(R.string.voltage), voltage), color = MaterialTheme.colorScheme.onSurface, fontSize = MaterialTheme.typography.labelLarge.fontSize, ) } - if (hasCurrent) { - val current = envMetrics.current!! + } + } + + envMetrics.current?.let { current -> + if (!current.isNaN()) { + Spacer(modifier = Modifier.height(4.dp)) + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { Text( text = "%s %.2f mA".format(stringResource(R.string.current), current), color = MaterialTheme.colorScheme.onSurface, @@ -255,66 +266,15 @@ private fun VoltageCurrentDisplay(envMetrics: TelemetryProtos.EnvironmentMetrics } @Composable -private fun GasCompositionDisplay(envMetrics: TelemetryProtos.EnvironmentMetrics) { - val iaqValue = envMetrics.iaq - val gasResistance = envMetrics.gasResistance - - if ((iaqValue != null && iaqValue != Int.MIN_VALUE) || (gasResistance != null && !gasResistance.isNaN())) { +private fun GasResistanceDisplay(gasResistance: Float) { + if (!gasResistance.isNaN()) { + Spacer(modifier = Modifier.height(4.dp)) Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { - if (iaqValue != null && iaqValue != Int.MIN_VALUE) { - Row(verticalAlignment = Alignment.CenterVertically) { - Text( - text = stringResource(R.string.iaq), - color = MaterialTheme.colorScheme.onSurface, - fontSize = MaterialTheme.typography.labelLarge.fontSize, - ) - Spacer(modifier = Modifier.width(4.dp)) - IndoorAirQuality(iaq = iaqValue, displayMode = IaqDisplayMode.Dot) - } - } - if (gasResistance != null && !gasResistance.isNaN()) { - Text( - text = "%s %.2f Ohm".format(stringResource(R.string.gas_resistance), gasResistance), - color = MaterialTheme.colorScheme.onSurface, - fontSize = MaterialTheme.typography.labelLarge.fontSize, - ) - } - } - } - // These are in a differnt proto ... - // envMetrics.co2?.let { co2 -> - // Spacer(modifier = Modifier.height(4.dp)) - // Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { - // Text( - // text = "%s %.0f ppm".format(stringResource(R.string.co2), co2), - // color = MaterialTheme.colorScheme.onSurface, - // fontSize = MaterialTheme.typography.labelLarge.fontSize, - // ) - // } - // } - // envMetrics.tvoc?.let { tvoc -> - // Spacer(modifier = Modifier.height(4.dp)) - // Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { - // Text( - // text = "%s %.0f ppb".format(stringResource(R.string.tvoc), tvoc), - // color = MaterialTheme.colorScheme.onSurface, - // fontSize = MaterialTheme.typography.labelLarge.fontSize, - // ) - // } - // } -} - -@Composable -private fun RadiationDisplay(envMetrics: TelemetryProtos.EnvironmentMetrics) { - envMetrics.radiation?.let { radiation -> - if (!radiation.isNaN() && radiation > 0f) { - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { - Text( - text = "%s %.2f µSv/h".format(stringResource(R.string.radiation), radiation), - color = MaterialTheme.colorScheme.onSurface, - fontSize = MaterialTheme.typography.labelLarge.fontSize, - ) - } + Text( + text = "%s %.2f Ohm".format(stringResource(R.string.gas_resistance), gasResistance), + color = MaterialTheme.colorScheme.onSurface, + fontSize = MaterialTheme.typography.labelLarge.fontSize, + ) } } } @@ -332,7 +292,7 @@ private fun EnvironmentMetricsCard(telemetry: Telemetry, environmentDisplayFahre private fun EnvironmentMetricsContent(telemetry: Telemetry, environmentDisplayFahrenheit: Boolean) { val envMetrics = telemetry.environmentMetrics val time = telemetry.time * MS_PER_SEC - Column(modifier = Modifier.fillMaxWidth().padding(horizontal = 2.dp, vertical = 2.dp)) { + Column(modifier = Modifier.fillMaxWidth().padding(8.dp)) { /* Time and Temperature */ Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { Text( @@ -340,47 +300,23 @@ private fun EnvironmentMetricsContent(telemetry: Telemetry, environmentDisplayFa style = TextStyle(fontWeight = FontWeight.Bold), fontSize = MaterialTheme.typography.labelLarge.fontSize, ) - TemperatureDisplay(envMetrics, environmentDisplayFahrenheit) + envMetrics.temperature?.let { temperature -> TemperatureDisplay(temperature, environmentDisplayFahrenheit) } } + Spacer(modifier = Modifier.height(4.dp)) + + /* Humidity and Barometric Pressure */ HumidityAndBarometricPressureDisplay(envMetrics) + /* Soil Moisture and Soil Temperature */ SoilMetricsDisplay(envMetrics, environmentDisplayFahrenheit) - GasCompositionDisplay(envMetrics) + envMetrics.iaq?.let { iaqValue -> IaqDisplay(iaqValue) } LuxUVLuxDisplay(envMetrics) VoltageCurrentDisplay(envMetrics) - RadiationDisplay(envMetrics) - } -} -@Preview(showBackground = true) -@Composable -private fun PreviewEnvironmentMetricsContent() { - // Build a fake EnvironmentMetrics using the generated proto builder APIs - val fakeEnvMetrics = - TelemetryProtos.EnvironmentMetrics.newBuilder() - .setTemperature(22.5f) - .setRelativeHumidity(55.0f) - .setBarometricPressure(1013.25f) - .setSoilMoisture(33) - .setSoilTemperature(18.0f) - .setLux(100.0f) - .setUvLux(100.0f) - .setVoltage(3.7f) - .setCurrent(0.12f) - .setIaq(100) - .setRadiation(0.15f) - .setGasResistance(1200.0f) - .build() - val fakeTelemetry = - TelemetryProtos.Telemetry.newBuilder() - .setTime((System.currentTimeMillis() / 1000).toInt()) - .setEnvironmentMetrics(fakeEnvMetrics) - .build() - MaterialTheme { - Surface { EnvironmentMetricsContent(telemetry = fakeTelemetry, environmentDisplayFahrenheit = false) } + envMetrics.gasResistance?.let { gasResistance -> GasResistanceDisplay(gasResistance) } } }