Different unit support, fixes #2

This commit is contained in:
Henry Hiles 2023-12-29 10:08:48 -05:00
parent 985382fa1b
commit ae71058669
23 changed files with 304 additions and 67 deletions

View file

@ -1,6 +1,7 @@
package com.henryhiles.qweather.di
import com.henryhiles.qweather.presentation.screenmodel.AppearancePreferenceManager
import com.henryhiles.qweather.presentation.screenmodel.UnitPreferenceManager
import com.henryhiles.qweather.presentation.screenmodel.LocationPreferenceManager
import org.koin.core.module.dsl.singleOf
@ -8,5 +9,6 @@ import org.koin.dsl.module
val managerModule = module {
singleOf(::AppearancePreferenceManager)
singleOf(::UnitPreferenceManager)
singleOf(::LocationPreferenceManager)
}

View file

@ -1,6 +1,7 @@
package com.henryhiles.qweather.di
import com.henryhiles.qweather.presentation.screenmodel.AppearancePreferencesScreenModel
import com.henryhiles.qweather.presentation.screenmodel.UnitPreferencesScreenModel
import com.henryhiles.qweather.presentation.screenmodel.DailyWeatherScreenModel
import com.henryhiles.qweather.presentation.screenmodel.HourlyWeatherScreenModel
import com.henryhiles.qweather.presentation.screenmodel.LocationPickerScreenModel
@ -9,6 +10,7 @@ import org.koin.dsl.module
val screenModelModule = module {
factoryOf(::AppearancePreferencesScreenModel)
factoryOf(::UnitPreferencesScreenModel)
factoryOf(::LocationPickerScreenModel)
factoryOf(::HourlyWeatherScreenModel)
factoryOf(::DailyWeatherScreenModel)

View file

@ -1,7 +1,9 @@
package com.henryhiles.qweather.domain.mappers
import com.henryhiles.qweather.domain.remote.DailyWeatherDataDto
import com.henryhiles.qweather.domain.remote.DailyWeatherUnitsDto
import com.henryhiles.qweather.domain.remote.HourlyWeatherDataDto
import com.henryhiles.qweather.domain.remote.HourlyWeatherUnitsDto
import com.henryhiles.qweather.domain.remote.WeatherDto
import com.henryhiles.qweather.domain.weather.DailyWeatherData
import com.henryhiles.qweather.domain.weather.HourlyWeatherData
@ -12,7 +14,7 @@ import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import kotlin.math.roundToInt
fun HourlyWeatherDataDto.toHourlyWeatherData(): List<HourlyWeatherData> {
fun HourlyWeatherDataDto.toHourlyWeatherData(units: HourlyWeatherUnitsDto): List<HourlyWeatherData> {
return time.subList(0, 24).mapIndexed { index, time ->
HourlyWeatherData(
time = LocalDateTime.parse(time, DateTimeFormatter.ISO_DATE_TIME),
@ -21,11 +23,12 @@ fun HourlyWeatherDataDto.toHourlyWeatherData(): List<HourlyWeatherData> {
windSpeed = windSpeed[index].roundToInt(),
precipitationProbability = precipitationProbability.getOrNull(index),
weatherType = WeatherType.fromWMO(weatherCode[index]),
units = units,
)
}
}
fun DailyWeatherDataDto.toDailyWeatherData(): List<DailyWeatherData> {
fun DailyWeatherDataDto.toDailyWeatherData(units: DailyWeatherUnitsDto): List<DailyWeatherData> {
return date.mapIndexed { index, date ->
DailyWeatherData(
date = LocalDate.parse(date, DateTimeFormatter.ISO_DATE),
@ -38,12 +41,17 @@ fun DailyWeatherDataDto.toDailyWeatherData(): List<DailyWeatherData> {
windSpeedMax = windSpeedMax[index].roundToInt(),
sunrise = LocalDateTime.parse(sunrise[index]),
sunset = LocalDateTime.parse(sunset[index]),
precipitationSum = precipitationSum[index],
units = units.copy(
precipitationSum = units.precipitationSum.replace("inch", "\""),
windSpeedMax = units.windSpeedMax.replace("mp/h", "mph"),
)
)
}
}
fun WeatherDto.toHourlyWeatherInfo(): HourlyWeatherInfo {
val weatherDataMap = hourlyWeatherData.toHourlyWeatherData()
val weatherDataMap = hourlyWeatherData.toHourlyWeatherData(units = hourlyUnits)
val now = LocalDateTime.now()
val currentWeatherData = weatherDataMap.find {
it.time.hour == now.hour

View file

@ -25,4 +25,21 @@ data class DailyWeatherDataDto(
val apparentTemperatureMax: List<Float>,
@SerialName("apparent_temperature_min")
val apparentTemperatureMin: List<Float>
)
@Serializable
data class DailyWeatherUnitsDto(
@SerialName("precipitation_probability_max")
val precipitationProbabilityMax: String,
@SerialName("precipitation_sum")
val precipitationSum: String,
@SerialName("windspeed_10m_max")
val windSpeedMax: String,
@SerialName("temperature_2m_max")
val temperatureMax: String,
@SerialName("temperature_2m_min")
val temperatureMin: String,
@SerialName("apparent_temperature_max")
val apparentTemperatureMax: String,
@SerialName("apparent_temperature_min")
val apparentTemperatureMin: String
)

View file

@ -16,4 +16,16 @@ data class HourlyWeatherDataDto(
val precipitationProbability: List<Int?>,
@SerialName("windspeed_10m")
val windSpeed: List<Float>,
)
@Serializable
data class HourlyWeatherUnitsDto(
@SerialName("temperature_2m")
val temperature: String,
@SerialName("apparent_temperature")
val apparentTemperature: String,
@SerialName("precipitation_probability")
val precipitationProbability: String,
@SerialName("windspeed_10m")
val windSpeed: String,
)

View file

@ -1,5 +1,7 @@
package com.henryhiles.qweather.domain.remote
import com.henryhiles.qweather.presentation.screenmodel.PrecipitationUnit
import com.henryhiles.qweather.presentation.screenmodel.TempUnit
import retrofit2.http.GET
import retrofit2.http.Headers
import retrofit2.http.Query
@ -17,6 +19,9 @@ interface WeatherApi {
suspend fun getWeatherData(
@Query("latitude") lat: Float,
@Query("longitude") long: Float,
@Query("temperature_unit") tempUnit: String,
@Query("wind_speed_unit") windUnit: String,
@Query("precipitation_unit") precipitationUnit: String,
): WeatherDto
@Headers("Cache-Control: no-cache")
@ -24,5 +29,8 @@ interface WeatherApi {
suspend fun getWeatherDataWithoutCache(
@Query("latitude") lat: Float,
@Query("longitude") long: Float,
@Query("temperature_unit") tempUnit: String,
@Query("wind_speed_unit") windUnit: String,
@Query("precipitation_unit") precipitationUnit: String,
): WeatherDto
}

View file

@ -8,6 +8,12 @@ data class WeatherDto(
@SerialName("hourly")
val hourlyWeatherData: HourlyWeatherDataDto,
@SerialName("hourly_units")
val hourlyUnits: HourlyWeatherUnitsDto,
@SerialName("daily")
val dailyWeatherData: DailyWeatherDataDto
val dailyWeatherData: DailyWeatherDataDto,
@SerialName("daily_units")
val dailyUnits: DailyWeatherUnitsDto,
)

View file

@ -1,28 +1,48 @@
package com.henryhiles.qweather.domain.repository
import androidx.compose.ui.text.toLowerCase
import com.henryhiles.qweather.domain.mappers.toDailyWeatherData
import com.henryhiles.qweather.domain.mappers.toHourlyWeatherInfo
import com.henryhiles.qweather.domain.remote.WeatherApi
import com.henryhiles.qweather.domain.remote.WeatherDto
import com.henryhiles.qweather.domain.util.Resource
import com.henryhiles.qweather.domain.weather.DailyWeatherData
import com.henryhiles.qweather.domain.weather.HourlyWeatherInfo
import com.henryhiles.qweather.presentation.screenmodel.UnitPreferenceManager
class WeatherRepository(private val api: WeatherApi) {
suspend fun getHourlyWeatherData(
private suspend fun getWeatherData(
lat: Float,
long: Float,
units: UnitPreferenceManager,
cache: Boolean = true,
): WeatherDto {
return if (cache) api.getWeatherData(
lat,
long,
units.tempUnit.name.lowercase(),
units.windUnit.name.lowercase(),
units.precipitationUnit.name.lowercase(),
) else api.getWeatherDataWithoutCache(
lat,
long,
units.tempUnit.name,
units.windUnit.name,
units.precipitationUnit.name,
)
}
suspend fun getDailyWeatherData(
lat: Float,
long: Float,
units: UnitPreferenceManager,
cache: Boolean = true
): Resource<HourlyWeatherInfo> {
): Resource<List<DailyWeatherData>> {
return try {
Resource.Success(
data = (
if (cache) api.getWeatherData(
lat = lat,
long = long
) else api.getWeatherDataWithoutCache(
lat = lat,
long = long
)).toHourlyWeatherInfo()
with(getWeatherData(lat, long, units, cache)) {
dailyWeatherData.toDailyWeatherData(dailyUnits)
}
)
} catch (e: Exception) {
e.printStackTrace()
@ -30,20 +50,15 @@ class WeatherRepository(private val api: WeatherApi) {
}
}
suspend fun getDailyWeatherData(
suspend fun getHourlyWeatherData(
lat: Float,
long: Float,
units: UnitPreferenceManager,
cache: Boolean = true
): Resource<List<DailyWeatherData>> {
): Resource<HourlyWeatherInfo> {
return try {
Resource.Success(
(if (cache) api.getWeatherData(
lat = lat,
long = long
) else api.getWeatherDataWithoutCache(
lat = lat,
long = long
)).dailyWeatherData.toDailyWeatherData()
getWeatherData(lat, long, units, cache).toHourlyWeatherInfo()
)
} catch (e: Exception) {
e.printStackTrace()

View file

@ -1,10 +1,12 @@
package com.henryhiles.qweather.domain.weather
import com.henryhiles.qweather.domain.remote.DailyWeatherUnitsDto
import java.time.LocalDate
import java.time.LocalDateTime
data class DailyWeatherData(
val date: LocalDate,
val precipitationSum: Float,
val weatherType: WeatherType,
val sunrise: LocalDateTime,
val sunset: LocalDateTime,
@ -13,5 +15,6 @@ data class DailyWeatherData(
val apparentTemperatureMax: Int,
val apparentTemperatureMin: Int,
val precipitationProbabilityMax: Int?,
val windSpeedMax: Int
val windSpeedMax: Int,
val units: DailyWeatherUnitsDto,
)

View file

@ -1,5 +1,6 @@
package com.henryhiles.qweather.domain.weather
import com.henryhiles.qweather.domain.remote.HourlyWeatherUnitsDto
import java.time.LocalDateTime
data class HourlyWeatherData(
@ -9,4 +10,5 @@ data class HourlyWeatherData(
val weatherType: WeatherType,
val precipitationProbability: Int?,
val windSpeed: Int,
val units: HourlyWeatherUnitsDto,
)

View file

@ -9,6 +9,7 @@ import androidx.compose.ui.Modifier
@Composable
inline fun <reified E : Enum<E>> SettingsItemChoice(
label: String,
secondaryLabel: String? = null,
title: String = label,
disabled: Boolean = false,
pref: E,
@ -23,6 +24,7 @@ inline fun <reified E : Enum<E>> SettingsItemChoice(
SettingItem(
modifier = Modifier.clickable { opened = true },
text = { Text(text = label) },
secondaryText = { if (secondaryLabel != null) Text(text = secondaryLabel) }
) {
SettingsChoiceDialog(
visible = opened,

View file

@ -15,15 +15,22 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.henryhiles.qweather.R
import com.henryhiles.qweather.domain.util.getIcon
import com.henryhiles.qweather.domain.weather.DailyWeatherData
import com.henryhiles.qweather.domain.weather.HourlyWeatherData
import java.time.format.DateTimeFormatter
@Composable
fun WeatherCard(hour: HourlyWeatherData, dailyData: DailyWeatherData, modifier: Modifier = Modifier) {
fun WeatherCard(
hour: HourlyWeatherData,
dailyData: DailyWeatherData,
modifier: Modifier = Modifier
) {
val formattedTime = remember(hour) {
hour.time.format(DateTimeFormatter.ofPattern("HH:mm"))
}
@ -48,14 +55,23 @@ fun WeatherCard(hour: HourlyWeatherData, dailyData: DailyWeatherData, modifier:
Spacer(modifier = Modifier.height(16.dp))
Image(
painter = painterResource(id = getIcon(hour, dailyData)),
contentDescription = "Image of ${hour.weatherType.weatherDesc}",
contentDescription = hour.weatherType.weatherDesc,
modifier = Modifier.height(140.dp),
contentScale = ContentScale.FillHeight
)
Spacer(modifier = Modifier.height(16.dp))
Text(text = "${hour.temperature}°C", fontSize = 50.sp)
Text(text = "${hour.temperature}${hour.units.temperature}", fontSize = 50.sp)
Spacer(modifier = Modifier.height(16.dp))
Text(text = "${hour.weatherType.weatherDesc} - Feels like ${hour.apparentTemperature}°C", fontSize = 20.sp)
Text(
text = stringResource(
id = R.string.weather_description,
hour.weatherType.weatherDesc,
hour.apparentTemperature,
hour.units.apparentTemperature
),
fontSize = 20.sp,
textAlign = TextAlign.Center,
)
Spacer(modifier = Modifier.height(32.dp))
Row(
modifier = Modifier.fillMaxWidth(),
@ -63,15 +79,15 @@ fun WeatherCard(hour: HourlyWeatherData, dailyData: DailyWeatherData, modifier:
) {
WeatherDataDisplay(
value = hour.precipitationProbability,
unit = "%",
unit = hour.units.precipitationProbability,
icon = Icons.Outlined.WaterDrop,
description = "Chance of precipitation"
description = stringResource(id = R.string.precipitation_probability)
)
WeatherDataDisplay(
value = hour.windSpeed,
unit = "km/h",
unit = hour.units.windSpeed,
icon = Icons.Outlined.WindPower,
description = "Wind Speed",
description = stringResource(id = R.string.wind_speed),
)
}
}

View file

@ -16,7 +16,7 @@ import com.henryhiles.qweather.R
@Composable
fun WeatherDataDisplay(
value: Int?,
value: Any?,
unit: String,
icon: ImageVector,
description: String,

View file

@ -16,8 +16,10 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.henryhiles.qweather.R
import com.henryhiles.qweather.domain.weather.DailyWeatherData
import java.time.format.DateTimeFormatter
@ -40,7 +42,7 @@ fun WeatherDay(dailyWeatherData: DailyWeatherData) {
) {
Image(
painter = painterResource(id = dailyWeatherData.weatherType.iconRes),
contentDescription = "Image of ${dailyWeatherData.weatherType.weatherDesc}",
contentDescription = dailyWeatherData.weatherType.weatherDesc,
modifier = Modifier.width(48.dp)
)
@ -50,12 +52,18 @@ fun WeatherDay(dailyWeatherData: DailyWeatherData) {
text = formattedDate,
fontWeight = FontWeight.Bold,
)
Text(text = "Feels like ${dailyWeatherData.apparentTemperatureMax}°C")
Text(
text = stringResource(
id = R.string.feels_like,
dailyWeatherData.apparentTemperatureMax,
dailyWeatherData.units.apparentTemperatureMax
)
)
}
Spacer(modifier = Modifier.weight(1f))
Text(
text = "${dailyWeatherData.temperatureMax}°C",
text = "${dailyWeatherData.temperatureMax}${dailyWeatherData.units.temperatureMax}",
style = MaterialTheme.typography.titleLarge,
)
}
@ -67,23 +75,21 @@ fun WeatherDay(dailyWeatherData: DailyWeatherData) {
) {
WeatherDataDisplay(
value = dailyWeatherData.precipitationProbabilityMax,
unit = "%",
unit = dailyWeatherData.units.precipitationProbabilityMax,
icon = Icons.Outlined.WaterDrop,
description = "Chance of rain"
description = stringResource(id = R.string.precipitation_probability)
)
Spacer(modifier = Modifier.width(16.dp))
WeatherDataDisplay(
value = dailyWeatherData.windSpeedMax,
unit = "mm",
value = dailyWeatherData.precipitationSum,
unit = dailyWeatherData.units.precipitationSum,
icon = Icons.Outlined.Water,
description = "Precipitation Amount"
description = stringResource(id = R.string.precipitation_amount)
)
Spacer(modifier = Modifier.width(16.dp))
WeatherDataDisplay(
value = dailyWeatherData.windSpeedMax,
unit = "km/h",
unit = dailyWeatherData.units.windSpeedMax,
icon = Icons.Outlined.WindPower,
description = "Wind Speed"
description = stringResource(id = R.string.wind_speed)
)
}
}

View file

@ -44,10 +44,10 @@ fun WeatherHour(
painter = painterResource(
id = getIcon(it, dailyData)
),
contentDescription = "Image of ${it.weatherType.weatherDesc}",
contentDescription = it.weatherType.weatherDesc,
modifier = Modifier.width(40.dp)
)
Text(text = "${it.temperature}°C")
Text(text = "${it.temperature}${it.units.temperature}")
}
}
}

View file

@ -46,19 +46,19 @@ fun WeatherToday(data: DailyWeatherData) {
) {
WeatherDataDisplay(
value = data.temperatureMax,
unit = "°C",
unit = data.units.temperatureMax,
icon = Icons.Default.ArrowUpward,
description = stringResource(R.string.weather_high, data.temperatureMax)
description = stringResource(R.string.weather_high, data.temperatureMax, data.units.temperatureMax)
)
WeatherDataDisplay(
value = data.temperatureMin,
unit = "°C",
unit = data.units.temperatureMin,
icon = Icons.Default.ArrowDownward,
description = stringResource(id = R.string.weather_low, data.temperatureMin)
description = stringResource(id = R.string.weather_low, data.temperatureMin, data.units.temperatureMin)
)
WeatherDataDisplay(
value = data.precipitationProbabilityMax,
unit = "%",
unit = data.units.precipitationProbabilityMax,
icon = Icons.Outlined.WaterDrop,
description = data.precipitationProbabilityMax?.let {
stringResource(

View file

@ -0,0 +1,60 @@
package com.henryhiles.qweather.presentation.screen
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.koin.getScreenModel
import com.henryhiles.qweather.R
import com.henryhiles.qweather.presentation.components.navigation.SmallToolbar
import com.henryhiles.qweather.presentation.components.settings.SettingsItemChoice
import com.henryhiles.qweather.presentation.screenmodel.UnitPreferencesScreenModel
class UnitsScreen : Screen {
@Composable
override fun Content(){
val screenModel: UnitPreferencesScreenModel = getScreenModel()
val context = LocalContext.current
Scaffold(topBar = {
SmallToolbar(
title = { Text(text = stringResource(R.string.settings_units)) },
backButton = true
)
}) { padding ->
Column(
modifier = Modifier
.padding(padding)
.verticalScroll(rememberScrollState())
) {
SettingsItemChoice(
label = stringResource(R.string.unit_temp),
secondaryLabel = stringResource(R.string.unit_temp_desc),
pref = screenModel.prefs.tempUnit,
labelFactory = { context.getString(it.label) }
) { screenModel.prefs.tempUnit = it }
SettingsItemChoice(
label = stringResource(R.string.unit_wind),
secondaryLabel = stringResource(R.string.unit_wind_desc),
pref = screenModel.prefs.windUnit,
labelFactory = { context.getString(it.label) }
) { screenModel.prefs.windUnit = it }
SettingsItemChoice(
label = stringResource(R.string.unit_precipitation),
secondaryLabel = stringResource(R.string.unit_precipitation_desc),
pref = screenModel.prefs.precipitationUnit,
labelFactory = { context.getString(it.label) }
) { screenModel.prefs.precipitationUnit = it }
}
}
}
}

View file

@ -19,7 +19,8 @@ data class DailyWeatherState(
class DailyWeatherScreenModel(
private val repository: WeatherRepository,
val locationPreferenceManager: LocationPreferenceManager
private val unitsPreferenceManager: UnitPreferenceManager,
val locationPreferenceManager: LocationPreferenceManager,
) : ScreenModel {
var state by mutableStateOf(DailyWeatherState())
private set
@ -31,7 +32,8 @@ class DailyWeatherScreenModel(
state = when (val result = repository.getDailyWeatherData(
lat = location.latitude,
long = location.longitude,
cache = cache
cache = cache,
units = unitsPreferenceManager,
)) {
is Resource.Success -> {
state.copy(

View file

@ -19,6 +19,7 @@ data class HourlyWeatherState(
class HourlyWeatherScreenModel(
private val repository: WeatherRepository,
private val unitsPreferenceManager: UnitPreferenceManager,
val locationPreferenceManager: LocationPreferenceManager,
) : ScreenModel {
var state by mutableStateOf(HourlyWeatherState())
@ -32,6 +33,7 @@ class HourlyWeatherScreenModel(
repository.getHourlyWeatherData(
lat = location.latitude,
long = location.longitude,
units = unitsPreferenceManager,
cache = cache
)) {
is Resource.Success -> {

View file

@ -0,0 +1,36 @@
package com.henryhiles.qweather.presentation.screenmodel
import android.content.Context
import androidx.annotation.StringRes
import cafe.adriel.voyager.core.model.ScreenModel
import com.henryhiles.qweather.R
import com.henryhiles.qweather.domain.manager.BasePreferenceManager
class UnitPreferenceManager(context: Context) :
BasePreferenceManager(context.getSharedPreferences("prefs", Context.MODE_PRIVATE)) {
var tempUnit by enumPreference("temp_unit", TempUnit.CELSIUS)
var windUnit by enumPreference("wind_unit", WindUnit.KMH)
var precipitationUnit by enumPreference("precipitation_unit", PrecipitationUnit.MM)
}
enum class TempUnit(@StringRes val label: Int) {
CELSIUS(R.string.celsius),
FAHRENHEIT(R.string.fahrenheit),
}
enum class WindUnit(@StringRes val label: Int) {
KMH(R.string.kmh),
MS(R.string.ms),
MPH(R.string.mph),
KN(R.string.kn),
}
enum class PrecipitationUnit(@StringRes val label: Int) {
MM(R.string.mm),
INCH(R.string.inch)
}
class UnitPreferencesScreenModel(
val prefs: UnitPreferenceManager
) : ScreenModel

View file

@ -3,6 +3,7 @@ package com.henryhiles.qweather.presentation.tabs
import androidx.compose.foundation.layout.Column
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.outlined.AcUnit
import androidx.compose.material.icons.outlined.GpsFixed
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material.icons.outlined.Palette
@ -20,6 +21,7 @@ import com.henryhiles.qweather.presentation.components.settings.SettingsCategory
import com.henryhiles.qweather.presentation.screen.AboutScreen
import com.henryhiles.qweather.presentation.screen.AppearanceSettingsScreen
import com.henryhiles.qweather.presentation.screen.LocationPickerScreen
import com.henryhiles.qweather.presentation.screen.UnitsScreen
object SettingsTab : NavigationTab {
override val options: TabOptions
@ -52,6 +54,12 @@ object SettingsTab : NavigationTab {
subtext = stringResource(R.string.settings_location_description),
destination = ::LocationPickerScreen
)
SettingsCategory(
icon = Icons.Outlined.AcUnit,
text = stringResource(R.string.settings_units),
subtext = stringResource(R.string.settings_units_description),
destination = ::UnitsScreen
)
}
}

View file

@ -46,15 +46,15 @@ object WeekTab : NavigationTab {
@Composable
override fun Content() {
val dailyWeatherViewModel = getScreenModel<DailyWeatherScreenModel>()
val weatherViewModel = getScreenModel<DailyWeatherScreenModel>()
LaunchedEffect(key1 = dailyWeatherViewModel.locationPreferenceManager.selectedIndex) {
dailyWeatherViewModel.loadWeatherInfo()
LaunchedEffect(key1 = weatherViewModel.locationPreferenceManager.selectedIndex) {
weatherViewModel.loadWeatherInfo()
}
Box(modifier = Modifier.fillMaxSize()) {
when {
dailyWeatherViewModel.state.isLoading -> {
weatherViewModel.state.isLoading -> {
CircularProgressIndicator(
modifier = Modifier.align(
Alignment.Center
@ -62,15 +62,19 @@ object WeekTab : NavigationTab {
)
}
dailyWeatherViewModel.state.error != null -> {
weatherViewModel.state.error != null -> {
AlertDialog(
onDismissRequest = {},
confirmButton = {},
title = { Text(text = stringResource(R.string.error)) },
confirmButton = {
TextButton(onClick = { weatherViewModel.loadWeatherInfo() }) {
Text(text = stringResource(id = R.string.action_try_again))
}
},
title = { Text(text = stringResource(id = R.string.error)) },
text = {
SelectionContainer {
Text(
text = dailyWeatherViewModel.state.error!!,
text = weatherViewModel.state.error!!,
)
}
},
@ -79,7 +83,7 @@ object WeekTab : NavigationTab {
else -> {
LazyColumn(contentPadding = PaddingValues(16.dp)) {
dailyWeatherViewModel.state.dailyWeatherData?.let { data ->
weatherViewModel.state.dailyWeatherData?.let { data ->
item { WeatherToday(data = data[0]) }
items(data) {
Spacer(modifier = Modifier.height(16.dp))
@ -94,10 +98,10 @@ object WeekTab : NavigationTab {
@Composable
override fun Actions() {
val dailyWeatherViewModel = getScreenModel<DailyWeatherScreenModel>()
val weatherViewModel = getScreenModel<DailyWeatherScreenModel>()
IconButton(onClick = {
dailyWeatherViewModel.loadWeatherInfo(cache = false)
weatherViewModel.loadWeatherInfo(cache = false)
}) {
Icon(
imageVector = Icons.Filled.Refresh,

View file

@ -23,6 +23,8 @@
<string name="settings_appearance_description">Theme, dynamic colors</string>
<string name="settings_location">Location</string>
<string name="settings_location_description">Location to fetch data from</string>
<string name="settings_units">Units</string>
<string name="settings_units_description">Units to fetch data in, e.g. imperial/metric</string>
<string name="location">Location</string>
<string name="locations">Locations</string>
@ -34,9 +36,33 @@
<string name="theme_light">Light</string>
<string name="theme_dark">Dark</string>
<string name="weather_high">High: %1$d°C</string>
<string name="weather_low">Low: %1$d°C</string>
<string name="unit_temp">Temperature Unit</string>
<string name="celsius">Celsius (C°)</string>
<string name="fahrenheit">Fahrenheit (F°)</string>
<string name="unit_temp_desc">Celsius, Fahrenheit</string>
<string name="unit_wind">Wind Speed Unit</string>
<string name="kmh">Kilometers per Hour (km/h)</string>
<string name="ms">Meters per second (m/s)</string>
<string name="mph">Miles per hour (mph)</string>
<string name="kn">Knots (kn)</string>
<string name="unit_wind_desc">Km/h, m/s, Mph, Knots</string>
<string name="unit_precipitation">Precipitation Unit</string>
<string name="mm">Millimeters (mm)</string>
<string name="inch">Inches (in)</string>
<string name="unit_precipitation_desc">Millimeters, Inches</string>
<string name="weather_high">High: %1$d%2$s</string>
<string name="weather_low">Low: %1$d%2$s</string>
<string name="feels_like">Feels like %1$d%2$s</string>
<string name="weather_precipitation">Precipitation: %1$d&#65130;</string>
<string name="weather_description">%1$s - Feels like %2$d%3$s</string>
<string name="precipitation_probability">Precipitation Probability</string>
<string name="precipitation_amount">Precipitation Amount</string>
<string name="wind_speed">Wind Speed</string>
<string name="today_in">Today in %1$s</string>