Weather widget: select current time on resume

This commit is contained in:
MM20 2022-07-05 22:34:49 +02:00
parent 9e6a1cde3c
commit 109271947d
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
2 changed files with 47 additions and 0 deletions

View File

@ -20,11 +20,14 @@ import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.ktx.tryStartActivity import de.mm20.launcher2.ktx.tryStartActivity
import de.mm20.launcher2.ui.R import de.mm20.launcher2.ui.R
@ -44,6 +47,13 @@ fun WeatherWidget() {
val viewModel: WeatherWidgetWM = viewModel() val viewModel: WeatherWidgetWM = viewModel()
val context = LocalContext.current val context = LocalContext.current
val lifecycleOwner = LocalLifecycleOwner.current
LaunchedEffect(null) {
lifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
viewModel.selectNow()
}
}
val selectedForecast by viewModel.currentForecast.observeAsState() val selectedForecast by viewModel.currentForecast.observeAsState()

View File

@ -13,6 +13,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent import org.koin.core.component.KoinComponent
import org.koin.core.component.inject import org.koin.core.component.inject
import kotlin.math.max
import kotlin.math.min import kotlin.math.min
class WeatherWidgetWM : ViewModel(), KoinComponent { class WeatherWidgetWM : ViewModel(), KoinComponent {
@ -22,6 +23,9 @@ class WeatherWidgetWM : ViewModel(), KoinComponent {
private val dataStore: LauncherDataStore by inject() private val dataStore: LauncherDataStore by inject()
/**
* Index of the currently selected day in [dailyForecasts]
*/
private var selectedDayIndex = 0 private var selectedDayIndex = 0
set(value) { set(value) {
field = min(value, forecasts.lastIndex) field = min(value, forecasts.lastIndex)
@ -38,6 +42,9 @@ class WeatherWidgetWM : ViewModel(), KoinComponent {
currentForecast.postValue(getCurrentlySelectedForecast()) currentForecast.postValue(getCurrentlySelectedForecast())
} }
/**
* Index of the currently selected forecast in [currentDayForecasts]
*/
private var selectedForecastIndex = 0 private var selectedForecastIndex = 0
set(value) { set(value) {
if (selectedDayIndex < 0) { if (selectedDayIndex < 0) {
@ -50,6 +57,9 @@ class WeatherWidgetWM : ViewModel(), KoinComponent {
private val forecastsFlow = weatherRepository.forecasts private val forecastsFlow = weatherRepository.forecasts
/**
* All available forecasts, grouped by day
*/
private var forecasts: List<DailyForecast> = emptyList() private var forecasts: List<DailyForecast> = emptyList()
set(value) { set(value) {
field = value field = value
@ -58,15 +68,32 @@ class WeatherWidgetWM : ViewModel(), KoinComponent {
dailyForecasts.postValue(value) dailyForecasts.postValue(value)
} }
/**
* Currently selected forecast, one of [currentDayForecasts]
*/
val currentForecast = MutableLiveData<Forecast?>(getCurrentlySelectedForecast()) val currentForecast = MutableLiveData<Forecast?>(getCurrentlySelectedForecast())
/**
* List of forecast summaries for each day
*/
val dailyForecasts = MutableLiveData<List<DailyForecast>>(emptyList()) val dailyForecasts = MutableLiveData<List<DailyForecast>>(emptyList())
/**
* Forecasts of the currently selected day (hourly in most cases).
* This is [DailyForecast.hourlyForecasts] of [currentDailyForecast]
*/
val currentDayForecasts = MutableLiveData<List<Forecast>>(emptyList()) val currentDayForecasts = MutableLiveData<List<Forecast>>(emptyList())
/**
* Daily forecast summary for the currently selected day, one of [dailyForecasts] or null
*/
val currentDailyForecast = MutableLiveData<DailyForecast>(null) val currentDailyForecast = MutableLiveData<DailyForecast>(null)
init { init {
viewModelScope.launch { viewModelScope.launch {
forecastsFlow.collectLatest { forecastsFlow.collectLatest {
forecasts = it forecasts = it
selectNow()
} }
} }
} }
@ -90,4 +117,14 @@ class WeatherWidgetWM : ViewModel(), KoinComponent {
private fun getCurrentlySelectedForecast(): Forecast? { private fun getCurrentlySelectedForecast(): Forecast? {
return forecasts.getOrNull(selectedDayIndex)?.hourlyForecasts?.getOrNull(selectedForecastIndex) return forecasts.getOrNull(selectedDayIndex)?.hourlyForecasts?.getOrNull(selectedForecastIndex)
} }
fun selectNow() {
if (forecasts.isEmpty()) return
val now = System.currentTimeMillis()
val dayIndex = max(0, forecasts.indexOfLast { it.timestamp < now })
val day = forecasts[dayIndex]
val forecastIndex = max(0, day.hourlyForecasts.indexOfLast { it.timestamp < now })
selectDay(dayIndex)
selectForecast(forecastIndex)
}
} }