mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-03 23:58:55 +01:00 
			
		
		
		
	Update Voyager
This commit is contained in:
		@@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.padding
 | 
			
		||||
import androidx.compose.foundation.lazy.grid.GridCells
 | 
			
		||||
import androidx.compose.material.icons.Icons
 | 
			
		||||
import androidx.compose.material.icons.automirrored.outlined.HelpOutline
 | 
			
		||||
import androidx.compose.material.icons.outlined.HelpOutline
 | 
			
		||||
import androidx.compose.material.icons.outlined.Public
 | 
			
		||||
import androidx.compose.material.icons.outlined.Refresh
 | 
			
		||||
import androidx.compose.material3.SnackbarDuration
 | 
			
		||||
@@ -98,7 +97,7 @@ fun BrowseSourceContent(
 | 
			
		||||
                    ),
 | 
			
		||||
                    EmptyScreenAction(
 | 
			
		||||
                        stringResId = R.string.label_help,
 | 
			
		||||
                        icon = Icons.Outlined.HelpOutline,
 | 
			
		||||
                        icon = Icons.AutoMirrored.Outlined.HelpOutline,
 | 
			
		||||
                        onClick = onHelpClick,
 | 
			
		||||
                    ),
 | 
			
		||||
                )
 | 
			
		||||
 
 | 
			
		||||
@@ -31,8 +31,8 @@ import androidx.compose.ui.res.stringResource
 | 
			
		||||
import androidx.compose.ui.unit.dp
 | 
			
		||||
import androidx.compose.ui.util.fastMap
 | 
			
		||||
import cafe.adriel.voyager.core.model.StateScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.rememberScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import cafe.adriel.voyager.navigator.LocalNavigator
 | 
			
		||||
import cafe.adriel.voyager.navigator.currentOrThrow
 | 
			
		||||
import eu.kanade.presentation.browse.components.SourceIcon
 | 
			
		||||
@@ -210,7 +210,7 @@ private class ClearDatabaseScreenModel : StateScreenModel<ClearDatabaseScreenMod
 | 
			
		||||
    private val database: Database = Injekt.get()
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            getSourcesWithNonLibraryManga.subscribe()
 | 
			
		||||
                .collectLatest { list ->
 | 
			
		||||
                    mutableState.update { old ->
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.extension
 | 
			
		||||
 | 
			
		||||
import androidx.compose.runtime.Immutable
 | 
			
		||||
import cafe.adriel.voyager.core.model.StateScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import eu.kanade.domain.extension.interactor.GetExtensionLanguages
 | 
			
		||||
import eu.kanade.domain.source.interactor.ToggleLanguage
 | 
			
		||||
import eu.kanade.domain.source.service.SourcePreferences
 | 
			
		||||
@@ -29,7 +29,7 @@ class ExtensionFilterScreenModel(
 | 
			
		||||
    val events: Flow<ExtensionFilterEvent> = _events.receiveAsFlow()
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            combine(
 | 
			
		||||
                getExtensionLanguages.subscribe(),
 | 
			
		||||
                preferences.enabledLanguages().changes(),
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ import android.app.Application
 | 
			
		||||
import androidx.annotation.StringRes
 | 
			
		||||
import androidx.compose.runtime.Immutable
 | 
			
		||||
import cafe.adriel.voyager.core.model.StateScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import eu.kanade.domain.extension.interactor.GetExtensionsByType
 | 
			
		||||
import eu.kanade.domain.source.service.SourcePreferences
 | 
			
		||||
import eu.kanade.presentation.components.SEARCH_DEBOUNCE_MILLIS
 | 
			
		||||
@@ -74,7 +74,7 @@ class ExtensionsScreenModel(
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            combine(
 | 
			
		||||
                state.map { it.searchQuery }.distinctUntilChanged().debounce(SEARCH_DEBOUNCE_MILLIS),
 | 
			
		||||
                _currentDownloads,
 | 
			
		||||
@@ -118,11 +118,11 @@ class ExtensionsScreenModel(
 | 
			
		||||
                }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        coroutineScope.launchIO { findAvailableExtensions() }
 | 
			
		||||
        screenModelScope.launchIO { findAvailableExtensions() }
 | 
			
		||||
 | 
			
		||||
        preferences.extensionUpdatesCount().changes()
 | 
			
		||||
            .onEach { mutableState.update { state -> state.copy(updates = it) } }
 | 
			
		||||
            .launchIn(coroutineScope)
 | 
			
		||||
            .launchIn(screenModelScope)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun search(query: String?) {
 | 
			
		||||
@@ -132,7 +132,7 @@ class ExtensionsScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun updateAllExtensions() {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            state.value.items.values.flatten()
 | 
			
		||||
                .map { it.extension }
 | 
			
		||||
                .filterIsInstance<Extension.Installed>()
 | 
			
		||||
@@ -142,13 +142,13 @@ class ExtensionsScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun installExtension(extension: Extension.Available) {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            extensionManager.installExtension(extension).collectToInstallUpdate(extension)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun updateExtension(extension: Extension.Installed) {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            extensionManager.updateExtension(extension).collectToInstallUpdate(extension)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -176,7 +176,7 @@ class ExtensionsScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun findAvailableExtensions() {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            mutableState.update { it.copy(isRefreshing = true) }
 | 
			
		||||
 | 
			
		||||
            extensionManager.findAvailableExtensions()
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.ui.browse.extension.details
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import androidx.compose.runtime.Immutable
 | 
			
		||||
import cafe.adriel.voyager.core.model.StateScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import eu.kanade.domain.extension.interactor.ExtensionSourceItem
 | 
			
		||||
import eu.kanade.domain.extension.interactor.GetExtensionSources
 | 
			
		||||
import eu.kanade.domain.source.interactor.ToggleSource
 | 
			
		||||
@@ -44,7 +44,7 @@ class ExtensionDetailsScreenModel(
 | 
			
		||||
    val events: Flow<ExtensionDetailsEvent> = _events.receiveAsFlow()
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            launch {
 | 
			
		||||
                extensionManager.installedExtensionsFlow
 | 
			
		||||
                    .map { it.firstOrNull { extension -> extension.pkgName == pkgName } }
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.migration.manga
 | 
			
		||||
 | 
			
		||||
import androidx.compose.runtime.Immutable
 | 
			
		||||
import cafe.adriel.voyager.core.model.StateScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import eu.kanade.tachiyomi.source.Source
 | 
			
		||||
import kotlinx.coroutines.channels.Channel
 | 
			
		||||
import kotlinx.coroutines.flow.Flow
 | 
			
		||||
@@ -30,7 +30,7 @@ class MigrateMangaScreenModel(
 | 
			
		||||
    val events: Flow<MigrationMangaEvent> = _events.receiveAsFlow()
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            mutableState.update { state ->
 | 
			
		||||
                state.copy(source = sourceManager.getOrStub(sourceId))
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.migration.search
 | 
			
		||||
 | 
			
		||||
import androidx.compose.runtime.Immutable
 | 
			
		||||
import cafe.adriel.voyager.core.model.StateScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import kotlinx.coroutines.flow.update
 | 
			
		||||
import kotlinx.coroutines.launch
 | 
			
		||||
import tachiyomi.domain.manga.interactor.GetManga
 | 
			
		||||
@@ -16,7 +16,7 @@ class MigrateSearchScreenDialogScreenModel(
 | 
			
		||||
) : StateScreenModel<MigrateSearchScreenDialogScreenModel.State>(State()) {
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            val manga = getManga.await(mangaId)!!
 | 
			
		||||
 | 
			
		||||
            mutableState.update {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
package eu.kanade.tachiyomi.ui.browse.migration.search
 | 
			
		||||
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import eu.kanade.tachiyomi.source.CatalogueSource
 | 
			
		||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchScreenModel
 | 
			
		||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SourceFilter
 | 
			
		||||
@@ -16,7 +16,7 @@ class MigrateSearchScreenModel(
 | 
			
		||||
) : SearchScreenModel() {
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            val manga = getManga.await(mangaId)!!
 | 
			
		||||
            mutableState.update {
 | 
			
		||||
                it.copy(
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.migration.sources
 | 
			
		||||
 | 
			
		||||
import androidx.compose.runtime.Immutable
 | 
			
		||||
import cafe.adriel.voyager.core.model.StateScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import eu.kanade.domain.source.interactor.GetSourcesWithFavoriteCount
 | 
			
		||||
import eu.kanade.domain.source.interactor.SetMigrateSorting
 | 
			
		||||
import eu.kanade.domain.source.service.SourcePreferences
 | 
			
		||||
@@ -30,7 +30,7 @@ class MigrateSourceScreenModel(
 | 
			
		||||
    val channel = _channel.receiveAsFlow()
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            getSourcesWithFavoriteCount.subscribe()
 | 
			
		||||
                .catch {
 | 
			
		||||
                    logcat(LogPriority.ERROR, it)
 | 
			
		||||
@@ -48,11 +48,11 @@ class MigrateSourceScreenModel(
 | 
			
		||||
 | 
			
		||||
        preferences.migrationSortingDirection().changes()
 | 
			
		||||
            .onEach { mutableState.update { state -> state.copy(sortingDirection = it) } }
 | 
			
		||||
            .launchIn(coroutineScope)
 | 
			
		||||
            .launchIn(screenModelScope)
 | 
			
		||||
 | 
			
		||||
        preferences.migrationSortingMode().changes()
 | 
			
		||||
            .onEach { mutableState.update { state -> state.copy(sortingMode = it) } }
 | 
			
		||||
            .launchIn(coroutineScope)
 | 
			
		||||
            .launchIn(screenModelScope)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun toggleSortingMode() {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.source
 | 
			
		||||
 | 
			
		||||
import androidx.compose.runtime.Immutable
 | 
			
		||||
import cafe.adriel.voyager.core.model.StateScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import eu.kanade.domain.source.interactor.GetLanguagesWithSources
 | 
			
		||||
import eu.kanade.domain.source.interactor.ToggleLanguage
 | 
			
		||||
import eu.kanade.domain.source.interactor.ToggleSource
 | 
			
		||||
@@ -25,7 +25,7 @@ class SourcesFilterScreenModel(
 | 
			
		||||
) : StateScreenModel<SourcesFilterScreenModel.State>(State.Loading) {
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            combine(
 | 
			
		||||
                getLanguagesWithSources.subscribe(),
 | 
			
		||||
                preferences.enabledLanguages().changes(),
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.source
 | 
			
		||||
 | 
			
		||||
import androidx.compose.runtime.Immutable
 | 
			
		||||
import cafe.adriel.voyager.core.model.StateScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import eu.kanade.domain.source.interactor.GetEnabledSources
 | 
			
		||||
import eu.kanade.domain.source.interactor.ToggleSource
 | 
			
		||||
import eu.kanade.domain.source.interactor.ToggleSourcePin
 | 
			
		||||
@@ -31,7 +31,7 @@ class SourcesScreenModel(
 | 
			
		||||
    val events = _events.receiveAsFlow()
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            getEnabledSources.subscribe()
 | 
			
		||||
                .catch {
 | 
			
		||||
                    logcat(LogPriority.ERROR, it)
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ import androidx.paging.cachedIn
 | 
			
		||||
import androidx.paging.filter
 | 
			
		||||
import androidx.paging.map
 | 
			
		||||
import cafe.adriel.voyager.core.model.StateScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import eu.kanade.core.preference.asState
 | 
			
		||||
import eu.kanade.domain.base.BasePreferences
 | 
			
		||||
import eu.kanade.domain.manga.interactor.UpdateManga
 | 
			
		||||
@@ -72,7 +72,7 @@ class BrowseSourceScreenModel(
 | 
			
		||||
    private val addTracks: AddTracks = Injekt.get(),
 | 
			
		||||
) : StateScreenModel<BrowseSourceScreenModel.State>(State(Listing.valueOf(listingQuery))) {
 | 
			
		||||
 | 
			
		||||
    var displayMode by sourcePreferences.sourceDisplayMode().asState(coroutineScope)
 | 
			
		||||
    var displayMode by sourcePreferences.sourceDisplayMode().asState(screenModelScope)
 | 
			
		||||
 | 
			
		||||
    val source = sourceManager.getOrStub(sourceId)
 | 
			
		||||
 | 
			
		||||
@@ -220,7 +220,7 @@ class BrowseSourceScreenModel(
 | 
			
		||||
     * @param manga the manga to update.
 | 
			
		||||
     */
 | 
			
		||||
    fun changeMangaFavorite(manga: Manga) {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            var new = manga.copy(
 | 
			
		||||
                favorite = !manga.favorite,
 | 
			
		||||
                dateAdded = when (manga.favorite) {
 | 
			
		||||
@@ -241,7 +241,7 @@ class BrowseSourceScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun addFavorite(manga: Manga) {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            val categories = getCategories()
 | 
			
		||||
            val defaultCategoryId = libraryPreferences.defaultCategory().get()
 | 
			
		||||
            val defaultCategory = categories.find { it.id == defaultCategoryId.toLong() }
 | 
			
		||||
@@ -291,7 +291,7 @@ class BrowseSourceScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun moveMangaToCategories(manga: Manga, categoryIds: List<Long>) {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            setMangaCategories.await(
 | 
			
		||||
                mangaId = manga.id,
 | 
			
		||||
                categoryIds = categoryIds.toList(),
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.ui.category
 | 
			
		||||
import androidx.annotation.StringRes
 | 
			
		||||
import androidx.compose.runtime.Immutable
 | 
			
		||||
import cafe.adriel.voyager.core.model.StateScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import kotlinx.coroutines.channels.Channel
 | 
			
		||||
import kotlinx.coroutines.flow.collectLatest
 | 
			
		||||
@@ -31,7 +31,7 @@ class CategoryScreenModel(
 | 
			
		||||
    val events = _events.receiveAsFlow()
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            getCategories.subscribe()
 | 
			
		||||
                .collectLatest { categories ->
 | 
			
		||||
                    mutableState.update {
 | 
			
		||||
@@ -44,7 +44,7 @@ class CategoryScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun createCategory(name: String) {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            when (createCategoryWithName.await(name)) {
 | 
			
		||||
                is CreateCategoryWithName.Result.InternalError -> _events.send(CategoryEvent.InternalError)
 | 
			
		||||
                else -> {}
 | 
			
		||||
@@ -53,7 +53,7 @@ class CategoryScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun deleteCategory(categoryId: Long) {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            when (deleteCategory.await(categoryId = categoryId)) {
 | 
			
		||||
                is DeleteCategory.Result.InternalError -> _events.send(CategoryEvent.InternalError)
 | 
			
		||||
                else -> {}
 | 
			
		||||
@@ -62,7 +62,7 @@ class CategoryScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun sortAlphabetically() {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            when (reorderCategory.sortAlphabetically()) {
 | 
			
		||||
                is ReorderCategory.Result.InternalError -> _events.send(CategoryEvent.InternalError)
 | 
			
		||||
                else -> {}
 | 
			
		||||
@@ -71,7 +71,7 @@ class CategoryScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun moveUp(category: Category) {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            when (reorderCategory.moveUp(category)) {
 | 
			
		||||
                is ReorderCategory.Result.InternalError -> _events.send(CategoryEvent.InternalError)
 | 
			
		||||
                else -> {}
 | 
			
		||||
@@ -80,7 +80,7 @@ class CategoryScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun moveDown(category: Category) {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            when (reorderCategory.moveDown(category)) {
 | 
			
		||||
                is ReorderCategory.Result.InternalError -> _events.send(CategoryEvent.InternalError)
 | 
			
		||||
                else -> {}
 | 
			
		||||
@@ -89,7 +89,7 @@ class CategoryScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun renameCategory(category: Category, name: String) {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            when (renameCategory.await(category, name)) {
 | 
			
		||||
                is RenameCategory.Result.InternalError -> _events.send(CategoryEvent.InternalError)
 | 
			
		||||
                else -> {}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.deeplink
 | 
			
		||||
 | 
			
		||||
import androidx.compose.runtime.Immutable
 | 
			
		||||
import cafe.adriel.voyager.core.model.StateScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
 | 
			
		||||
import eu.kanade.domain.manga.model.toDomainManga
 | 
			
		||||
import eu.kanade.domain.manga.model.toSManga
 | 
			
		||||
@@ -32,7 +32,7 @@ class DeepLinkScreenModel(
 | 
			
		||||
) : StateScreenModel<DeepLinkScreenModel.State>(State.Loading) {
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            val source = sourceManager.getCatalogueSources()
 | 
			
		||||
                .filterIsInstance<ResolvableSource>()
 | 
			
		||||
                .firstOrNull { it.getUriType(query) != UriType.Unknown }
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.download
 | 
			
		||||
 | 
			
		||||
import android.view.MenuItem
 | 
			
		||||
import cafe.adriel.voyager.core.model.ScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.data.download.DownloadManager
 | 
			
		||||
import eu.kanade.tachiyomi.data.download.model.Download
 | 
			
		||||
@@ -114,7 +114,7 @@ class DownloadQueueScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            downloadManager.queueState
 | 
			
		||||
                .map { downloads ->
 | 
			
		||||
                    downloads
 | 
			
		||||
@@ -208,7 +208,7 @@ class DownloadQueueScreenModel(
 | 
			
		||||
     * @param download the download to observe its progress.
 | 
			
		||||
     */
 | 
			
		||||
    private fun launchProgressJob(download: Download) {
 | 
			
		||||
        val job = coroutineScope.launch {
 | 
			
		||||
        val job = screenModelScope.launch {
 | 
			
		||||
            while (download.pages == null) {
 | 
			
		||||
                delay(50)
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.history
 | 
			
		||||
 | 
			
		||||
import androidx.compose.runtime.Immutable
 | 
			
		||||
import cafe.adriel.voyager.core.model.StateScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import eu.kanade.core.util.insertSeparators
 | 
			
		||||
import eu.kanade.presentation.history.HistoryUiModel
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.toDateKey
 | 
			
		||||
@@ -40,7 +40,7 @@ class HistoryScreenModel(
 | 
			
		||||
    val events: Flow<Event> = _events.receiveAsFlow()
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            state.map { it.searchQuery }
 | 
			
		||||
                .distinctUntilChanged()
 | 
			
		||||
                .flatMapLatest { query ->
 | 
			
		||||
@@ -75,7 +75,7 @@ class HistoryScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun getNextChapterForManga(mangaId: Long, chapterId: Long) {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            sendNextChapterEvent(getNextChapters.await(mangaId, chapterId, onlyUnread = false))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -86,19 +86,19 @@ class HistoryScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun removeFromHistory(history: HistoryWithRelations) {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            removeHistory.await(history)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun removeAllFromHistory(mangaId: Long) {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            removeHistory.await(mangaId)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun removeAllHistory() {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            val result = removeHistory.awaitAll()
 | 
			
		||||
            if (!result) return@launchIO
 | 
			
		||||
            _events.send(Event.HistoryCleared)
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ import androidx.compose.runtime.setValue
 | 
			
		||||
import androidx.compose.ui.util.fastAny
 | 
			
		||||
import androidx.compose.ui.util.fastMap
 | 
			
		||||
import cafe.adriel.voyager.core.model.StateScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import eu.kanade.core.preference.PreferenceMutableState
 | 
			
		||||
import eu.kanade.core.preference.asState
 | 
			
		||||
import eu.kanade.core.util.fastDistinctBy
 | 
			
		||||
@@ -91,10 +91,10 @@ class LibraryScreenModel(
 | 
			
		||||
    private val trackerManager: TrackerManager = Injekt.get(),
 | 
			
		||||
) : StateScreenModel<LibraryScreenModel.State>(State()) {
 | 
			
		||||
 | 
			
		||||
    var activeCategoryIndex: Int by libraryPreferences.lastUsedCategory().asState(coroutineScope)
 | 
			
		||||
    var activeCategoryIndex: Int by libraryPreferences.lastUsedCategory().asState(screenModelScope)
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            combine(
 | 
			
		||||
                state.map { it.searchQuery }.distinctUntilChanged().debounce(SEARCH_DEBOUNCE_MILLIS),
 | 
			
		||||
                getLibraryFlow(),
 | 
			
		||||
@@ -139,7 +139,7 @@ class LibraryScreenModel(
 | 
			
		||||
                    )
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            .launchIn(coroutineScope)
 | 
			
		||||
            .launchIn(screenModelScope)
 | 
			
		||||
 | 
			
		||||
        combine(
 | 
			
		||||
            getLibraryItemPreferencesFlow(),
 | 
			
		||||
@@ -161,7 +161,7 @@ class LibraryScreenModel(
 | 
			
		||||
                    state.copy(hasActiveFilters = it)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            .launchIn(coroutineScope)
 | 
			
		||||
            .launchIn(screenModelScope)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -429,7 +429,7 @@ class LibraryScreenModel(
 | 
			
		||||
     * @param amount the amount to queue or null to queue all
 | 
			
		||||
     */
 | 
			
		||||
    private fun downloadUnreadChapters(mangas: List<Manga>, amount: Int?) {
 | 
			
		||||
        coroutineScope.launchNonCancellable {
 | 
			
		||||
        screenModelScope.launchNonCancellable {
 | 
			
		||||
            mangas.forEach { manga ->
 | 
			
		||||
                val chapters = getNextChapters.await(manga.id)
 | 
			
		||||
                    .fastFilterNot { chapter ->
 | 
			
		||||
@@ -453,7 +453,7 @@ class LibraryScreenModel(
 | 
			
		||||
     */
 | 
			
		||||
    fun markReadSelection(read: Boolean) {
 | 
			
		||||
        val mangas = state.value.selection.toList()
 | 
			
		||||
        coroutineScope.launchNonCancellable {
 | 
			
		||||
        screenModelScope.launchNonCancellable {
 | 
			
		||||
            mangas.forEach { manga ->
 | 
			
		||||
                setReadStatus.await(
 | 
			
		||||
                    manga = manga.manga,
 | 
			
		||||
@@ -472,7 +472,7 @@ class LibraryScreenModel(
 | 
			
		||||
     * @param deleteChapters whether to delete downloaded chapters.
 | 
			
		||||
     */
 | 
			
		||||
    fun removeMangas(mangaList: List<Manga>, deleteFromLibrary: Boolean, deleteChapters: Boolean) {
 | 
			
		||||
        coroutineScope.launchNonCancellable {
 | 
			
		||||
        screenModelScope.launchNonCancellable {
 | 
			
		||||
            val mangaToDelete = mangaList.distinctBy { it.id }
 | 
			
		||||
 | 
			
		||||
            if (deleteFromLibrary) {
 | 
			
		||||
@@ -505,7 +505,7 @@ class LibraryScreenModel(
 | 
			
		||||
     * @param removeCategories the categories to remove in all mangas.
 | 
			
		||||
     */
 | 
			
		||||
    fun setMangaCategories(mangaList: List<Manga>, addCategories: List<Long>, removeCategories: List<Long>) {
 | 
			
		||||
        coroutineScope.launchNonCancellable {
 | 
			
		||||
        screenModelScope.launchNonCancellable {
 | 
			
		||||
            mangaList.forEach { manga ->
 | 
			
		||||
                val categoryIds = getCategories.await(manga.id)
 | 
			
		||||
                    .map { it.id }
 | 
			
		||||
@@ -519,11 +519,11 @@ class LibraryScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun getDisplayMode(): PreferenceMutableState<LibraryDisplayMode> {
 | 
			
		||||
        return libraryPreferences.displayMode().asState(coroutineScope)
 | 
			
		||||
        return libraryPreferences.displayMode().asState(screenModelScope)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun getColumnsPreferenceForCurrentOrientation(isLandscape: Boolean): PreferenceMutableState<Int> {
 | 
			
		||||
        return (if (isLandscape) libraryPreferences.landscapeColumns() else libraryPreferences.portraitColumns()).asState(coroutineScope)
 | 
			
		||||
        return (if (isLandscape) libraryPreferences.landscapeColumns() else libraryPreferences.portraitColumns()).asState(screenModelScope)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun getRandomLibraryItemForCurrentCategory(): LibraryItem? {
 | 
			
		||||
@@ -626,7 +626,7 @@ class LibraryScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun openChangeCategoryDialog() {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            // Create a copy of selected manga
 | 
			
		||||
            val mangaList = state.value.selection.map { it.manga }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
package eu.kanade.tachiyomi.ui.library
 | 
			
		||||
 | 
			
		||||
import cafe.adriel.voyager.core.model.ScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import eu.kanade.domain.base.BasePreferences
 | 
			
		||||
import eu.kanade.tachiyomi.data.track.TrackerManager
 | 
			
		||||
import tachiyomi.core.preference.Preference
 | 
			
		||||
@@ -43,7 +43,7 @@ class LibrarySettingsScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun setSort(category: Category?, mode: LibrarySort.Type, direction: LibrarySort.Direction) {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            setSortModeForCategory.await(category, mode, direction)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ import android.content.Context
 | 
			
		||||
import android.net.Uri
 | 
			
		||||
import androidx.compose.material3.SnackbarHostState
 | 
			
		||||
import cafe.adriel.voyager.core.model.StateScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import coil.imageLoader
 | 
			
		||||
import coil.request.ImageRequest
 | 
			
		||||
import coil.size.Size
 | 
			
		||||
@@ -40,14 +40,14 @@ class MangaCoverScreenModel(
 | 
			
		||||
) : StateScreenModel<Manga?>(null) {
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            getManga.subscribe(mangaId)
 | 
			
		||||
                .collect { newManga -> mutableState.update { newManga } }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun saveCover(context: Context) {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            try {
 | 
			
		||||
                saveCoverInternal(context, temp = false)
 | 
			
		||||
                snackbarHostState.showSnackbar(
 | 
			
		||||
@@ -65,7 +65,7 @@ class MangaCoverScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun shareCover(context: Context) {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            try {
 | 
			
		||||
                val uri = saveCoverInternal(context, temp = true) ?: return@launch
 | 
			
		||||
                withUIContext {
 | 
			
		||||
@@ -117,7 +117,7 @@ class MangaCoverScreenModel(
 | 
			
		||||
     */
 | 
			
		||||
    fun editCover(context: Context, data: Uri) {
 | 
			
		||||
        val manga = state.value ?: return
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            context.contentResolver.openInputStream(data)?.use {
 | 
			
		||||
                try {
 | 
			
		||||
                    manga.editCover(Injekt.get(), it, updateManga, coverCache)
 | 
			
		||||
@@ -131,7 +131,7 @@ class MangaCoverScreenModel(
 | 
			
		||||
 | 
			
		||||
    fun deleteCustomCover(context: Context) {
 | 
			
		||||
        val mangaId = state.value?.id ?: return
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            try {
 | 
			
		||||
                coverCache.deleteCustomCover(mangaId)
 | 
			
		||||
                updateManga.awaitUpdateCoverLastModified(mangaId)
 | 
			
		||||
@@ -143,7 +143,7 @@ class MangaCoverScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun notifyCoverUpdated(context: Context) {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            snackbarHostState.showSnackbar(
 | 
			
		||||
                context.getString(R.string.cover_updated),
 | 
			
		||||
                withDismissAction = true,
 | 
			
		||||
@@ -152,7 +152,7 @@ class MangaCoverScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun notifyFailedCoverUpdate(context: Context, e: Throwable) {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            snackbarHostState.showSnackbar(
 | 
			
		||||
                context.getString(R.string.notification_cover_update_failed),
 | 
			
		||||
                withDismissAction = true,
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ import androidx.compose.runtime.Immutable
 | 
			
		||||
import androidx.compose.runtime.getValue
 | 
			
		||||
import androidx.compose.runtime.mutableStateOf
 | 
			
		||||
import cafe.adriel.voyager.core.model.StateScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import eu.kanade.core.preference.asState
 | 
			
		||||
import eu.kanade.core.util.addOrRemove
 | 
			
		||||
import eu.kanade.domain.chapter.interactor.SetReadStatus
 | 
			
		||||
@@ -126,9 +126,9 @@ class MangaScreenModel(
 | 
			
		||||
    val chapterSwipeStartAction = libraryPreferences.swipeToEndAction().get()
 | 
			
		||||
    val chapterSwipeEndAction = libraryPreferences.swipeToStartAction().get()
 | 
			
		||||
 | 
			
		||||
    val relativeTime by uiPreferences.relativeTime().asState(coroutineScope)
 | 
			
		||||
    val relativeTime by uiPreferences.relativeTime().asState(screenModelScope)
 | 
			
		||||
    val dateFormat by mutableStateOf(UiPreferences.dateFormat(uiPreferences.dateFormat().get()))
 | 
			
		||||
    private val skipFiltered by readerPreferences.skipFiltered().asState(coroutineScope)
 | 
			
		||||
    private val skipFiltered by readerPreferences.skipFiltered().asState(screenModelScope)
 | 
			
		||||
 | 
			
		||||
    val isUpdateIntervalEnabled = LibraryPreferences.MANGA_OUTSIDE_RELEASE_PERIOD in libraryPreferences.autoUpdateMangaRestrictions().get()
 | 
			
		||||
 | 
			
		||||
@@ -148,7 +148,7 @@ class MangaScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            combine(
 | 
			
		||||
                getMangaAndChapters.subscribe(mangaId).distinctUntilChanged(),
 | 
			
		||||
                downloadCache.changes,
 | 
			
		||||
@@ -166,7 +166,7 @@ class MangaScreenModel(
 | 
			
		||||
 | 
			
		||||
        observeDownloads()
 | 
			
		||||
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            val manga = getMangaAndChapters.awaitManga(mangaId)
 | 
			
		||||
            val chapters = getMangaAndChapters.awaitChapters(mangaId)
 | 
			
		||||
                .toChapterItems(manga)
 | 
			
		||||
@@ -194,7 +194,7 @@ class MangaScreenModel(
 | 
			
		||||
            observeTrackers()
 | 
			
		||||
 | 
			
		||||
            // Fetch info-chapters when needed
 | 
			
		||||
            if (coroutineScope.isActive) {
 | 
			
		||||
            if (screenModelScope.isActive) {
 | 
			
		||||
                val fetchFromSourceTasks = listOf(
 | 
			
		||||
                    async { if (needRefreshInfo) fetchMangaFromSource() },
 | 
			
		||||
                    async { if (needRefreshChapter) fetchChaptersFromSource() },
 | 
			
		||||
@@ -208,7 +208,7 @@ class MangaScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun fetchAllFromSource(manualFetch: Boolean = true) {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            updateSuccessState { it.copy(isRefreshingData = true) }
 | 
			
		||||
            val fetchFromSourceTasks = listOf(
 | 
			
		||||
                async { fetchMangaFromSource(manualFetch) },
 | 
			
		||||
@@ -236,7 +236,7 @@ class MangaScreenModel(
 | 
			
		||||
            if (e is HttpException && e.code == 103) return
 | 
			
		||||
 | 
			
		||||
            logcat(LogPriority.ERROR, e)
 | 
			
		||||
            coroutineScope.launch {
 | 
			
		||||
            screenModelScope.launch {
 | 
			
		||||
                snackbarHostState.showSnackbar(message = with(context) { e.formattedMessage })
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -245,7 +245,7 @@ class MangaScreenModel(
 | 
			
		||||
    fun toggleFavorite() {
 | 
			
		||||
        toggleFavorite(
 | 
			
		||||
            onRemoved = {
 | 
			
		||||
                coroutineScope.launch {
 | 
			
		||||
                screenModelScope.launch {
 | 
			
		||||
                    if (!hasDownloads()) return@launch
 | 
			
		||||
                    val result = snackbarHostState.showSnackbar(
 | 
			
		||||
                        message = context.getString(R.string.delete_downloads_for_manga),
 | 
			
		||||
@@ -268,7 +268,7 @@ class MangaScreenModel(
 | 
			
		||||
        checkDuplicate: Boolean = true,
 | 
			
		||||
    ) {
 | 
			
		||||
        val state = successState ?: return
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            val manga = state.manga
 | 
			
		||||
 | 
			
		||||
            if (isFavorited) {
 | 
			
		||||
@@ -323,7 +323,7 @@ class MangaScreenModel(
 | 
			
		||||
 | 
			
		||||
    fun showChangeCategoryDialog() {
 | 
			
		||||
        val manga = successState?.manga ?: return
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            val categories = getCategories()
 | 
			
		||||
            val selection = getMangaCategoryIds(manga)
 | 
			
		||||
            updateSuccessState { successState ->
 | 
			
		||||
@@ -345,7 +345,7 @@ class MangaScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun setFetchInterval(manga: Manga, interval: Int) {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            updateManga.awaitUpdateFetchInterval(
 | 
			
		||||
                // Custom intervals are negative
 | 
			
		||||
                manga.copy(fetchInterval = -interval),
 | 
			
		||||
@@ -395,7 +395,7 @@ class MangaScreenModel(
 | 
			
		||||
        moveMangaToCategory(categories)
 | 
			
		||||
        if (manga.favorite) return
 | 
			
		||||
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            updateManga.awaitUpdateFavorite(manga.id, true)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -411,7 +411,7 @@ class MangaScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun moveMangaToCategory(categoryIds: List<Long>) {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            setMangaCategories.await(mangaId, categoryIds)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -430,7 +430,7 @@ class MangaScreenModel(
 | 
			
		||||
    // Chapters list - start
 | 
			
		||||
 | 
			
		||||
    private fun observeDownloads() {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            downloadManager.statusFlow()
 | 
			
		||||
                .filter { it.manga.id == successState?.manga?.id }
 | 
			
		||||
                .catch { error -> logcat(LogPriority.ERROR, error) }
 | 
			
		||||
@@ -441,7 +441,7 @@ class MangaScreenModel(
 | 
			
		||||
                }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            downloadManager.progressFlow()
 | 
			
		||||
                .filter { it.manga.id == successState?.manga?.id }
 | 
			
		||||
                .catch { error -> logcat(LogPriority.ERROR, error) }
 | 
			
		||||
@@ -523,7 +523,7 @@ class MangaScreenModel(
 | 
			
		||||
                with(context) { e.formattedMessage }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            coroutineScope.launch {
 | 
			
		||||
            screenModelScope.launch {
 | 
			
		||||
                snackbarHostState.showSnackbar(message = message)
 | 
			
		||||
            }
 | 
			
		||||
            val newManga = mangaRepository.getMangaById(mangaId)
 | 
			
		||||
@@ -535,7 +535,7 @@ class MangaScreenModel(
 | 
			
		||||
     * @throws IllegalStateException if the swipe action is [LibraryPreferences.ChapterSwipeAction.Disabled]
 | 
			
		||||
     */
 | 
			
		||||
    fun chapterSwipe(chapterItem: ChapterItem, swipeAction: LibraryPreferences.ChapterSwipeAction) {
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            executeChapterSwipeAction(chapterItem, swipeAction)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -612,7 +612,7 @@ class MangaScreenModel(
 | 
			
		||||
            updateSuccessState { state ->
 | 
			
		||||
                state.copy(hasPromptedToAddBefore = true)
 | 
			
		||||
            }
 | 
			
		||||
            coroutineScope.launch {
 | 
			
		||||
            screenModelScope.launch {
 | 
			
		||||
                val result = snackbarHostState.showSnackbar(
 | 
			
		||||
                    message = context.getString(R.string.snack_add_to_library),
 | 
			
		||||
                    actionLabel = context.getString(R.string.action_add),
 | 
			
		||||
@@ -683,7 +683,7 @@ class MangaScreenModel(
 | 
			
		||||
     * @param read whether to mark chapters as read or unread.
 | 
			
		||||
     */
 | 
			
		||||
    fun markChaptersRead(chapters: List<Chapter>, read: Boolean) {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            setReadStatus.await(
 | 
			
		||||
                read = read,
 | 
			
		||||
                chapters = chapters.toTypedArray(),
 | 
			
		||||
@@ -707,7 +707,7 @@ class MangaScreenModel(
 | 
			
		||||
     * @param chapters the list of chapters to bookmark.
 | 
			
		||||
     */
 | 
			
		||||
    fun bookmarkChapters(chapters: List<Chapter>, bookmarked: Boolean) {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            chapters
 | 
			
		||||
                .filterNot { it.bookmark == bookmarked }
 | 
			
		||||
                .map { ChapterUpdate(id = it.id, bookmark = bookmarked) }
 | 
			
		||||
@@ -722,7 +722,7 @@ class MangaScreenModel(
 | 
			
		||||
     * @param chapters the list of chapters to delete.
 | 
			
		||||
     */
 | 
			
		||||
    fun deleteChapters(chapters: List<Chapter>) {
 | 
			
		||||
        coroutineScope.launchNonCancellable {
 | 
			
		||||
        screenModelScope.launchNonCancellable {
 | 
			
		||||
            try {
 | 
			
		||||
                successState?.let { state ->
 | 
			
		||||
                    downloadManager.deleteChapters(
 | 
			
		||||
@@ -738,7 +738,7 @@ class MangaScreenModel(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun downloadNewChapters(chapters: List<Chapter>) {
 | 
			
		||||
        coroutineScope.launchNonCancellable {
 | 
			
		||||
        screenModelScope.launchNonCancellable {
 | 
			
		||||
            val manga = successState?.manga ?: return@launchNonCancellable
 | 
			
		||||
            val categories = getCategories.await(manga.id).map { it.id }
 | 
			
		||||
            if (chapters.isEmpty() || !manga.shouldDownloadNewChapters(categories, downloadPreferences)) return@launchNonCancellable
 | 
			
		||||
@@ -758,7 +758,7 @@ class MangaScreenModel(
 | 
			
		||||
            TriState.ENABLED_IS -> Manga.CHAPTER_SHOW_UNREAD
 | 
			
		||||
            TriState.ENABLED_NOT -> Manga.CHAPTER_SHOW_READ
 | 
			
		||||
        }
 | 
			
		||||
        coroutineScope.launchNonCancellable {
 | 
			
		||||
        screenModelScope.launchNonCancellable {
 | 
			
		||||
            setMangaChapterFlags.awaitSetUnreadFilter(manga, flag)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -776,7 +776,7 @@ class MangaScreenModel(
 | 
			
		||||
            TriState.ENABLED_NOT -> Manga.CHAPTER_SHOW_NOT_DOWNLOADED
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        coroutineScope.launchNonCancellable {
 | 
			
		||||
        screenModelScope.launchNonCancellable {
 | 
			
		||||
            setMangaChapterFlags.awaitSetDownloadedFilter(manga, flag)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -794,7 +794,7 @@ class MangaScreenModel(
 | 
			
		||||
            TriState.ENABLED_NOT -> Manga.CHAPTER_SHOW_NOT_BOOKMARKED
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        coroutineScope.launchNonCancellable {
 | 
			
		||||
        screenModelScope.launchNonCancellable {
 | 
			
		||||
            setMangaChapterFlags.awaitSetBookmarkFilter(manga, flag)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -806,7 +806,7 @@ class MangaScreenModel(
 | 
			
		||||
    fun setDisplayMode(mode: Long) {
 | 
			
		||||
        val manga = successState?.manga ?: return
 | 
			
		||||
 | 
			
		||||
        coroutineScope.launchNonCancellable {
 | 
			
		||||
        screenModelScope.launchNonCancellable {
 | 
			
		||||
            setMangaChapterFlags.awaitSetDisplayMode(manga, mode)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -818,14 +818,14 @@ class MangaScreenModel(
 | 
			
		||||
    fun setSorting(sort: Long) {
 | 
			
		||||
        val manga = successState?.manga ?: return
 | 
			
		||||
 | 
			
		||||
        coroutineScope.launchNonCancellable {
 | 
			
		||||
        screenModelScope.launchNonCancellable {
 | 
			
		||||
            setMangaChapterFlags.awaitSetSortingModeOrFlipOrder(manga, sort)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun setCurrentSettingsAsDefault(applyToExisting: Boolean) {
 | 
			
		||||
        val manga = successState?.manga ?: return
 | 
			
		||||
        coroutineScope.launchNonCancellable {
 | 
			
		||||
        screenModelScope.launchNonCancellable {
 | 
			
		||||
            libraryPreferences.setChapterSettingsDefault(manga)
 | 
			
		||||
            if (applyToExisting) {
 | 
			
		||||
                setMangaDefaultChapterFlags.awaitAll()
 | 
			
		||||
@@ -929,7 +929,7 @@ class MangaScreenModel(
 | 
			
		||||
    private fun observeTrackers() {
 | 
			
		||||
        val manga = successState?.manga ?: return
 | 
			
		||||
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            getTracks.subscribe(manga.id)
 | 
			
		||||
                .catch { logcat(LogPriority.ERROR, it) }
 | 
			
		||||
                .map { tracks ->
 | 
			
		||||
 
 | 
			
		||||
@@ -34,8 +34,8 @@ import androidx.compose.ui.text.style.TextAlign
 | 
			
		||||
import androidx.compose.ui.unit.dp
 | 
			
		||||
import cafe.adriel.voyager.core.model.ScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.StateScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.rememberScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import cafe.adriel.voyager.navigator.LocalNavigator
 | 
			
		||||
import cafe.adriel.voyager.navigator.Navigator
 | 
			
		||||
import cafe.adriel.voyager.navigator.currentOrThrow
 | 
			
		||||
@@ -188,11 +188,11 @@ data class TrackInfoDialogHomeScreen(
 | 
			
		||||
    ) : StateScreenModel<Model.State>(State()) {
 | 
			
		||||
 | 
			
		||||
        init {
 | 
			
		||||
            coroutineScope.launch {
 | 
			
		||||
            screenModelScope.launch {
 | 
			
		||||
                refreshTrackers()
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            coroutineScope.launch {
 | 
			
		||||
            screenModelScope.launch {
 | 
			
		||||
                getTracks.subscribe(mangaId)
 | 
			
		||||
                    .catch { logcat(LogPriority.ERROR, it) }
 | 
			
		||||
                    .distinctUntilChanged()
 | 
			
		||||
@@ -203,7 +203,7 @@ data class TrackInfoDialogHomeScreen(
 | 
			
		||||
 | 
			
		||||
        fun registerEnhancedTracking(item: TrackItem) {
 | 
			
		||||
            item.tracker as EnhancedTracker
 | 
			
		||||
            coroutineScope.launchNonCancellable {
 | 
			
		||||
            screenModelScope.launchNonCancellable {
 | 
			
		||||
                val manga = Injekt.get<GetManga>().await(mangaId) ?: return@launchNonCancellable
 | 
			
		||||
                try {
 | 
			
		||||
                    val matchResult = item.tracker.match(manga) ?: throw Exception()
 | 
			
		||||
@@ -294,7 +294,7 @@ private data class TrackStatusSelectorScreen(
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fun setStatus() {
 | 
			
		||||
            coroutineScope.launchNonCancellable {
 | 
			
		||||
            screenModelScope.launchNonCancellable {
 | 
			
		||||
                tracker.setRemoteStatus(track.toDbTrack(), state.value.selection)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -353,7 +353,7 @@ private data class TrackChapterSelectorScreen(
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fun setChapter() {
 | 
			
		||||
            coroutineScope.launchNonCancellable {
 | 
			
		||||
            screenModelScope.launchNonCancellable {
 | 
			
		||||
                tracker.setRemoteLastChapterRead(track.toDbTrack(), state.value.selection)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -407,7 +407,7 @@ private data class TrackScoreSelectorScreen(
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fun setScore() {
 | 
			
		||||
            coroutineScope.launchNonCancellable {
 | 
			
		||||
            screenModelScope.launchNonCancellable {
 | 
			
		||||
                tracker.setRemoteScore(track.toDbTrack(), state.value.selection)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -533,7 +533,7 @@ private data class TrackDateSelectorScreen(
 | 
			
		||||
        fun setDate(millis: Long) {
 | 
			
		||||
            // Convert to local time
 | 
			
		||||
            val localMillis = millis.convertEpochMillisZone(ZoneOffset.UTC, ZoneOffset.systemDefault())
 | 
			
		||||
            coroutineScope.launchNonCancellable {
 | 
			
		||||
            screenModelScope.launchNonCancellable {
 | 
			
		||||
                if (start) {
 | 
			
		||||
                    tracker.setRemoteStartDate(track.toDbTrack(), localMillis)
 | 
			
		||||
                } else {
 | 
			
		||||
@@ -622,7 +622,7 @@ private data class TrackDateRemoverScreen(
 | 
			
		||||
        fun getServiceName() = tracker.name
 | 
			
		||||
 | 
			
		||||
        fun removeDate() {
 | 
			
		||||
            coroutineScope.launchNonCancellable {
 | 
			
		||||
            screenModelScope.launchNonCancellable {
 | 
			
		||||
                if (start) {
 | 
			
		||||
                    tracker.setRemoteStartDate(track.toDbTrack(), 0)
 | 
			
		||||
                } else {
 | 
			
		||||
@@ -685,7 +685,7 @@ data class TrackerSearchScreen(
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fun trackingSearch(query: String) {
 | 
			
		||||
            coroutineScope.launch {
 | 
			
		||||
            screenModelScope.launch {
 | 
			
		||||
                // To show loading state
 | 
			
		||||
                mutableState.update { it.copy(queryResult = null, selected = null) }
 | 
			
		||||
 | 
			
		||||
@@ -707,7 +707,7 @@ data class TrackerSearchScreen(
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fun registerTracking(item: TrackSearch) {
 | 
			
		||||
            coroutineScope.launchNonCancellable { tracker.register(item, mangaId) }
 | 
			
		||||
            screenModelScope.launchNonCancellable { tracker.register(item, mangaId) }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fun updateSelection(selected: TrackSearch) {
 | 
			
		||||
@@ -812,13 +812,13 @@ private data class TrackerRemoveScreen(
 | 
			
		||||
        fun isDeletable() = tracker is DeletableTracker
 | 
			
		||||
 | 
			
		||||
        fun deleteMangaFromService() {
 | 
			
		||||
            coroutineScope.launchNonCancellable {
 | 
			
		||||
            screenModelScope.launchNonCancellable {
 | 
			
		||||
                (tracker as DeletableTracker).delete(track.toDbTrack())
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fun unregisterTracking(serviceId: Long) {
 | 
			
		||||
            coroutineScope.launchNonCancellable { deleteTrack.await(mangaId, serviceId) }
 | 
			
		||||
            screenModelScope.launchNonCancellable { deleteTrack.await(mangaId, serviceId) }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,8 +10,8 @@ import androidx.compose.runtime.setValue
 | 
			
		||||
import androidx.compose.ui.platform.LocalContext
 | 
			
		||||
import androidx.compose.ui.res.stringResource
 | 
			
		||||
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.core.model.screenModelScope
 | 
			
		||||
import cafe.adriel.voyager.navigator.LocalNavigator
 | 
			
		||||
import cafe.adriel.voyager.navigator.Navigator
 | 
			
		||||
import cafe.adriel.voyager.navigator.currentOrThrow
 | 
			
		||||
@@ -83,15 +83,15 @@ private class MoreScreenModel(
 | 
			
		||||
    preferences: BasePreferences = Injekt.get(),
 | 
			
		||||
) : ScreenModel {
 | 
			
		||||
 | 
			
		||||
    var downloadedOnly by preferences.downloadedOnly().asState(coroutineScope)
 | 
			
		||||
    var incognitoMode by preferences.incognitoMode().asState(coroutineScope)
 | 
			
		||||
    var downloadedOnly by preferences.downloadedOnly().asState(screenModelScope)
 | 
			
		||||
    var incognitoMode by preferences.incognitoMode().asState(screenModelScope)
 | 
			
		||||
 | 
			
		||||
    private var _state: MutableStateFlow<DownloadQueueState> = MutableStateFlow(DownloadQueueState.Stopped)
 | 
			
		||||
    val downloadQueueState: StateFlow<DownloadQueueState> = _state.asStateFlow()
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        // Handle running/paused status change and queue progress updating
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            combine(
 | 
			
		||||
                downloadManager.isDownloaderRunning,
 | 
			
		||||
                downloadManager.queueState,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
package eu.kanade.tachiyomi.ui.stats
 | 
			
		||||
 | 
			
		||||
import cafe.adriel.voyager.core.model.StateScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import eu.kanade.core.util.fastCountNot
 | 
			
		||||
import eu.kanade.core.util.fastDistinctBy
 | 
			
		||||
import eu.kanade.core.util.fastFilter
 | 
			
		||||
@@ -39,7 +39,7 @@ class StatsScreenModel(
 | 
			
		||||
    private val loggedInTrackers by lazy { trackerManager.trackers.fastFilter { it.isLoggedIn } }
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            val libraryManga = getLibraryManga.await()
 | 
			
		||||
 | 
			
		||||
            val distinctLibraryManga = libraryManga.fastDistinctBy { it.id }
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ import androidx.compose.runtime.Immutable
 | 
			
		||||
import androidx.compose.runtime.getValue
 | 
			
		||||
import androidx.compose.runtime.mutableStateOf
 | 
			
		||||
import cafe.adriel.voyager.core.model.StateScreenModel
 | 
			
		||||
import cafe.adriel.voyager.core.model.coroutineScope
 | 
			
		||||
import cafe.adriel.voyager.core.model.screenModelScope
 | 
			
		||||
import eu.kanade.core.preference.asState
 | 
			
		||||
import eu.kanade.core.util.addOrRemove
 | 
			
		||||
import eu.kanade.core.util.insertSeparators
 | 
			
		||||
@@ -65,15 +65,15 @@ class UpdatesScreenModel(
 | 
			
		||||
    private val _events: Channel<Event> = Channel(Int.MAX_VALUE)
 | 
			
		||||
    val events: Flow<Event> = _events.receiveAsFlow()
 | 
			
		||||
 | 
			
		||||
    val lastUpdated by libraryPreferences.lastUpdatedTimestamp().asState(coroutineScope)
 | 
			
		||||
    val relativeTime by uiPreferences.relativeTime().asState(coroutineScope)
 | 
			
		||||
    val lastUpdated by libraryPreferences.lastUpdatedTimestamp().asState(screenModelScope)
 | 
			
		||||
    val relativeTime by uiPreferences.relativeTime().asState(screenModelScope)
 | 
			
		||||
 | 
			
		||||
    // First and last selected index in list
 | 
			
		||||
    private val selectedPositions: Array<Int> = arrayOf(-1, -1)
 | 
			
		||||
    private val selectedChapterIds: HashSet<Long> = HashSet()
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            // Set date limit for recent chapters
 | 
			
		||||
            val calendar = Calendar.getInstance().apply {
 | 
			
		||||
                time = Date()
 | 
			
		||||
@@ -99,7 +99,7 @@ class UpdatesScreenModel(
 | 
			
		||||
                }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            merge(downloadManager.statusFlow(), downloadManager.progressFlow())
 | 
			
		||||
                .catch { logcat(LogPriority.ERROR, it) }
 | 
			
		||||
                .collect(this@UpdatesScreenModel::updateDownloadState)
 | 
			
		||||
@@ -131,7 +131,7 @@ class UpdatesScreenModel(
 | 
			
		||||
 | 
			
		||||
    fun updateLibrary(): Boolean {
 | 
			
		||||
        val started = LibraryUpdateJob.startNow(Injekt.get<Application>())
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            _events.send(Event.LibraryUpdateTriggered(started))
 | 
			
		||||
        }
 | 
			
		||||
        return started
 | 
			
		||||
@@ -163,7 +163,7 @@ class UpdatesScreenModel(
 | 
			
		||||
 | 
			
		||||
    fun downloadChapters(items: List<UpdatesItem>, action: ChapterDownloadAction) {
 | 
			
		||||
        if (items.isEmpty()) return
 | 
			
		||||
        coroutineScope.launch {
 | 
			
		||||
        screenModelScope.launch {
 | 
			
		||||
            when (action) {
 | 
			
		||||
                ChapterDownloadAction.START -> {
 | 
			
		||||
                    downloadChapters(items)
 | 
			
		||||
@@ -203,7 +203,7 @@ class UpdatesScreenModel(
 | 
			
		||||
     * @param read whether to mark chapters as read or unread.
 | 
			
		||||
     */
 | 
			
		||||
    fun markUpdatesRead(updates: List<UpdatesItem>, read: Boolean) {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            setReadStatus.await(
 | 
			
		||||
                read = read,
 | 
			
		||||
                chapters = updates
 | 
			
		||||
@@ -219,7 +219,7 @@ class UpdatesScreenModel(
 | 
			
		||||
     * @param updates the list of chapters to bookmark.
 | 
			
		||||
     */
 | 
			
		||||
    fun bookmarkUpdates(updates: List<UpdatesItem>, bookmark: Boolean) {
 | 
			
		||||
        coroutineScope.launchIO {
 | 
			
		||||
        screenModelScope.launchIO {
 | 
			
		||||
            updates
 | 
			
		||||
                .filterNot { it.update.bookmark == bookmark }
 | 
			
		||||
                .map { ChapterUpdate(id = it.update.chapterId, bookmark = bookmark) }
 | 
			
		||||
@@ -233,7 +233,7 @@ class UpdatesScreenModel(
 | 
			
		||||
     * @param updatesItem the list of chapters to download.
 | 
			
		||||
     */
 | 
			
		||||
    private fun downloadChapters(updatesItem: List<UpdatesItem>) {
 | 
			
		||||
        coroutineScope.launchNonCancellable {
 | 
			
		||||
        screenModelScope.launchNonCancellable {
 | 
			
		||||
            val groupedUpdates = updatesItem.groupBy { it.update.mangaId }.values
 | 
			
		||||
            for (updates in groupedUpdates) {
 | 
			
		||||
                val mangaId = updates.first().update.mangaId
 | 
			
		||||
@@ -252,7 +252,7 @@ class UpdatesScreenModel(
 | 
			
		||||
     * @param updatesItem list of chapters
 | 
			
		||||
     */
 | 
			
		||||
    fun deleteChapters(updatesItem: List<UpdatesItem>) {
 | 
			
		||||
        coroutineScope.launchNonCancellable {
 | 
			
		||||
        screenModelScope.launchNonCancellable {
 | 
			
		||||
            updatesItem
 | 
			
		||||
                .groupBy { it.update.mangaId }
 | 
			
		||||
                .entries
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user