Weather widget: select current time on resume
This commit is contained in:
parent
9e6a1cde3c
commit
109271947d
@ -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()
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user