Refactor weather widget
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
package de.mm20.launcher2.weather
|
||||
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.dsl.module
|
||||
|
||||
val weatherModule = module {
|
||||
single { WeatherRepository(androidContext(), get()) }
|
||||
}
|
||||
@@ -2,31 +2,35 @@ package de.mm20.launcher2.weather
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.MediatorLiveData
|
||||
import androidx.work.*
|
||||
import de.mm20.launcher2.database.AppDatabase
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class WeatherRepository(
|
||||
val context: Context
|
||||
val context: Context,
|
||||
val database: AppDatabase,
|
||||
) {
|
||||
|
||||
val forecasts = MediatorLiveData<List<DailyForecast>>()
|
||||
|
||||
init {
|
||||
|
||||
forecasts.addSource(AppDatabase.getInstance(context).weatherDao().getForecasts()) { entities ->
|
||||
forecasts.value = sortDailyForecasts(entities.map { Forecast(it) })
|
||||
val forecasts = database.weatherDao().getForecasts()
|
||||
.map { it.map { Forecast(it) } }
|
||||
.map {
|
||||
groupForecastsPerDay(it)
|
||||
}
|
||||
|
||||
val weatherRequest = PeriodicWorkRequest.Builder(WeatherUpdateWorker::class.java, 60, TimeUnit.MINUTES)
|
||||
init {
|
||||
val weatherRequest =
|
||||
PeriodicWorkRequest.Builder(WeatherUpdateWorker::class.java, 60, TimeUnit.MINUTES)
|
||||
.build()
|
||||
WorkManager.getInstance().enqueueUniquePeriodicWork("weather",
|
||||
ExistingPeriodicWorkPolicy.KEEP, weatherRequest)
|
||||
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
|
||||
"weather",
|
||||
ExistingPeriodicWorkPolicy.KEEP, weatherRequest
|
||||
)
|
||||
}
|
||||
|
||||
private fun sortDailyForecasts(forecasts: List<Forecast>): List<DailyForecast> {
|
||||
private fun groupForecastsPerDay(forecasts: List<Forecast>): List<DailyForecast> {
|
||||
val dailyForecasts = mutableListOf<DailyForecast>()
|
||||
val calendar = Calendar.getInstance()
|
||||
var currentDay = 0
|
||||
@@ -35,12 +39,16 @@ class WeatherRepository(
|
||||
calendar.timeInMillis = fc.timestamp
|
||||
if (currentDay != calendar.get(Calendar.DAY_OF_YEAR)) {
|
||||
if (currentDayForecasts.isNotEmpty()) {
|
||||
dailyForecasts.add(DailyForecast(
|
||||
dailyForecasts.add(
|
||||
DailyForecast(
|
||||
timestamp = currentDayForecasts.first().timestamp,
|
||||
minTemp = currentDayForecasts.minByOrNull { it.temperature }?.temperature ?: 0.0,
|
||||
maxTemp = currentDayForecasts.maxByOrNull { it.temperature }?.temperature ?: 0.0,
|
||||
minTemp = currentDayForecasts.minByOrNull { it.temperature }?.temperature
|
||||
?: 0.0,
|
||||
maxTemp = currentDayForecasts.maxByOrNull { it.temperature }?.temperature
|
||||
?: 0.0,
|
||||
hourlyForecasts = currentDayForecasts
|
||||
))
|
||||
)
|
||||
)
|
||||
currentDayForecasts = mutableListOf()
|
||||
}
|
||||
currentDay = calendar.get(Calendar.DAY_OF_YEAR)
|
||||
@@ -48,12 +56,16 @@ class WeatherRepository(
|
||||
currentDayForecasts.add(fc)
|
||||
}
|
||||
if (currentDayForecasts.isNotEmpty()) {
|
||||
dailyForecasts.add(DailyForecast(
|
||||
dailyForecasts.add(
|
||||
DailyForecast(
|
||||
timestamp = currentDayForecasts.first().timestamp,
|
||||
minTemp = currentDayForecasts.minByOrNull { it.temperature }?.temperature ?: 0.0,
|
||||
maxTemp = currentDayForecasts.maxByOrNull { it.temperature }?.temperature ?: 0.0,
|
||||
minTemp = currentDayForecasts.minByOrNull { it.temperature }?.temperature
|
||||
?: 0.0,
|
||||
maxTemp = currentDayForecasts.maxByOrNull { it.temperature }?.temperature
|
||||
?: 0.0,
|
||||
hourlyForecasts = currentDayForecasts
|
||||
))
|
||||
)
|
||||
)
|
||||
}
|
||||
return dailyForecasts
|
||||
}
|
||||
@@ -63,8 +75,8 @@ class WeatherRepository(
|
||||
val provider = WeatherProvider.getInstance(context) ?: return
|
||||
if (provider.isUpdateRequired()) {
|
||||
val weatherRequest = OneTimeWorkRequest.Builder(WeatherUpdateWorker::class.java)
|
||||
.addTag("weather")
|
||||
.build()
|
||||
.addTag("weather")
|
||||
.build()
|
||||
WorkManager.getInstance(context).enqueue(weatherRequest)
|
||||
} else {
|
||||
Log.d("MM20", "No weather update required")
|
||||
@@ -72,7 +84,8 @@ class WeatherRepository(
|
||||
}
|
||||
}
|
||||
|
||||
class WeatherUpdateWorker(val context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
|
||||
class WeatherUpdateWorker(val context: Context, params: WorkerParameters) :
|
||||
CoroutineWorker(context, params) {
|
||||
override suspend fun doWork(): Result {
|
||||
val provider = WeatherProvider.getInstance(context) ?: return Result.failure()
|
||||
if (!provider.isAvailable()) return Result.failure()
|
||||
@@ -83,7 +96,8 @@ class WeatherUpdateWorker(val context: Context, params: WorkerParameters) : Coro
|
||||
Result.retry()
|
||||
} else {
|
||||
Log.d("MM20", "Weather update succeeded")
|
||||
AppDatabase.getInstance(applicationContext).weatherDao().replaceAll(weatherData.map { it.toDatabaseEntity() })
|
||||
AppDatabase.getInstance(applicationContext).weatherDao()
|
||||
.replaceAll(weatherData.map { it.toDatabaseEntity() })
|
||||
Result.success()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,19 +4,17 @@ import android.app.Application
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.LiveData
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
class WeatherViewModel(application: Application) : AndroidViewModel(application) {
|
||||
class WeatherViewModel(application: Application) : AndroidViewModel(application), KoinComponent {
|
||||
|
||||
private val repository = WeatherRepository(application)
|
||||
private val repository : WeatherRepository by inject()
|
||||
|
||||
init {
|
||||
requestUpdate(application)
|
||||
}
|
||||
|
||||
val forecasts: LiveData<List<DailyForecast>> by lazy {
|
||||
repository.forecasts
|
||||
}
|
||||
|
||||
fun requestUpdate(context: Context) {
|
||||
repository.requestUpdate(context)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user