diff --git a/app/src/main/java/com/matedroid/domain/model/UnitFormatter.kt b/app/src/main/java/com/matedroid/domain/model/UnitFormatter.kt index dfbe7fa9..83140584 100644 --- a/app/src/main/java/com/matedroid/domain/model/UnitFormatter.kt +++ b/app/src/main/java/com/matedroid/domain/model/UnitFormatter.kt @@ -9,9 +9,38 @@ import com.matedroid.data.api.models.Units * IMPORTANT: TeslamateAPI already returns all values pre-converted to the user's preferred * unit system. Do NOT apply any conversion here — just format the number and attach the * correct unit label. + * + * Exception: elevation units. We need implement the conversion here until API/Teslamate do itself */ object UnitFormatter { + /** + * Format elevation value with appropriate unit label. + * Value is also converted here as the API do not convert to ft when user select mi instead of km. + */ + fun formatElevation(value: Int?, units: Units?): String { + val v = value ?: 0 + return if (units?.isImperial == true) { + "%,d ft".format((v * 3.28084).toInt()) + } else { + "%,d m".format(v) + } + } + + /** + * Get the elevation value + */ + fun getElevationValue(value: Float, units: Units?): Float { + return if (units?.isImperial == true) (value * 3.28084f) else value + } + + /** + * Get the elevation unit label + */ + fun getElevationUnit(units: Units?): String { + return if (units?.isImperial == true) "ft" else "m" + } + /** * Format distance value with appropriate unit label. * Value is already in km (metric) or mi (imperial) as returned by the API. diff --git a/app/src/main/java/com/matedroid/ui/screens/dashboard/DashboardScreen.kt b/app/src/main/java/com/matedroid/ui/screens/dashboard/DashboardScreen.kt index 85a70982..1d11d1d3 100644 --- a/app/src/main/java/com/matedroid/ui/screens/dashboard/DashboardScreen.kt +++ b/app/src/main/java/com/matedroid/ui/screens/dashboard/DashboardScreen.kt @@ -127,9 +127,9 @@ import com.matedroid.data.api.models.CarExterior import com.matedroid.data.api.models.CarGeodata import com.matedroid.data.api.models.CarStatus import com.matedroid.domain.model.CarImageResolver +import com.matedroid.domain.model.UnitFormatter import com.matedroid.data.api.models.CarStatusDetails import com.matedroid.data.api.models.Units -import com.matedroid.domain.model.UnitFormatter import com.matedroid.data.api.models.CarVersions import com.matedroid.data.api.models.ChargingDetails import com.matedroid.data.api.models.TpmsDetails @@ -1544,17 +1544,6 @@ private fun LocationCard(status: CarStatus, units: Units?, resolvedAddress: Stri } } - // Format elevation with unit conversion - val elevationText = elevation?.let { - val isImperial = units?.unitOfLength == "mi" - if (isImperial) { - val feet = (it * 3.28084).toInt() - "%,d ft".format(feet) - } else { - "%,d m".format(it) - } - } - fun openInMaps() { if (latitude != null && longitude != null) { val geoUri = Uri.parse("geo:$latitude,$longitude?q=$latitude,$longitude") @@ -1615,13 +1604,13 @@ private fun LocationCard(status: CarStatus, units: Units?, resolvedAddress: Stri } // Elevation row - icon aligned with location icon, text aligned with location text - if (elevationText != null) { + if (elevation != null) { Spacer(modifier = Modifier.height(8.dp)) Row(verticalAlignment = Alignment.CenterVertically) { Icon( imageVector = Icons.Filled.Terrain, contentDescription = null, - tint = palette.onSurfaceVariant + tint = palette.accent ) Spacer(modifier = Modifier.width(12.dp)) Text( @@ -1631,7 +1620,7 @@ private fun LocationCard(status: CarStatus, units: Units?, resolvedAddress: Stri ) Spacer(modifier = Modifier.width(8.dp)) Text( - text = elevationText, + text = UnitFormatter.formatElevation(elevation, units), style = MaterialTheme.typography.bodyMedium, color = palette.onSurface, maxLines = 1, diff --git a/app/src/main/java/com/matedroid/ui/screens/drives/DriveDetailScreen.kt b/app/src/main/java/com/matedroid/ui/screens/drives/DriveDetailScreen.kt index 52e1310f..7b8f0e6c 100644 --- a/app/src/main/java/com/matedroid/ui/screens/drives/DriveDetailScreen.kt +++ b/app/src/main/java/com/matedroid/ui/screens/drives/DriveDetailScreen.kt @@ -247,10 +247,10 @@ private fun DriveDetailContent( title = stringResource(R.string.elevation), icon = Icons.Default.Landscape, stats = listOf( - StatItem(stringResource(R.string.maximum), "%,d m".format(s.elevationMax)), - StatItem(stringResource(R.string.minimum), "%,d m".format(s.elevationMin)), - StatItem(stringResource(R.string.gain), "+%,d m".format(s.elevationGain)), - StatItem(stringResource(R.string.loss), "-%,d m".format(s.elevationLoss)) + StatItem(stringResource(R.string.maximum), UnitFormatter.formatElevation(s.elevationMax, units)), + StatItem(stringResource(R.string.minimum), UnitFormatter.formatElevation(s.elevationMin, units)), + StatItem(stringResource(R.string.gain), "+" + UnitFormatter.formatElevation(s.elevationGain, units)), + StatItem(stringResource(R.string.loss), "-" + UnitFormatter.formatElevation(s.elevationLoss, units)), ) ) } @@ -312,6 +312,7 @@ private fun DriveDetailContent( if (detail.positions.any { it.elevation != null && it.elevation != 0 }) { ElevationChartCard( positions = detail.positions, + units = units, timeLabels = timeLabels, externalSelectedFraction = sharedXFraction, onXSelected = { sharedXFraction = it }, @@ -745,6 +746,7 @@ private fun BatteryChartCard( @Composable private fun ElevationChartCard( positions: List, + units: Units?, timeLabels: List, externalSelectedFraction: Float? = null, onXSelected: ((Float?) -> Unit)? = null, @@ -758,11 +760,12 @@ private fun ElevationChartCard( icon = Icons.Default.Landscape, data = elevations, color = Color(0xFF8B4513), // Brown color for terrain - unit = "m", + unit = UnitFormatter.getElevationUnit(units), timeLabels = timeLabels, externalSelectedFraction = externalSelectedFraction, onXSelected = onXSelected, - fractionToTimeLabel = fractionToTimeLabel + fractionToTimeLabel = fractionToTimeLabel, + convertValue = { UnitFormatter.getElevationValue(it, units) } ) } diff --git a/app/src/main/java/com/matedroid/ui/screens/stats/StatsScreen.kt b/app/src/main/java/com/matedroid/ui/screens/stats/StatsScreen.kt index a9369e99..ba668c23 100644 --- a/app/src/main/java/com/matedroid/ui/screens/stats/StatsScreen.kt +++ b/app/src/main/java/com/matedroid/ui/screens/stats/StatsScreen.kt @@ -844,10 +844,10 @@ private fun RecordsCard( // Category 3: Weather & Altitude val weatherRecords = mutableListOf() deepStats?.driveWithMaxElevation?.let { record -> - weatherRecords.add(RecordData("🏔️", labelHighestPoint, "%,d m".format(record.elevationM), record.date?.take(10) ?: "") { onDriveClick(record.driveId) }) + weatherRecords.add(RecordData("🏔️", labelHighestPoint, UnitFormatter.formatElevation(record.elevationM, units), record.date?.take(10) ?: "") { onDriveClick(record.driveId) }) } deepStats?.driveWithMostClimbing?.let { record -> - weatherRecords.add(RecordData("⛰️", labelMostClimbing, record.elevationGainM?.let { "+%,d m".format(it) } ?: "N/A", record.date?.take(10) ?: "") { onDriveClick(record.driveId) }) + weatherRecords.add(RecordData("⛰️", labelMostClimbing, record.elevationGainM?.let { "+" + UnitFormatter.formatElevation(it, units) } ?: "N/A", record.date?.take(10) ?: "") { onDriveClick(record.driveId) }) } deepStats?.hottestDrive?.let { record -> weatherRecords.add(RecordData("🌡️", labelHottestDrive, UnitFormatter.formatTemperature(record.tempC, units, 1), record.date?.take(10) ?: "") { onDriveClick(record.driveId) })