refactor(android): switch to DispatcherProvider

This commit is contained in:
Harsh Shandilya 2022-09-09 12:02:22 +05:30
parent 1db2f3256d
commit 59b35a9255
No known key found for this signature in database
5 changed files with 61 additions and 13 deletions

View file

@ -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)

View file

@ -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

View file

@ -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,

View file

@ -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()

View file

@ -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 {