Use IO dispatcher for some screen model work
Not sure if this is an ideal approach. If it is, we could migrate more usages to this.
This commit is contained in:
parent
d1bf857079
commit
18f9e5ba6b
@ -31,11 +31,11 @@ import androidx.lifecycle.asFlow
|
||||
import androidx.work.WorkInfo
|
||||
import androidx.work.WorkQuery
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import cafe.adriel.voyager.core.model.coroutineScope
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||
import eu.kanade.presentation.util.Screen
|
||||
import eu.kanade.presentation.util.ioCoroutineScope
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.util.system.workManager
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
@ -128,19 +128,19 @@ object WorkerInfoScreen : Screen() {
|
||||
.getWorkInfosLiveData(WorkQuery.fromStates(WorkInfo.State.SUCCEEDED, WorkInfo.State.FAILED, WorkInfo.State.CANCELLED))
|
||||
.asFlow()
|
||||
.map(::constructString)
|
||||
.stateIn(coroutineScope, SharingStarted.WhileSubscribed(), "")
|
||||
.stateIn(ioCoroutineScope, SharingStarted.WhileSubscribed(), "")
|
||||
|
||||
val running = workManager
|
||||
.getWorkInfosLiveData(WorkQuery.fromStates(WorkInfo.State.RUNNING))
|
||||
.asFlow()
|
||||
.map(::constructString)
|
||||
.stateIn(coroutineScope, SharingStarted.WhileSubscribed(), "")
|
||||
.stateIn(ioCoroutineScope, SharingStarted.WhileSubscribed(), "")
|
||||
|
||||
val enqueued = workManager
|
||||
.getWorkInfosLiveData(WorkQuery.fromStates(WorkInfo.State.ENQUEUED))
|
||||
.asFlow()
|
||||
.map(::constructString)
|
||||
.stateIn(coroutineScope, SharingStarted.WhileSubscribed(), "")
|
||||
.stateIn(ioCoroutineScope, SharingStarted.WhileSubscribed(), "")
|
||||
|
||||
private fun constructString(list: List<WorkInfo>) = buildString {
|
||||
if (list.isEmpty()) {
|
||||
|
@ -3,12 +3,20 @@ package eu.kanade.presentation.util
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.ProvidableCompositionLocal
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import cafe.adriel.voyager.core.model.ScreenModelStore
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.core.screen.ScreenKey
|
||||
import cafe.adriel.voyager.core.screen.uniqueScreenKey
|
||||
import cafe.adriel.voyager.core.stack.StackEvent
|
||||
import cafe.adriel.voyager.navigator.Navigator
|
||||
import cafe.adriel.voyager.transitions.ScreenTransition
|
||||
import kotlinx.coroutines.CoroutineName
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.plus
|
||||
import soup.compose.material.motion.animation.materialSharedAxisX
|
||||
import soup.compose.material.motion.animation.rememberSlideDistance
|
||||
|
||||
@ -28,6 +36,18 @@ abstract class Screen : Screen {
|
||||
override val key: ScreenKey = uniqueScreenKey
|
||||
}
|
||||
|
||||
/**
|
||||
* A variant of ScreenModel.coroutineScope except with the IO dispatcher instead of the
|
||||
* main dispatcher.
|
||||
*/
|
||||
val ScreenModel.ioCoroutineScope: CoroutineScope
|
||||
get() = ScreenModelStore.getOrPutDependency(
|
||||
screenModel = this,
|
||||
name = "ScreenModelIoCoroutineScope",
|
||||
factory = { key -> CoroutineScope(Dispatchers.IO + SupervisorJob()) + CoroutineName(key) },
|
||||
onDispose = { scope -> scope.cancel() },
|
||||
)
|
||||
|
||||
interface AssistContentScreen {
|
||||
fun onProvideAssistUrl(): String?
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.manga.model.toDomainManga
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.domain.track.model.toDomainTrack
|
||||
import eu.kanade.presentation.util.ioCoroutineScope
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.data.track.EnhancedTrackService
|
||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
@ -125,12 +126,12 @@ class BrowseSourceScreenModel(
|
||||
.filter { localManga ->
|
||||
!sourcePreferences.hideInLibraryItems().get() || !localManga.favorite
|
||||
}
|
||||
.stateIn(coroutineScope)
|
||||
.stateIn(ioCoroutineScope)
|
||||
}
|
||||
}
|
||||
.cachedIn(coroutineScope)
|
||||
.cachedIn(ioCoroutineScope)
|
||||
}
|
||||
.stateIn(coroutineScope, SharingStarted.Lazily, emptyFlow())
|
||||
.stateIn(ioCoroutineScope, SharingStarted.Lazily, emptyFlow())
|
||||
|
||||
fun getColumnsPreference(orientation: Int): GridCells {
|
||||
val isLandscape = orientation == Configuration.ORIENTATION_LANDSCAPE
|
||||
|
@ -4,10 +4,10 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.produceState
|
||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||
import cafe.adriel.voyager.core.model.coroutineScope
|
||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||
import eu.kanade.domain.manga.model.toDomainManga
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.presentation.util.ioCoroutineScope
|
||||
import eu.kanade.tachiyomi.extension.ExtensionManager
|
||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||
import kotlinx.coroutines.asCoroutineDispatcher
|
||||
@ -17,7 +17,6 @@ import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import tachiyomi.core.util.lang.awaitSingle
|
||||
import tachiyomi.core.util.lang.withIOContext
|
||||
import tachiyomi.domain.manga.interactor.GetManga
|
||||
import tachiyomi.domain.manga.interactor.NetworkToLocalManga
|
||||
import tachiyomi.domain.manga.model.Manga
|
||||
@ -94,7 +93,7 @@ abstract class SearchScreenModel<T>(
|
||||
|
||||
abstract fun getItems(): Map<CatalogueSource, SearchItemResult>
|
||||
|
||||
fun getAndUpdateItems(function: (Map<CatalogueSource, SearchItemResult>) -> Map<CatalogueSource, SearchItemResult>) {
|
||||
private fun getAndUpdateItems(function: (Map<CatalogueSource, SearchItemResult>) -> Map<CatalogueSource, SearchItemResult>) {
|
||||
updateItems(function(getItems()))
|
||||
}
|
||||
|
||||
@ -106,7 +105,7 @@ abstract class SearchScreenModel<T>(
|
||||
val initialItems = getSelectedSources().associateWith { SearchItemResult.Loading }
|
||||
updateItems(initialItems)
|
||||
|
||||
coroutineScope.launch {
|
||||
ioCoroutineScope.launch {
|
||||
sources
|
||||
.map { source ->
|
||||
async {
|
||||
@ -115,10 +114,8 @@ abstract class SearchScreenModel<T>(
|
||||
source.fetchSearchManga(1, query, source.getFilterList()).awaitSingle()
|
||||
}
|
||||
|
||||
val titles = withIOContext {
|
||||
page.mangas.map {
|
||||
networkToLocalManga.await(it.toDomainManga(source.id))
|
||||
}
|
||||
val titles = page.mangas.map {
|
||||
networkToLocalManga.await(it.toDomainManga(source.id))
|
||||
}
|
||||
|
||||
getAndUpdateItems { items ->
|
||||
@ -129,7 +126,7 @@ abstract class SearchScreenModel<T>(
|
||||
} catch (e: Exception) {
|
||||
getAndUpdateItems { items ->
|
||||
val mutableMap = items.toMutableMap()
|
||||
mutableMap[source] = SearchItemResult.Error(throwable = e)
|
||||
mutableMap[source] = SearchItemResult.Error(e)
|
||||
mutableMap.toSortedMap(sortComparator(mutableMap))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user