mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-14 08:17:04 +05:30
refactor(android): switch to DispatcherProvider
This commit is contained in:
parent
1db2f3256d
commit
59b35a9255
5 changed files with 61 additions and 13 deletions
|
@ -41,6 +41,7 @@ dependencies {
|
|||
kapt(libs.dagger.hilt.compiler)
|
||||
implementation(projects.api)
|
||||
implementation(projects.common)
|
||||
implementation(projects.coroutineUtils)
|
||||
implementation(projects.database)
|
||||
implementation(projects.metadataExtractor)
|
||||
implementation(projects.model)
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
package dev.msfjarvis.claw.android.injection
|
||||
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import dev.msfjarvis.claw.util.coroutines.DefaultDispatcherProvider
|
||||
import dev.msfjarvis.claw.util.coroutines.DispatcherProvider
|
||||
import javax.inject.Qualifier
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
abstract class CoroutineDispatcherModule {
|
||||
|
||||
@Binds abstract fun DefaultDispatcherProvider.bind(): DispatcherProvider
|
||||
|
||||
companion object {
|
||||
@[Provides IODispatcher]
|
||||
fun provideIODispatcher(dispatcherProvider: DispatcherProvider): CoroutineDispatcher {
|
||||
return dispatcherProvider.io()
|
||||
}
|
||||
|
||||
@[Provides DatabaseDispatcher]
|
||||
fun provideDatabaseDispatcher(dispatcherProvider: DispatcherProvider): CoroutineDispatcher {
|
||||
return dispatcherProvider.database()
|
||||
}
|
||||
|
||||
@[Provides MainDispatcher]
|
||||
fun provideMainDispatcher(dispatcherProvider: DispatcherProvider): CoroutineDispatcher {
|
||||
return dispatcherProvider.main()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class DatabaseDispatcher
|
||||
|
||||
@Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class MainDispatcher
|
||||
|
||||
@Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class IODispatcher
|
|
@ -3,17 +3,18 @@ package dev.msfjarvis.claw.android.paging
|
|||
import androidx.paging.PagingSource
|
||||
import androidx.paging.PagingState
|
||||
import dev.msfjarvis.claw.model.LobstersPost
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class LobstersPagingSource(
|
||||
private val getMorePosts: suspend (Int) -> List<LobstersPost>,
|
||||
private val ioDispatcher: CoroutineDispatcher,
|
||||
) : PagingSource<Int, LobstersPost>() {
|
||||
|
||||
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, LobstersPost> {
|
||||
return try {
|
||||
val page = params.key ?: 1
|
||||
val posts = withContext(Dispatchers.IO) { getMorePosts(page) }
|
||||
val posts = withContext(ioDispatcher) { getMorePosts(page) }
|
||||
|
||||
LoadResult.Page(
|
||||
data = posts,
|
||||
|
|
|
@ -5,12 +5,13 @@ import androidx.lifecycle.viewModelScope
|
|||
import androidx.paging.Pager
|
||||
import androidx.paging.PagingConfig
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dev.msfjarvis.claw.android.injection.IODispatcher
|
||||
import dev.msfjarvis.claw.android.paging.LobstersPagingSource
|
||||
import dev.msfjarvis.claw.android.ui.toLocalDateTime
|
||||
import dev.msfjarvis.claw.api.LobstersApi
|
||||
import dev.msfjarvis.claw.database.local.SavedPost
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -24,16 +25,19 @@ constructor(
|
|||
private val api: LobstersApi,
|
||||
private val savedPostsRepository: SavedPostsRepository,
|
||||
private val postDetailsRepository: PostDetailsRepository,
|
||||
@IODispatcher private val ioDispatcher: CoroutineDispatcher,
|
||||
) : ViewModel() {
|
||||
private var hottestPostsPagingSource: LobstersPagingSource? = null
|
||||
private var newestPostsPagingSource: LobstersPagingSource? = null
|
||||
private val hottestPostsPager =
|
||||
Pager(PagingConfig(20)) {
|
||||
LobstersPagingSource(api::getHottestPosts).also { hottestPostsPagingSource = it }
|
||||
LobstersPagingSource(api::getHottestPosts, ioDispatcher).also {
|
||||
hottestPostsPagingSource = it
|
||||
}
|
||||
}
|
||||
private val newestPostsPager =
|
||||
Pager(PagingConfig(20)) {
|
||||
LobstersPagingSource(api::getNewestPosts).also { newestPostsPagingSource = it }
|
||||
LobstersPagingSource(api::getNewestPosts, ioDispatcher).also { newestPostsPagingSource = it }
|
||||
}
|
||||
|
||||
val hottestPosts
|
||||
|
@ -58,7 +62,7 @@ constructor(
|
|||
}
|
||||
|
||||
fun toggleSave(post: SavedPost) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
viewModelScope.launch(ioDispatcher) {
|
||||
val saved = isPostSaved(post)
|
||||
if (saved) {
|
||||
savedPostsRepository.removePost(post)
|
||||
|
@ -69,14 +73,13 @@ constructor(
|
|||
}
|
||||
|
||||
suspend fun getPostComments(postId: String) =
|
||||
withContext(Dispatchers.IO) {
|
||||
withContext(ioDispatcher) {
|
||||
val details = api.getPostDetails(postId)
|
||||
val extendedDetails = postDetailsRepository.getExtendedDetails(details)
|
||||
extendedDetails
|
||||
}
|
||||
|
||||
suspend fun getUserProfile(username: String) =
|
||||
withContext(Dispatchers.IO) { api.getUser(username) }
|
||||
suspend fun getUserProfile(username: String) = withContext(ioDispatcher) { api.getUser(username) }
|
||||
|
||||
fun refreshHottestPosts() {
|
||||
hottestPostsPagingSource?.invalidate()
|
||||
|
|
|
@ -2,29 +2,31 @@ package dev.msfjarvis.claw.android.viewmodel
|
|||
|
||||
import app.cash.sqldelight.coroutines.asFlow
|
||||
import app.cash.sqldelight.coroutines.mapToList
|
||||
import dev.msfjarvis.claw.android.injection.DatabaseDispatcher
|
||||
import dev.msfjarvis.claw.database.LobstersDatabase
|
||||
import dev.msfjarvis.claw.database.local.SavedPost
|
||||
import io.github.aakira.napier.Napier
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class SavedPostsRepository
|
||||
@Inject
|
||||
constructor(
|
||||
database: LobstersDatabase,
|
||||
@DatabaseDispatcher private val dbDispatcher: CoroutineDispatcher,
|
||||
) {
|
||||
private val savedPostQueries = database.savedPostQueries
|
||||
val savedPosts = savedPostQueries.selectAllPosts().asFlow().mapToList()
|
||||
val savedPosts = savedPostQueries.selectAllPosts().asFlow().mapToList(dbDispatcher)
|
||||
|
||||
suspend fun savePost(post: SavedPost) {
|
||||
Napier.d(tag = TAG) { "Saving post: ${post.shortId}" }
|
||||
withContext(Dispatchers.IO) { savedPostQueries.insertOrReplacePost(post) }
|
||||
withContext(dbDispatcher) { savedPostQueries.insertOrReplacePost(post) }
|
||||
}
|
||||
|
||||
suspend fun removePost(post: SavedPost) {
|
||||
Napier.d(tag = TAG) { "Removing post: ${post.shortId}" }
|
||||
withContext(Dispatchers.IO) { savedPostQueries.deletePost(post.shortId) }
|
||||
withContext(dbDispatcher) { savedPostQueries.deletePost(post.shortId) }
|
||||
}
|
||||
|
||||
private companion object {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue