mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
refactor: consolidate metric formatting through MetricFormatter (#5169)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
9f3fe865e3
commit
b979663e24
5 changed files with 56 additions and 13 deletions
|
|
@ -23,6 +23,7 @@ package org.meshtastic.core.common.util
|
|||
* All methods return locale-independent strings using [NumberFormatter] (dot decimal separator), which is intentional
|
||||
* for a mesh networking app where consistency matters.
|
||||
*/
|
||||
@Suppress("TooManyFunctions")
|
||||
object MetricFormatter {
|
||||
|
||||
fun temperature(celsius: Float, isFahrenheit: Boolean): String {
|
||||
|
|
@ -47,6 +48,12 @@ object MetricFormatter {
|
|||
fun snr(value: Float, decimalPlaces: Int = 1): String = "${NumberFormatter.format(value, decimalPlaces)} dB"
|
||||
|
||||
fun rssi(value: Int): String = "$value dBm"
|
||||
|
||||
fun windSpeed(metersPerSecond: Float, decimalPlaces: Int = 1): String =
|
||||
"${NumberFormatter.format(metersPerSecond, decimalPlaces)} m/s"
|
||||
|
||||
fun rainfall(millimeters: Float, decimalPlaces: Int = 1): String =
|
||||
"${NumberFormatter.format(millimeters, decimalPlaces)} mm"
|
||||
}
|
||||
|
||||
private const val FAHRENHEIT_SCALE = 1.8f
|
||||
|
|
|
|||
|
|
@ -120,4 +120,24 @@ class MetricFormatterTest {
|
|||
fun snrNegative() {
|
||||
assertEquals("-5.5 dB", MetricFormatter.snr(-5.5f))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun windSpeed() {
|
||||
assertEquals("12.3 m/s", MetricFormatter.windSpeed(12.34f))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun windSpeedZero() {
|
||||
assertEquals("0.0 m/s", MetricFormatter.windSpeed(0.0f))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun rainfall() {
|
||||
assertEquals("2.5 mm", MetricFormatter.rainfall(2.54f))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun rainfallZero() {
|
||||
assertEquals("0.0 mm", MetricFormatter.rainfall(0.0f))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.common.util.DateFormatter
|
||||
import org.meshtastic.core.common.util.MetricFormatter
|
||||
import org.meshtastic.core.common.util.formatString
|
||||
import org.meshtastic.core.common.util.nowSeconds
|
||||
import org.meshtastic.core.model.TelemetryType
|
||||
|
|
@ -165,7 +166,10 @@ private fun HumidityAndBarometricPressureDisplay(envMetrics: org.meshtastic.prot
|
|||
MetricIndicator(Environment.HUMIDITY.color)
|
||||
Spacer(Modifier.width(4.dp))
|
||||
Text(
|
||||
text = formatString("%s %.2f%%", stringResource(Res.string.humidity), humidity),
|
||||
text =
|
||||
"${stringResource(
|
||||
Res.string.humidity,
|
||||
)} ${MetricFormatter.percent(humidity, decimalPlaces = 2)}",
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
fontSize = MaterialTheme.typography.labelLarge.fontSize,
|
||||
modifier = Modifier.padding(vertical = 0.dp),
|
||||
|
|
@ -178,7 +182,7 @@ private fun HumidityAndBarometricPressureDisplay(envMetrics: org.meshtastic.prot
|
|||
MetricIndicator(Environment.BAROMETRIC_PRESSURE.color)
|
||||
Spacer(Modifier.width(4.dp))
|
||||
Text(
|
||||
text = formatString("%.2f hPa", pressure),
|
||||
text = MetricFormatter.pressure(pressure, decimalPlaces = 2),
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
fontSize = MaterialTheme.typography.labelLarge.fontSize,
|
||||
modifier = Modifier.padding(vertical = 0.dp),
|
||||
|
|
@ -286,7 +290,7 @@ private fun VoltageCurrentDisplay(envMetrics: org.meshtastic.proto.EnvironmentMe
|
|||
if (hasVoltage) {
|
||||
val voltage = envMetrics.voltage!!
|
||||
Text(
|
||||
text = formatString("%s %.2f V", stringResource(Res.string.voltage), voltage),
|
||||
text = "${stringResource(Res.string.voltage)} ${MetricFormatter.voltage(voltage)}",
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
fontSize = MaterialTheme.typography.labelLarge.fontSize,
|
||||
)
|
||||
|
|
@ -294,7 +298,10 @@ private fun VoltageCurrentDisplay(envMetrics: org.meshtastic.proto.EnvironmentMe
|
|||
if (hasCurrent) {
|
||||
val currentValue = envMetrics.current!!
|
||||
Text(
|
||||
text = formatString("%s %.2f mA", stringResource(Res.string.current), currentValue),
|
||||
text =
|
||||
"${stringResource(
|
||||
Res.string.current,
|
||||
)} ${MetricFormatter.current(currentValue, decimalPlaces = 2)}",
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
fontSize = MaterialTheme.typography.labelLarge.fontSize,
|
||||
)
|
||||
|
|
@ -387,7 +394,11 @@ private fun WindSpeedRow(envMetrics: org.meshtastic.proto.EnvironmentMetrics) {
|
|||
envMetrics.wind_direction!!,
|
||||
)
|
||||
} else {
|
||||
formatString("%s %.1f m/s", stringResource(Res.string.wind_speed), envMetrics.wind_speed!!)
|
||||
formatString(
|
||||
"%s %s",
|
||||
stringResource(Res.string.wind_speed),
|
||||
MetricFormatter.windSpeed(envMetrics.wind_speed!!),
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = dirText,
|
||||
|
|
@ -403,14 +414,14 @@ private fun WindGustLullRow(envMetrics: org.meshtastic.proto.EnvironmentMetrics,
|
|||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
|
||||
if (hasGust) {
|
||||
Text(
|
||||
text = formatString("%s %.1f m/s", stringResource(Res.string.wind_gust), envMetrics.wind_gust!!),
|
||||
text = "${stringResource(Res.string.wind_gust)} ${MetricFormatter.windSpeed(envMetrics.wind_gust!!)}",
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
fontSize = MaterialTheme.typography.labelLarge.fontSize,
|
||||
)
|
||||
}
|
||||
if (hasLull) {
|
||||
Text(
|
||||
text = formatString("%s %.1f m/s", stringResource(Res.string.wind_lull), envMetrics.wind_lull!!),
|
||||
text = "${stringResource(Res.string.wind_lull)} ${MetricFormatter.windSpeed(envMetrics.wind_lull!!)}",
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
fontSize = MaterialTheme.typography.labelLarge.fontSize,
|
||||
)
|
||||
|
|
@ -427,7 +438,10 @@ private fun RainfallDisplay(envMetrics: org.meshtastic.proto.EnvironmentMetrics)
|
|||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
|
||||
if (has1h) {
|
||||
Text(
|
||||
text = formatString("%s %.1f mm", stringResource(Res.string.rainfall_1h), envMetrics.rainfall_1h!!),
|
||||
text =
|
||||
"${stringResource(
|
||||
Res.string.rainfall_1h,
|
||||
)} ${MetricFormatter.rainfall(envMetrics.rainfall_1h!!)}",
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
fontSize = MaterialTheme.typography.labelLarge.fontSize,
|
||||
)
|
||||
|
|
@ -435,7 +449,9 @@ private fun RainfallDisplay(envMetrics: org.meshtastic.proto.EnvironmentMetrics)
|
|||
if (has24h) {
|
||||
Text(
|
||||
text =
|
||||
formatString("%s %.1f mm", stringResource(Res.string.rainfall_24h), envMetrics.rainfall_24h!!),
|
||||
"${stringResource(
|
||||
Res.string.rainfall_24h,
|
||||
)} ${MetricFormatter.rainfall(envMetrics.rainfall_24h!!)}",
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
fontSize = MaterialTheme.typography.labelLarge.fontSize,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.meshtastic.core.common.util.formatString
|
||||
import org.meshtastic.core.common.util.MetricFormatter
|
||||
import org.meshtastic.feature.settings.radio.ResponseState
|
||||
|
||||
private const val LOADING_OVERLAY_ALPHA = 0.8f
|
||||
|
|
@ -73,7 +73,7 @@ fun LoadingOverlay(state: ResponseState<*>, modifier: Modifier = Modifier) {
|
|||
trackColor = MaterialTheme.colorScheme.surfaceVariant,
|
||||
)
|
||||
Text(
|
||||
text = formatString("%.0f%%", progress * PERCENTAGE_FACTOR),
|
||||
text = MetricFormatter.percent(progress * PERCENTAGE_FACTOR, decimalPlaces = 0),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.Bold,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ import androidx.compose.ui.text.style.TextAlign
|
|||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.delay
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.common.util.formatString
|
||||
import org.meshtastic.core.common.util.MetricFormatter
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.cancel
|
||||
import org.meshtastic.core.resources.close
|
||||
|
|
@ -111,7 +111,7 @@ private fun LoadingContent(state: ResponseState.Loading, onComplete: () -> Unit)
|
|||
val progress by animateFloatAsState(targetValue = clampedProgress, label = "progress")
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Text(
|
||||
text = formatString("%.0f%%", progress * 100f),
|
||||
text = MetricFormatter.percent(progress * 100f, decimalPlaces = 0),
|
||||
style = MaterialTheme.typography.displaySmall,
|
||||
color = MaterialTheme.colorScheme.secondary,
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue