From 109271947d342a9f03c63bf9f9a62fffea5a7694 Mon Sep 17 00:00:00 2001 From: MM20 <15646950+MM2-0@users.noreply.github.com> Date: Tue, 5 Jul 2022 22:34:49 +0200 Subject: [PATCH] Weather widget: select current time on resume --- .../launcher/widgets/weather/WeatherWidget.kt | 10 +++++ .../widgets/weather/WeatherWidgetWM.kt | 37 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/weather/WeatherWidget.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/weather/WeatherWidget.kt index ac2e4bd8..0103f187 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/weather/WeatherWidget.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/weather/WeatherWidget.kt @@ -20,11 +20,14 @@ import androidx.compose.runtime.livedata.observeAsState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.repeatOnLifecycle import androidx.lifecycle.viewmodel.compose.viewModel import de.mm20.launcher2.ktx.tryStartActivity import de.mm20.launcher2.ui.R @@ -44,6 +47,13 @@ fun WeatherWidget() { val viewModel: WeatherWidgetWM = viewModel() val context = LocalContext.current + val lifecycleOwner = LocalLifecycleOwner.current + + LaunchedEffect(null) { + lifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) { + viewModel.selectNow() + } + } val selectedForecast by viewModel.currentForecast.observeAsState() diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/weather/WeatherWidgetWM.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/weather/WeatherWidgetWM.kt index 8eaaee33..b2060f1c 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/weather/WeatherWidgetWM.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/weather/WeatherWidgetWM.kt @@ -13,6 +13,7 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import org.koin.core.component.KoinComponent import org.koin.core.component.inject +import kotlin.math.max import kotlin.math.min class WeatherWidgetWM : ViewModel(), KoinComponent { @@ -22,6 +23,9 @@ class WeatherWidgetWM : ViewModel(), KoinComponent { private val dataStore: LauncherDataStore by inject() + /** + * Index of the currently selected day in [dailyForecasts] + */ private var selectedDayIndex = 0 set(value) { field = min(value, forecasts.lastIndex) @@ -38,6 +42,9 @@ class WeatherWidgetWM : ViewModel(), KoinComponent { currentForecast.postValue(getCurrentlySelectedForecast()) } + /** + * Index of the currently selected forecast in [currentDayForecasts] + */ private var selectedForecastIndex = 0 set(value) { if (selectedDayIndex < 0) { @@ -50,6 +57,9 @@ class WeatherWidgetWM : ViewModel(), KoinComponent { private val forecastsFlow = weatherRepository.forecasts + /** + * All available forecasts, grouped by day + */ private var forecasts: List = emptyList() set(value) { field = value @@ -58,15 +68,32 @@ class WeatherWidgetWM : ViewModel(), KoinComponent { dailyForecasts.postValue(value) } + /** + * Currently selected forecast, one of [currentDayForecasts] + */ val currentForecast = MutableLiveData(getCurrentlySelectedForecast()) + + /** + * List of forecast summaries for each day + */ val dailyForecasts = MutableLiveData>(emptyList()) + + /** + * Forecasts of the currently selected day (hourly in most cases). + * This is [DailyForecast.hourlyForecasts] of [currentDailyForecast] + */ val currentDayForecasts = MutableLiveData>(emptyList()) + + /** + * Daily forecast summary for the currently selected day, one of [dailyForecasts] or null + */ val currentDailyForecast = MutableLiveData(null) init { viewModelScope.launch { forecastsFlow.collectLatest { forecasts = it + selectNow() } } } @@ -90,4 +117,14 @@ class WeatherWidgetWM : ViewModel(), KoinComponent { private fun getCurrentlySelectedForecast(): Forecast? { 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) + } } \ No newline at end of file