mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-15 01:47:03 +05:30
android: use WorkManager to update saved posts periodically
This commit is contained in:
parent
f05a90e281
commit
27a8d16487
6 changed files with 105 additions and 9 deletions
|
@ -20,6 +20,7 @@ android {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
kapt(libs.dagger.hilt.compiler)
|
kapt(libs.dagger.hilt.compiler)
|
||||||
|
kapt(libs.androidx.hilt.compiler)
|
||||||
implementation(projects.api)
|
implementation(projects.api)
|
||||||
implementation(projects.common)
|
implementation(projects.common)
|
||||||
implementation(projects.database)
|
implementation(projects.database)
|
||||||
|
@ -30,6 +31,7 @@ dependencies {
|
||||||
implementation(libs.androidx.appcompat)
|
implementation(libs.androidx.appcompat)
|
||||||
implementation(libs.androidx.core.ktx)
|
implementation(libs.androidx.core.ktx)
|
||||||
implementation(libs.androidx.core.splashscreen)
|
implementation(libs.androidx.core.splashscreen)
|
||||||
|
implementation(libs.androidx.hilt.work)
|
||||||
implementation(libs.androidx.lifecycle.compose)
|
implementation(libs.androidx.lifecycle.compose)
|
||||||
implementation(libs.androidx.navigation.compose)
|
implementation(libs.androidx.navigation.compose)
|
||||||
implementation(libs.androidx.paging.compose)
|
implementation(libs.androidx.paging.compose)
|
||||||
|
@ -39,4 +41,5 @@ dependencies {
|
||||||
implementation(libs.kotlin.coroutines.core)
|
implementation(libs.kotlin.coroutines.core)
|
||||||
implementation(libs.kotlinx.serialization.json)
|
implementation(libs.kotlinx.serialization.json)
|
||||||
implementation(libs.retrofit.kotlinxSerializationConverter) { isTransitive = false }
|
implementation(libs.retrofit.kotlinxSerializationConverter) { isTransitive = false }
|
||||||
|
implementation(libs.androidx.work.runtime.ktx)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
package="dev.msfjarvis.claw.android">
|
package="dev.msfjarvis.claw.android">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
@ -56,5 +57,15 @@
|
||||||
android:pathPattern="/s/....../...*"/>
|
android:pathPattern="/s/....../...*"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
<provider
|
||||||
|
android:name="androidx.startup.InitializationProvider"
|
||||||
|
android:authorities="${applicationId}.androidx-startup"
|
||||||
|
android:exported="false"
|
||||||
|
tools:node="merge">
|
||||||
|
<meta-data
|
||||||
|
android:name="androidx.work.WorkManagerInitializer"
|
||||||
|
android:value="androidx.startup"
|
||||||
|
tools:node="remove" />
|
||||||
|
</provider>
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
@ -2,10 +2,16 @@ package dev.msfjarvis.claw.android
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.os.StrictMode
|
import android.os.StrictMode
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.hilt.work.HiltWorkerFactory
|
||||||
|
import androidx.work.Configuration
|
||||||
import dagger.hilt.android.HiltAndroidApp
|
import dagger.hilt.android.HiltAndroidApp
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltAndroidApp
|
@HiltAndroidApp
|
||||||
class ClawApplication : Application() {
|
class ClawApplication : Application(), Configuration.Provider {
|
||||||
|
@Inject lateinit var workerFactory: HiltWorkerFactory
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
|
@ -13,4 +19,11 @@ class ClawApplication : Application() {
|
||||||
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build())
|
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getWorkManagerConfiguration(): Configuration {
|
||||||
|
return Configuration.Builder()
|
||||||
|
.setMinimumLoggingLevel(Log.DEBUG)
|
||||||
|
.setWorkerFactory(workerFactory)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,18 @@ import android.os.Bundle
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.work.Constraints
|
||||||
|
import androidx.work.ExistingPeriodicWorkPolicy
|
||||||
|
import androidx.work.NetworkType
|
||||||
|
import androidx.work.PeriodicWorkRequestBuilder
|
||||||
|
import androidx.work.WorkManager
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import dev.msfjarvis.claw.android.ui.LobstersApp
|
import dev.msfjarvis.claw.android.ui.LobstersApp
|
||||||
|
import dev.msfjarvis.claw.android.work.SavedPostUpdaterWorker
|
||||||
import dev.msfjarvis.claw.common.comments.HTMLConverter
|
import dev.msfjarvis.claw.common.comments.HTMLConverter
|
||||||
import dev.msfjarvis.claw.common.urllauncher.UrlLauncher
|
import dev.msfjarvis.claw.common.urllauncher.UrlLauncher
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
|
@ -23,10 +31,26 @@ class MainActivity : ComponentActivity() {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
installSplashScreen()
|
installSplashScreen()
|
||||||
setContent {
|
setContent {
|
||||||
LobstersApp(
|
LobstersApp(urlLauncher = urlLauncher, htmlConverter = htmlConverter) { url -> webUri = url }
|
||||||
urlLauncher = urlLauncher,
|
}
|
||||||
htmlConverter = htmlConverter,
|
lifecycleScope.launchWhenCreated {
|
||||||
) { url -> webUri = url }
|
val postUpdateWorkRequest =
|
||||||
|
PeriodicWorkRequestBuilder<SavedPostUpdaterWorker>(24, TimeUnit.HOURS)
|
||||||
|
.setConstraints(
|
||||||
|
Constraints.Builder()
|
||||||
|
.setRequiresCharging(false)
|
||||||
|
.setRequiresBatteryNotLow(true)
|
||||||
|
.setRequiredNetworkType(NetworkType.CONNECTED)
|
||||||
|
.setRequiresDeviceIdle(true)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
WorkManager.getInstance(this@MainActivity)
|
||||||
|
.enqueueUniquePeriodicWork(
|
||||||
|
"updateSavedPosts",
|
||||||
|
ExistingPeriodicWorkPolicy.KEEP,
|
||||||
|
postUpdateWorkRequest,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
package dev.msfjarvis.claw.android.work
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.hilt.work.HiltWorker
|
||||||
|
import androidx.work.CoroutineWorker
|
||||||
|
import androidx.work.WorkerParameters
|
||||||
|
import dagger.assisted.Assisted
|
||||||
|
import dagger.assisted.AssistedInject
|
||||||
|
import dev.msfjarvis.claw.android.viewmodel.SavedPostsRepository
|
||||||
|
import dev.msfjarvis.claw.api.LobstersApi
|
||||||
|
import dev.msfjarvis.claw.common.posts.toDbModel
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WorkManager-backed [CoroutineWorker] that gets all the posts from [SavedPostsRepository], fetches
|
||||||
|
* their newest state using the [LobstersApi] and then writes them back to the database. This allows
|
||||||
|
* saved posts that were saved before comment counts were added to be able to show a comment count
|
||||||
|
* and for new-enough posts that are still getting comments to have an accurate one.
|
||||||
|
*/
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
@HiltWorker
|
||||||
|
class SavedPostUpdaterWorker
|
||||||
|
@AssistedInject
|
||||||
|
constructor(
|
||||||
|
private val savedPostsRepository: SavedPostsRepository,
|
||||||
|
private val lobstersApi: LobstersApi,
|
||||||
|
@Assisted appContext: Context,
|
||||||
|
@Assisted workerParams: WorkerParameters,
|
||||||
|
) : CoroutineWorker(appContext, workerParams) {
|
||||||
|
override suspend fun doWork(): Result {
|
||||||
|
savedPostsRepository
|
||||||
|
.savedPosts
|
||||||
|
.first()
|
||||||
|
.mapNotNull { post -> runCatching { lobstersApi.getPostDetails(post.shortId) }.getOrNull() }
|
||||||
|
.map { postDetails -> postDetails.toDbModel() }
|
||||||
|
.map { post -> savedPostsRepository.savePost(post) }
|
||||||
|
return Result.success()
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,11 +2,13 @@
|
||||||
accompanist = "0.24.5-alpha"
|
accompanist = "0.24.5-alpha"
|
||||||
aurora = "1.1.0"
|
aurora = "1.1.0"
|
||||||
coroutines = "1.6.1"
|
coroutines = "1.6.1"
|
||||||
hilt = "2.41"
|
dagger = "2.41"
|
||||||
|
hilt = "1.0.0"
|
||||||
kotlin = "1.6.10"
|
kotlin = "1.6.10"
|
||||||
richtext = "0.11.0"
|
richtext = "0.11.0"
|
||||||
serialization = "1.3.2"
|
serialization = "1.3.2"
|
||||||
sqldelight = "1.5.3"
|
sqldelight = "1.5.3"
|
||||||
|
workmanager = "2.8.0-alpha01"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
accompanist-swiperefresh = { module = "com.google.accompanist:accompanist-swiperefresh", version.ref = "accompanist" }
|
accompanist-swiperefresh = { module = "com.google.accompanist:accompanist-swiperefresh", version.ref = "accompanist" }
|
||||||
|
@ -16,9 +18,12 @@ androidx-appcompat = "androidx.appcompat:appcompat:1.6.0-alpha01"
|
||||||
androidx-browser = "androidx.browser:browser:1.4.0"
|
androidx-browser = "androidx.browser:browser:1.4.0"
|
||||||
androidx-core-ktx = "androidx.core:core-ktx:1.9.0-alpha02"
|
androidx-core-ktx = "androidx.core:core-ktx:1.9.0-alpha02"
|
||||||
androidx-core-splashscreen = "androidx.core:core-splashscreen:1.0.0-beta02"
|
androidx-core-splashscreen = "androidx.core:core-splashscreen:1.0.0-beta02"
|
||||||
|
androidx-hilt-compiler = { module = "androidx.hilt:hilt-compiler", version.ref = "hilt" }
|
||||||
|
androidx-hilt-work = { module = "androidx.hilt:hilt-work", version.ref = "hilt" }
|
||||||
androidx-lifecycle-compose = "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.0-alpha05"
|
androidx-lifecycle-compose = "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.0-alpha05"
|
||||||
androidx-navigation-compose = "androidx.navigation:navigation-compose:2.5.0-alpha03"
|
androidx-navigation-compose = "androidx.navigation:navigation-compose:2.5.0-alpha03"
|
||||||
androidx-paging-compose = "androidx.paging:paging-compose:1.0.0-alpha14"
|
androidx-paging-compose = "androidx.paging:paging-compose:1.0.0-alpha14"
|
||||||
|
androidx-work-runtime-ktx = { module = "androidx.work:work-runtime-ktx", version.ref = "workmanager" }
|
||||||
aurora-component = { module = "org.pushing-pixels:aurora-component", version.ref = "aurora" }
|
aurora-component = { module = "org.pushing-pixels:aurora-component", version.ref = "aurora" }
|
||||||
aurora-theming = { module = "org.pushing-pixels:aurora-theming", version.ref = "aurora" }
|
aurora-theming = { module = "org.pushing-pixels:aurora-theming", version.ref = "aurora" }
|
||||||
aurora-window = { module = "org.pushing-pixels:aurora-window", version.ref = "aurora" }
|
aurora-window = { module = "org.pushing-pixels:aurora-window", version.ref = "aurora" }
|
||||||
|
@ -33,8 +38,8 @@ compose-richtext-markdown = { module = "com.halilibo.compose-richtext:richtext-c
|
||||||
compose-richtext-material = { module = "com.halilibo.compose-richtext:richtext-ui-material", version.ref = "richtext" }
|
compose-richtext-material = { module = "com.halilibo.compose-richtext:richtext-ui-material", version.ref = "richtext" }
|
||||||
compose-richtext-ui = { module = "com.halilibo.compose-richtext:richtext-ui", version.ref = "richtext" }
|
compose-richtext-ui = { module = "com.halilibo.compose-richtext:richtext-ui", version.ref = "richtext" }
|
||||||
copydown = "io.github.furstenheim:copy_down:1.0"
|
copydown = "io.github.furstenheim:copy_down:1.0"
|
||||||
dagger-hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" }
|
dagger-hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "dagger" }
|
||||||
dagger-hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" }
|
dagger-hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "dagger" }
|
||||||
javapoet = "com.squareup:javapoet:1.13.0"
|
javapoet = "com.squareup:javapoet:1.13.0"
|
||||||
kamel-image = "com.alialbaali.kamel:kamel-image:0.3.0"
|
kamel-image = "com.alialbaali.kamel:kamel-image:0.3.0"
|
||||||
kotlin-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }
|
kotlin-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }
|
||||||
|
@ -51,5 +56,5 @@ testing-mockWebServer = "com.squareup.okhttp3:mockwebserver3-junit4:5.0.0-alpha.
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
compose = "org.jetbrains.compose:1.1.1"
|
compose = "org.jetbrains.compose:1.1.1"
|
||||||
hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
|
hilt = { id = "com.google.dagger.hilt.android", version.ref = "dagger" }
|
||||||
sqldelight = "com.squareup.sqldelight:1.5.3"
|
sqldelight = "com.squareup.sqldelight:1.5.3"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue