Weather: use null to indicate invalid values
This commit is contained in:
parent
065e6b828d
commit
3f7c2dbb8a
@ -249,18 +249,13 @@ fun CurrentWeather(forecast: Forecast, imperialUnits: Boolean) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val validHumidity = forecast.humidity != -1.0
|
|
||||||
val validWindDirection = forecast.windDirection != -1.0
|
|
||||||
val validWindSpeed = forecast.windSpeed != -1.0
|
|
||||||
val validPrecip = forecast.precipitation != -1.0
|
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(start = 16.dp, end = 16.dp, bottom = 12.dp, top = 8.dp)
|
.padding(start = 16.dp, end = 16.dp, bottom = 12.dp, top = 8.dp)
|
||||||
.fillMaxWidth(),
|
.fillMaxWidth(),
|
||||||
horizontalArrangement = Arrangement.SpaceBetween
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
) {
|
) {
|
||||||
if (validHumidity) {
|
if (forecast.humidity != null) {
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
@ -271,18 +266,18 @@ fun CurrentWeather(forecast: Forecast, imperialUnits: Boolean) {
|
|||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.padding(3.dp))
|
Spacer(modifier = Modifier.padding(3.dp))
|
||||||
Text(
|
Text(
|
||||||
text = "${forecast.humidity.roundToInt()} %",
|
text = "${forecast.humidity!!.roundToInt()} %",
|
||||||
style = MaterialTheme.typography.bodySmall
|
style = MaterialTheme.typography.bodySmall
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (validWindDirection || validWindSpeed) {
|
if (forecast.windDirection != null || forecast.windSpeed != null) {
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
if (validWindDirection) {
|
if (forecast.windDirection != null) {
|
||||||
// windDirection is "fromDirection"; Wind (arrow) blows into opposite direction
|
// windDirection is "fromDirection"; Wind (arrow) blows into opposite direction
|
||||||
val angle by animateFloatAsState(forecast.windDirection.toFloat() + 180f)
|
val angle by animateFloatAsState(forecast.windDirection!!.toFloat() + 180f)
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Rounded.North,
|
imageVector = Icons.Rounded.North,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@ -292,23 +287,23 @@ fun CurrentWeather(forecast: Forecast, imperialUnits: Boolean) {
|
|||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Rounded.WindPower,
|
imageVector = Icons.Rounded.Air,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
modifier = Modifier.size(20.dp)
|
modifier = Modifier.size(20.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.padding(3.dp))
|
Spacer(modifier = Modifier.padding(3.dp))
|
||||||
Text(
|
Text(
|
||||||
text = if (validWindSpeed) {
|
text = if (forecast.windSpeed != null) {
|
||||||
formatWindSpeed(imperialUnits, forecast)
|
formatWindSpeed(imperialUnits, forecast)
|
||||||
} else {
|
} else {
|
||||||
windDirectionAsWord(forecast.windDirection)
|
windDirectionAsWord(forecast.windDirection!!)
|
||||||
},
|
},
|
||||||
style = MaterialTheme.typography.bodySmall
|
style = MaterialTheme.typography.bodySmall
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (validPrecip) {
|
if (forecast.precipitation != null) {
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
@ -454,8 +449,9 @@ private fun convertTemperature(imperialUnits: Boolean, temp: Double): Int {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun formatWindSpeed(imperialUnits: Boolean, forecast: Forecast): String {
|
private fun formatWindSpeed(imperialUnits: Boolean, forecast: Forecast): String {
|
||||||
|
if (forecast.windSpeed == null) return ""
|
||||||
val formatter = DecimalFormat("0.#")
|
val formatter = DecimalFormat("0.#")
|
||||||
val speedValue = formatter.format(forecast.windSpeed * if (imperialUnits) 0.621371 else 1.0)
|
val speedValue = formatter.format(forecast.windSpeed!! * if (imperialUnits) 0.621371 else 1.0)
|
||||||
val speedUnit =
|
val speedUnit =
|
||||||
stringResource(id = if (imperialUnits) R.string.unit_mile_per_hour_symbol else R.string.unit_meter_per_second_symbol)
|
stringResource(id = if (imperialUnits) R.string.unit_mile_per_hour_symbol else R.string.unit_meter_per_second_symbol)
|
||||||
return "$speedValue $speedUnit"
|
return "$speedValue $speedUnit"
|
||||||
@ -463,6 +459,9 @@ private fun formatWindSpeed(imperialUnits: Boolean, forecast: Forecast): String
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun formatPrecipitation(imperialUnits: Boolean, forecast: Forecast): String {
|
private fun formatPrecipitation(imperialUnits: Boolean, forecast: Forecast): String {
|
||||||
|
if (forecast.precipProbability != null) {
|
||||||
|
return "${forecast.precipProbability} %"
|
||||||
|
}
|
||||||
val formatter = if (imperialUnits) DecimalFormat("#.##") else DecimalFormat("#.#")
|
val formatter = if (imperialUnits) DecimalFormat("#.##") else DecimalFormat("#.#")
|
||||||
val precipUnit =
|
val precipUnit =
|
||||||
if (imperialUnits) stringResource(id = R.string.unit_inch_symbol) else stringResource(id = R.string.unit_millimeter_symbol)
|
if (imperialUnits) stringResource(id = R.string.unit_inch_symbol) else stringResource(id = R.string.unit_millimeter_symbol)
|
||||||
|
|||||||
@ -28,13 +28,13 @@ data class Forecast(
|
|||||||
/** The temperature, in Kelvin **/
|
/** The temperature, in Kelvin **/
|
||||||
val temperature: Double,
|
val temperature: Double,
|
||||||
/** The min temperature, in Kelvin **/
|
/** The min temperature, in Kelvin **/
|
||||||
val minTemp: Double = -1.0,
|
val minTemp: Double? = null,
|
||||||
/** The max temperature, in Kelvin **/
|
/** The max temperature, in Kelvin **/
|
||||||
val maxTemp: Double = -1.0,
|
val maxTemp: Double? = null,
|
||||||
/** The temperature, in hPa **/
|
/** The temperature, in hPa **/
|
||||||
val pressure: Double = -1.0,
|
val pressure: Double? = null,
|
||||||
/** The temperature, in percent **/
|
/** The temperature, in percent **/
|
||||||
val humidity: Double = -1.0,
|
val humidity: Double? = null,
|
||||||
/** The icon, one of [NONE], [CLEAR], [CLOUDY], [COLD], [DRIZZLE], [HAZE], [FOG],
|
/** The icon, one of [NONE], [CLEAR], [CLOUDY], [COLD], [DRIZZLE], [HAZE], [FOG],
|
||||||
* [HAIL], [HEAVY_THUNDERSTORM], [HEAVY_THUNDERSTORM_WITH_RAIN], [HOT], [MOSTLY_CLOUDY],
|
* [HAIL], [HEAVY_THUNDERSTORM], [HEAVY_THUNDERSTORM_WITH_RAIN], [HOT], [MOSTLY_CLOUDY],
|
||||||
* [PARTLY_CLOUDY], [SHOWERS], [SLEET], [SNOW], [STORM], [THUNDERSTORM],
|
* [PARTLY_CLOUDY], [SHOWERS], [SLEET], [SNOW], [STORM], [THUNDERSTORM],
|
||||||
@ -43,13 +43,13 @@ data class Forecast(
|
|||||||
/** A text describing the current weather condition **/
|
/** A text describing the current weather condition **/
|
||||||
val condition: String,
|
val condition: String,
|
||||||
/** The clouds, percentage **/
|
/** The clouds, percentage **/
|
||||||
val clouds: Int = -1,
|
val clouds: Int? = null,
|
||||||
/** Wind speed, in m/s **/
|
/** Wind speed, in m/s **/
|
||||||
val windSpeed: Double = -1.0,
|
val windSpeed: Double? = null,
|
||||||
/** wind direction, in degrees **/
|
/** wind direction, in degrees **/
|
||||||
val windDirection: Double = -1.0,
|
val windDirection: Double? = null,
|
||||||
/** rain, in mm per hour **/
|
/** rain, in mm per hour **/
|
||||||
val precipitation: Double = -1.0,
|
val precipitation: Double? = null,
|
||||||
/** whether this forecast is during night time (whether a moon icon should be used instead of sun) **/
|
/** whether this forecast is during night time (whether a moon icon should be used instead of sun) **/
|
||||||
val night: Boolean = false,
|
val night: Boolean = false,
|
||||||
/** Location string **/
|
/** Location string **/
|
||||||
@ -58,31 +58,31 @@ data class Forecast(
|
|||||||
val provider: String,
|
val provider: String,
|
||||||
/** Url to the provider and more weather information **/
|
/** Url to the provider and more weather information **/
|
||||||
val providerUrl: String = "",
|
val providerUrl: String = "",
|
||||||
/** Rain probability, in percent [0..100]. -1 if not available **/
|
/** Rain probability, in percent [0..100]. null if not available **/
|
||||||
val precipProbability: Int = -1,
|
val precipProbability: Int? = null,
|
||||||
/** Timestamp (in millis) when when this forecast was created **/
|
/** Timestamp (in millis) when when this forecast was created **/
|
||||||
val updateTime: Long
|
val updateTime: Long
|
||||||
) {
|
) {
|
||||||
fun toDatabaseEntity(): ForecastEntity {
|
fun toDatabaseEntity(): ForecastEntity {
|
||||||
return ForecastEntity(
|
return ForecastEntity(
|
||||||
timestamp = timestamp,
|
timestamp = timestamp,
|
||||||
clouds = clouds,
|
clouds = clouds ?: -1,
|
||||||
condition = condition,
|
condition = condition,
|
||||||
humidity = humidity,
|
humidity = humidity ?: -1.0,
|
||||||
icon = icon,
|
icon = icon,
|
||||||
location = location,
|
location = location,
|
||||||
maxTemp = maxTemp,
|
maxTemp = maxTemp ?: -1.0,
|
||||||
minTemp = minTemp,
|
minTemp = minTemp ?: -1.0,
|
||||||
night = night,
|
night = night,
|
||||||
pressure = pressure,
|
pressure = pressure ?: -1.0,
|
||||||
provider = provider,
|
provider = provider,
|
||||||
providerUrl = providerUrl,
|
providerUrl = providerUrl,
|
||||||
precipitation = precipitation,
|
precipitation = precipitation ?: -1.0,
|
||||||
precipProbability = precipProbability,
|
precipProbability = precipProbability ?: -1,
|
||||||
temperature = temperature,
|
temperature = temperature,
|
||||||
updateTime = updateTime,
|
updateTime = updateTime,
|
||||||
windDirection = windDirection,
|
windDirection = windDirection ?: -1.0,
|
||||||
windSpeed = windSpeed,
|
windSpeed = windSpeed ?: -1.0,
|
||||||
snow = -1.0,
|
snow = -1.0,
|
||||||
snowProbability = -1
|
snowProbability = -1
|
||||||
)
|
)
|
||||||
@ -90,23 +90,23 @@ data class Forecast(
|
|||||||
|
|
||||||
constructor(entity: ForecastEntity) : this(
|
constructor(entity: ForecastEntity) : this(
|
||||||
timestamp = entity.timestamp,
|
timestamp = entity.timestamp,
|
||||||
clouds = entity.clouds,
|
clouds = entity.clouds.takeIf { it >= 0 },
|
||||||
condition = entity.condition,
|
condition = entity.condition,
|
||||||
humidity = entity.humidity,
|
humidity = entity.humidity.takeIf { it >= 0.0 },
|
||||||
icon = entity.icon,
|
icon = entity.icon,
|
||||||
location = entity.location,
|
location = entity.location,
|
||||||
maxTemp = entity.maxTemp,
|
maxTemp = entity.maxTemp.takeIf { it >= 0.0 },
|
||||||
minTemp = entity.minTemp,
|
minTemp = entity.minTemp.takeIf { it >= 0.0 },
|
||||||
night = entity.night,
|
night = entity.night,
|
||||||
pressure = entity.pressure,
|
pressure = entity.pressure.takeIf { it >= 0.0 },
|
||||||
provider = entity.provider,
|
provider = entity.provider,
|
||||||
providerUrl = entity.providerUrl,
|
providerUrl = entity.providerUrl,
|
||||||
precipitation = entity.precipitation,
|
precipitation = entity.precipitation.takeIf { it >= 0.0 },
|
||||||
precipProbability = entity.precipProbability,
|
precipProbability = entity.precipProbability.takeIf { it >= 0 },
|
||||||
temperature = entity.temperature,
|
temperature = entity.temperature,
|
||||||
updateTime = entity.updateTime,
|
updateTime = entity.updateTime,
|
||||||
windDirection = entity.windDirection,
|
windDirection = entity.windDirection.takeIf { it >= 0.0 },
|
||||||
windSpeed = entity.windSpeed
|
windSpeed = entity.windSpeed.takeIf { it >= 0.0 },
|
||||||
)
|
)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user