diff --git a/app/src/main/java/dev/hossain/weatheralert/notification/Notification.kt b/app/src/main/java/dev/hossain/weatheralert/notification/Notification.kt index 2a11ba2b..6df45268 100644 --- a/app/src/main/java/dev/hossain/weatheralert/notification/Notification.kt +++ b/app/src/main/java/dev/hossain/weatheralert/notification/Notification.kt @@ -8,6 +8,7 @@ import android.graphics.drawable.Icon import androidx.core.app.NotificationCompat import dev.hossain.weatheralert.R import dev.hossain.weatheralert.data.WeatherAlertCategory +import dev.hossain.weatheralert.util.formatUnit import dev.hossain.weatheralert.util.stripMarkdownSyntax import timber.log.Timber @@ -46,10 +47,10 @@ internal fun triggerNotification( append("About ") when (alertCategory) { WeatherAlertCategory.SNOW_FALL -> { - append("$currentValue cm snowfall expected.") + append("${currentValue.formatUnit(WeatherAlertCategory.SNOW_FALL.unit)} snowfall expected.") } WeatherAlertCategory.RAIN_FALL -> { - append("$currentValue mm rainfall expected.") + append("${currentValue.formatUnit(WeatherAlertCategory.RAIN_FALL.unit)} rainfall expected.") } } } @@ -60,13 +61,19 @@ internal fun triggerNotification( when (alertCategory) { WeatherAlertCategory.SNOW_FALL -> { append( - "$cityName is forecasted to receive $currentValue cm of snowfall within the next 24 hours, surpassing your configured threshold of $thresholdValue cm.", + "$cityName is forecasted to receive ${currentValue.formatUnit( + WeatherAlertCategory.SNOW_FALL.unit, + )} of snowfall within the next 24 hours, ", ) + append("surpassing your configured threshold of ${thresholdValue.formatUnit(WeatherAlertCategory.SNOW_FALL.unit)}.") } WeatherAlertCategory.RAIN_FALL -> { append( - "$cityName is forecasted to receive $currentValue mm of rainfall within the next 24 hours, surpassing your configured threshold of $thresholdValue mm.", + "$cityName is forecasted to receive ${currentValue.formatUnit( + WeatherAlertCategory.RAIN_FALL.unit, + )} of rainfall within the next 24 hours, ", ) + append("surpassing your configured threshold of ${thresholdValue.formatUnit(WeatherAlertCategory.RAIN_FALL.unit)}.") } } if (reminderNotes.isNotBlank()) { diff --git a/app/src/main/java/dev/hossain/weatheralert/ui/alertslist/CurrentAlertScreen.kt b/app/src/main/java/dev/hossain/weatheralert/ui/alertslist/CurrentAlertScreen.kt index f4ff608d..7f3e426c 100644 --- a/app/src/main/java/dev/hossain/weatheralert/ui/alertslist/CurrentAlertScreen.kt +++ b/app/src/main/java/dev/hossain/weatheralert/ui/alertslist/CurrentAlertScreen.kt @@ -89,11 +89,11 @@ import dev.hossain.weatheralert.di.AppScope import dev.hossain.weatheralert.network.NetworkMonitor import dev.hossain.weatheralert.ui.addalert.AlertSettingsScreen import dev.hossain.weatheralert.ui.theme.WeatherAlertAppTheme +import dev.hossain.weatheralert.util.formatUnit import dev.hossain.weatheralert.util.parseMarkdown import kotlinx.coroutines.launch import kotlinx.parcelize.Parcelize import timber.log.Timber -import java.util.Locale @Parcelize data class CurrentWeatherAlertScreen( @@ -160,22 +160,13 @@ class CurrentWeatherAlertPresenter lat = alert.city.lat, lon = alert.city.lng, category = alert.alert.alertCategory, - threshold = - "%.2f %s".format( - Locale.getDefault(), - alert.alert.threshold, - alert.alert.alertCategory.unit, - ), + threshold = alert.alert.threshold.formatUnit(alert.alert.alertCategory.unit), currentStatus = - "%.2f %s".format( - Locale.getDefault(), - if (alert.alert.alertCategory == WeatherAlertCategory.SNOW_FALL) { - snowStatus - } else { - rainStatus - }, - alert.alert.alertCategory.unit, - ), + if (alert.alert.alertCategory == WeatherAlertCategory.SNOW_FALL) { + snowStatus.formatUnit(alert.alert.alertCategory.unit) + } else { + rainStatus.formatUnit(alert.alert.alertCategory.unit) + }, isAlertActive = when (alert.alert.alertCategory) { WeatherAlertCategory.SNOW_FALL -> snowStatus > alert.alert.threshold @@ -673,7 +664,7 @@ fun CurrentWeatherAlertsPreview() { threshold = "10 mm", currentStatus = "Tomorrow: 12 mm", isAlertActive = true, - alertNote = "test note", + alertNote = "Note when alert is reached.\n* Charge batteries\n* Get car in **garage**", ), ) CurrentWeatherAlerts(CurrentWeatherAlertScreen.State(sampleTiles) {}) diff --git a/app/src/main/java/dev/hossain/weatheralert/util/HttpPingSender.kt b/app/src/main/java/dev/hossain/weatheralert/util/HttpPingSender.kt index b0fee212..673f3d3b 100644 --- a/app/src/main/java/dev/hossain/weatheralert/util/HttpPingSender.kt +++ b/app/src/main/java/dev/hossain/weatheralert/util/HttpPingSender.kt @@ -35,9 +35,9 @@ class HttpPingSender( val versionName = packageInfo.versionName // Add user agent with app name, version, and device info - // Example: `KA/1.6 (Android 14, API 34, samsung SM-S911W)` + // Example: `WAlert/1.6 (Android 14, API 34, samsung SM-S911W) [Alerts:3]` val userAgent = - "KA/$versionName (Android ${android.os.Build.VERSION.RELEASE}, " + + "WAlert/$versionName (Android ${android.os.Build.VERSION.RELEASE}, " + "API ${android.os.Build.VERSION.SDK_INT}, ${android.os.Build.MANUFACTURER} " + "${android.os.Build.MODEL}) $extraMessage" diff --git a/app/src/main/java/dev/hossain/weatheralert/util/TextFormatter.kt b/app/src/main/java/dev/hossain/weatheralert/util/TextFormatter.kt new file mode 100644 index 00000000..b34d1d88 --- /dev/null +++ b/app/src/main/java/dev/hossain/weatheralert/util/TextFormatter.kt @@ -0,0 +1,13 @@ +package dev.hossain.weatheralert.util + +import java.util.Locale + +/** + * Formats 2.440923834343 to 2.44 cm + */ +internal fun Float.formatUnit(unit: String): String = "%.2f %s".format(Locale.getDefault(), this, unit) + +/** + * Formats 8.98237320 to 8.98 mm + */ +internal fun Double.formatUnit(unit: String): String = "%.2f %s".format(Locale.getDefault(), this, unit) diff --git a/app/src/test/java/dev/hossain/weatheralert/util/TextFormatterTest.kt b/app/src/test/java/dev/hossain/weatheralert/util/TextFormatterTest.kt new file mode 100644 index 00000000..d317fda4 --- /dev/null +++ b/app/src/test/java/dev/hossain/weatheralert/util/TextFormatterTest.kt @@ -0,0 +1,70 @@ +package dev.hossain.weatheralert.util + +import org.junit.Assert.assertEquals +import org.junit.Test + +class TextFormatterTest { + @Test + fun formatUnit_handlesFloatValue() { + val value = 2.440923834343f + val unit = "cm" + val expected = "2.44 cm" + assertEquals(expected, value.formatUnit(unit)) + } + + @Test + fun formatUnit_handlesDoubleValue() { + val value = 8.98237320 + val unit = "mm" + val expected = "8.98 mm" + assertEquals(expected, value.formatUnit(unit)) + } + + @Test + fun formatUnit_handlesZeroFloatValue() { + val value = 0.0f + val unit = "cm" + val expected = "0.00 cm" + assertEquals(expected, value.formatUnit(unit)) + } + + @Test + fun formatUnit_handlesZeroDoubleValue() { + val value = 0.0 + val unit = "mm" + val expected = "0.00 mm" + assertEquals(expected, value.formatUnit(unit)) + } + + @Test + fun formatUnit_handlesNegativeFloatValue() { + val value = -2.440923834343f + val unit = "cm" + val expected = "-2.44 cm" + assertEquals(expected, value.formatUnit(unit)) + } + + @Test + fun formatUnit_handlesNegativeDoubleValue() { + val value = -8.98237320 + val unit = "mm" + val expected = "-8.98 mm" + assertEquals(expected, value.formatUnit(unit)) + } + + @Test + fun formatUnit_handlesLargeFloatValue() { + val value = 123456.78923f + val unit = "cm" + val expected = "123456.79 cm" + assertEquals(expected, value.formatUnit(unit)) + } + + @Test + fun formatUnit_handlesLargeDoubleValue() { + val value = 987654.321 + val unit = "mm" + val expected = "987654.32 mm" + assertEquals(expected, value.formatUnit(unit)) + } +}