Update Voyager

(cherry picked from commit 012854dd1e13eedecd92419fd6a4d1d5cc900462)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/browse/BrowseSourceScreen.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/SourcesScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/stats/StatsScreenModel.kt
This commit is contained in:
arkon 2023-10-22 15:54:31 -04:00 committed by Jobobby04
parent 41920d9e75
commit 59a6fd7dca
38 changed files with 231 additions and 215 deletions

View File

@ -34,8 +34,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
@ -230,7 +230,7 @@ private class ClearDatabaseScreenModel : StateScreenModel<ClearDatabaseScreenMod
private val database: Database = Injekt.get()
init {
coroutineScope.launchIO {
screenModelScope.launchIO {
getSourcesWithNonLibraryManga.subscribe()
.collectLatest { list ->
mutableState.update { old ->

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@ import androidx.compose.runtime.State
import androidx.compose.runtime.produceState
import androidx.compose.ui.util.fastAny
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.manga.interactor.UpdateManga
import eu.kanade.domain.manga.model.toDomainManga
import eu.kanade.domain.source.service.SourcePreferences
@ -90,12 +90,12 @@ open class FeedScreenModel(
getFeed(items)
}
.catch { _events.send(Event.FailedFetchingSources) }
.launchIn(coroutineScope)
.launchIn(screenModelScope)
}
fun init() {
pushed = false
coroutineScope.launchIO {
screenModelScope.launchIO {
val newItems = state.value.items?.map { it.copy(results = null) } ?: return@launchIO
mutableState.update { state ->
state.copy(
@ -107,7 +107,7 @@ open class FeedScreenModel(
}
fun openAddDialog() {
coroutineScope.launchIO {
screenModelScope.launchIO {
if (hasTooManyFeeds()) {
_events.send(Event.TooManyFeeds)
return@launchIO
@ -121,7 +121,7 @@ open class FeedScreenModel(
}
fun openAddSearchDialog(source: CatalogueSource) {
coroutineScope.launchIO {
screenModelScope.launchIO {
mutableState.update { state ->
state.copy(
dialog = Dialog.AddFeedSearch(source, (if (source.supportsLatest) listOf(null) else emptyList()) + getSourceSavedSearches(source.id)),
@ -131,7 +131,7 @@ open class FeedScreenModel(
}
fun openDeleteDialog(feed: FeedSavedSearch) {
coroutineScope.launchIO {
screenModelScope.launchIO {
mutableState.update { state ->
state.copy(
dialog = Dialog.DeleteFeed(feed),
@ -163,7 +163,7 @@ open class FeedScreenModel(
}
fun createFeed(source: CatalogueSource, savedSearch: SavedSearch?) {
coroutineScope.launchNonCancellable {
screenModelScope.launchNonCancellable {
insertFeedSavedSearch.await(
FeedSavedSearch(
id = -1,
@ -176,7 +176,7 @@ open class FeedScreenModel(
}
fun deleteFeed(feed: FeedSavedSearch) {
coroutineScope.launchNonCancellable {
screenModelScope.launchNonCancellable {
deleteFeedSavedSearchById.await(feed.id)
}
}
@ -215,7 +215,7 @@ open class FeedScreenModel(
* Initiates get manga per feed.
*/
private fun getFeed(feedSavedSearch: List<FeedItemUI>) {
coroutineScope.launch {
screenModelScope.launch {
feedSavedSearch.map { itemUI ->
async {
val page = try {

View File

@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.ui.browse.migration.advanced.design
import cafe.adriel.voyager.core.model.ScreenModel
import cafe.adriel.voyager.core.model.coroutineScope
import cafe.adriel.voyager.core.model.screenModelScope
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.tachiyomi.databinding.PreMigrationListBinding
@ -40,7 +40,7 @@ class PreMigrationScreenModel(
}
init {
coroutineScope.launchIO {
screenModelScope.launchIO {
val enabledSources = getEnabledSources()
_state.update { enabledSources }
}

View File

@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.ui.browse.migration.advanced.process
import android.content.Context
import android.widget.Toast
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.chapter.interactor.SyncChaptersWithSource
import eu.kanade.domain.manga.interactor.UpdateManga
import eu.kanade.domain.manga.model.hasCustomCover
@ -101,7 +101,7 @@ class MigrationListScreenModel(
private var migrateJob: Job? = null
init {
coroutineScope.launchIO {
screenModelScope.launchIO {
runMigrations(
config.mangaIds
.map {
@ -118,7 +118,7 @@ class MigrationListScreenModel(
null
},
),
parentContext = coroutineScope.coroutineContext,
parentContext = screenModelScope.coroutineContext,
)
}
}
@ -403,7 +403,7 @@ class MigrationListScreenModel(
val migratingManga = migratingItems.value.orEmpty().find { it.manga.id == selectedMangaId }
?: return
migratingManga.searchResult.value = SearchResult.Searching
coroutineScope.launchIO {
screenModelScope.launchIO {
val result = migratingManga.migrationScope.async {
val manga = getManga(newMangaId)!!
val localManga = networkToLocalManga.await(manga)
@ -447,7 +447,7 @@ class MigrationListScreenModel(
private fun migrateMangas(replace: Boolean) {
dialog.value = null
migrateJob = coroutineScope.launchIO {
migrateJob = screenModelScope.launchIO {
migratingProgress.value = 0f
val items = migratingItems.value.orEmpty()
try {
@ -494,7 +494,7 @@ class MigrationListScreenModel(
fun migrateManga(mangaId: Long, copy: Boolean) {
manualMigrations.value++
coroutineScope.launchIO {
screenModelScope.launchIO {
val manga = migratingItems.value.orEmpty().find { it.manga.id == mangaId }
?: return@launchIO
@ -511,7 +511,7 @@ class MigrationListScreenModel(
}
fun removeManga(mangaId: Long) {
coroutineScope.launchIO {
screenModelScope.launchIO {
val item = migratingItems.value.orEmpty().find { it.manga.id == mangaId }
?: return@launchIO
removeManga(item)

View File

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

View File

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

View File

@ -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
@ -23,7 +23,7 @@ class MigrateSearchScreenModel(
) : SearchScreenModel() {
init {
coroutineScope.launch {
screenModelScope.launch {
val manga = getManga.await(mangaId)!!
mutableState.update {
it.copy(

View File

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

View File

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

View File

@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.ui.browse.source
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.getValue
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.source.interactor.GetEnabledSources
import eu.kanade.domain.source.interactor.GetShowLatest
@ -52,7 +52,7 @@ class SourcesScreenModel(
private val _events = Channel<Event>(Int.MAX_VALUE)
val events = _events.receiveAsFlow()
val useNewSourceNavigation by uiPreferences.useNewSourceNavigation().asState(coroutineScope)
val useNewSourceNavigation by uiPreferences.useNewSourceNavigation().asState(screenModelScope)
init {
// SY -->
@ -68,7 +68,7 @@ class SourcesScreenModel(
_events.send(Event.FailedFetchingSources)
}
.flowOn(Dispatchers.IO)
.launchIn(coroutineScope)
.launchIn(screenModelScope)
sourcePreferences.dataSaver().changes()
.onEach {
@ -78,7 +78,7 @@ class SourcesScreenModel(
)
}
}
.launchIn(coroutineScope)
.launchIn(screenModelScope)
// SY <--
}

View File

@ -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
@ -116,14 +116,14 @@ open class BrowseSourceScreenModel(
// SY <--
) : 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)
// SY -->
val ehentaiBrowseDisplayMode by unsortedPreferences.enhancedEHentaiView().asState(coroutineScope)
val ehentaiBrowseDisplayMode by unsortedPreferences.enhancedEHentaiView().asState(screenModelScope)
val startExpanded by uiPreferences.expandFilters().asState(coroutineScope)
val startExpanded by uiPreferences.expandFilters().asState(screenModelScope)
private val filterSerializer = FilterSerializer()
@ -176,7 +176,7 @@ open class BrowseSourceScreenModel(
.onEach { savedSearches ->
mutableState.update { it.copy(savedSearches = savedSearches) }
}
.launchIn(coroutineScope)
.launchIn(screenModelScope)
}
// SY <--
}
@ -326,7 +326,7 @@ open 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) {
@ -347,7 +347,7 @@ open 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() }
@ -403,7 +403,7 @@ open class BrowseSourceScreenModel(
}
fun moveMangaToCategories(manga: Manga, categoryIds: List<Long>) {
coroutineScope.launchIO {
screenModelScope.launchIO {
setMangaCategories.await(
mangaId = manga.id,
categoryIds = categoryIds.toList(),
@ -471,7 +471,7 @@ open class BrowseSourceScreenModel(
// EXH -->
fun onSaveSearch() {
coroutineScope.launchIO {
screenModelScope.launchIO {
val names = state.value.savedSearches.map { it.name }
mutableState.update { it.copy(dialog = Dialog.CreateSavedSearch(names)) }
}
@ -481,7 +481,7 @@ open class BrowseSourceScreenModel(
search: EXHSavedSearch,
onToast: (Int) -> Unit,
) {
coroutineScope.launchIO {
screenModelScope.launchIO {
if (source !is CatalogueSource) return@launchIO
if (search.filterList == null && state.value.filters.isNotEmpty()) {
@ -519,7 +519,7 @@ open class BrowseSourceScreenModel(
name: String,
) {
if (source !is CatalogueSource) return
coroutineScope.launchNonCancellable {
screenModelScope.launchNonCancellable {
val query = state.value.toolbarQuery?.takeUnless {
it.isBlank() || it == GetRemoteManga.QUERY_POPULAR || it == GetRemoteManga.QUERY_LATEST
}?.trim()
@ -537,13 +537,13 @@ open class BrowseSourceScreenModel(
}
fun deleteSearch(savedSearchId: Long) {
coroutineScope.launchNonCancellable {
screenModelScope.launchNonCancellable {
deleteSavedSearchById.await(savedSearchId)
}
}
fun onMangaDexRandom(onRandomFound: (String) -> Unit) {
coroutineScope.launchIO {
screenModelScope.launchIO {
val random = source.getMainSource<MangaDex>()?.fetchRandomMangaUrl()
?: return@launchIO
onRandomFound(random)

View File

@ -6,7 +6,7 @@ import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.produceState
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.manga.interactor.UpdateManga
import eu.kanade.domain.manga.model.toDomainManga
@ -75,13 +75,13 @@ open class SourceFeedScreenModel(
private val coroutineDispatcher = Executors.newFixedThreadPool(5).asCoroutineDispatcher()
val startExpanded by uiPreferences.expandFilters().asState(coroutineScope)
val startExpanded by uiPreferences.expandFilters().asState(screenModelScope)
init {
if (source is CatalogueSource) {
setFilters(source.getFilterList())
coroutineScope.launchIO {
screenModelScope.launchIO {
val searches = loadSearches()
mutableState.update { it.copy(savedSearches = searches) }
}
@ -96,7 +96,7 @@ open class SourceFeedScreenModel(
}
getFeed(items)
}
.launchIn(coroutineScope)
.launchIn(screenModelScope)
}
}
@ -109,7 +109,7 @@ open class SourceFeedScreenModel(
}
fun createFeed(savedSearchId: Long) {
coroutineScope.launchNonCancellable {
screenModelScope.launchNonCancellable {
insertFeedSavedSearch.await(
FeedSavedSearch(
id = -1,
@ -122,7 +122,7 @@ open class SourceFeedScreenModel(
}
fun deleteFeed(feed: FeedSavedSearch) {
coroutineScope.launchNonCancellable {
screenModelScope.launchNonCancellable {
deleteFeedSavedSearchById.await(feed.id)
}
}
@ -148,7 +148,7 @@ open class SourceFeedScreenModel(
*/
private fun getFeed(feedSavedSearch: List<SourceFeedUI>) {
if (source !is CatalogueSource) return
coroutineScope.launch {
screenModelScope.launch {
feedSavedSearch.map { sourceFeed ->
async {
val page = try {
@ -213,7 +213,7 @@ open class SourceFeedScreenModel(
fun onFilter(onBrowseClick: (query: String?, filters: String?) -> Unit) {
if (source !is CatalogueSource) return
coroutineScope.launchIO {
screenModelScope.launchIO {
val allDefault = state.value.filters == source.getFilterList()
dismissDialog()
if (allDefault) {
@ -236,7 +236,7 @@ open class SourceFeedScreenModel(
onToast: (Int) -> Unit,
) {
if (source !is CatalogueSource) return
coroutineScope.launchIO {
screenModelScope.launchIO {
if (search.filterList == null && state.value.filters.isNotEmpty()) {
withUIContext {
onToast(R.string.save_search_invalid)
@ -260,7 +260,7 @@ open class SourceFeedScreenModel(
search: EXHSavedSearch,
onToast: (Int) -> Unit,
) {
coroutineScope.launchIO {
screenModelScope.launchIO {
if (hasTooManyFeeds()) {
withUIContext {
onToast(R.string.too_many_in_feed)
@ -272,7 +272,7 @@ open class SourceFeedScreenModel(
}
fun onMangaDexRandom(onRandomFound: (String) -> Unit) {
coroutineScope.launchIO {
screenModelScope.launchIO {
val random = source.getMainSource<MangaDex>()?.fetchRandomMangaUrl()
?: return@launchIO
onRandomFound(random)

View File

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

View File

@ -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.tachiyomi.R
import eu.kanade.tachiyomi.core.security.SecurityPreferences
import kotlinx.coroutines.channels.Channel
@ -24,7 +24,7 @@ class BiometricTimesScreenModel(
val events = _events.receiveAsFlow()
init {
coroutineScope.launchIO {
screenModelScope.launchIO {
// todo usecase
preferences.authenticatorTimeRanges().changes()
.collectLatest { times ->
@ -47,7 +47,7 @@ class BiometricTimesScreenModel(
*/
fun createTimeRange(timeRange: TimeRange) {
// todo usecase
coroutineScope.launchIO {
screenModelScope.launchIO {
// Do not allow duplicate categories.
if (timeRangeConflicts(timeRange)) {
_events.send(BiometricTimesEvent.TimeConflicts)
@ -65,7 +65,7 @@ class BiometricTimesScreenModel(
*/
fun deleteTimeRanges(timeRange: TimeRangeItem) {
// todo usecase
coroutineScope.launchIO {
screenModelScope.launchIO {
val state = state.value as? BiometricTimesScreenState.Success ?: return@launchIO
preferences.authenticatorTimeRanges().set(
state.timeRanges.filterNot { it == timeRange }.map { it.timeRange.toPreferenceString() }.toSet(),

View File

@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.ui.category.genre
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.manga.interactor.CreateSortTag
import eu.kanade.domain.manga.interactor.DeleteSortTag
import eu.kanade.domain.manga.interactor.GetSortTag
@ -28,7 +28,7 @@ class SortTagScreenModel(
val events = _events.receiveAsFlow()
init {
coroutineScope.launchIO {
screenModelScope.launchIO {
getSortTag.subscribe()
.collectLatest { tags ->
mutableState.update {
@ -41,7 +41,7 @@ class SortTagScreenModel(
}
fun createTag(name: String) {
coroutineScope.launchIO {
screenModelScope.launchIO {
when (createSortTag.await(name)) {
is CreateSortTag.Result.TagExists -> _events.send(SortTagEvent.TagExists)
else -> {}
@ -50,13 +50,13 @@ class SortTagScreenModel(
}
fun delete(tag: String) {
coroutineScope.launchIO {
screenModelScope.launchIO {
deleteSortTag.await(tag)
}
}
fun moveUp(tag: String, index: Int) {
coroutineScope.launchIO {
screenModelScope.launchIO {
when (reorderSortTag.await(tag, index - 1)) {
is ReorderSortTag.Result.InternalError -> _events.send(SortTagEvent.InternalError)
else -> {}
@ -65,7 +65,7 @@ class SortTagScreenModel(
}
fun moveDown(tag: String, index: Int) {
coroutineScope.launchIO {
screenModelScope.launchIO {
when (reorderSortTag.await(tag, index + 1)) {
is ReorderSortTag.Result.InternalError -> _events.send(SortTagEvent.InternalError)
else -> {}

View File

@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.ui.category.repos
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.source.interactor.CreateSourceRepo
import eu.kanade.tachiyomi.R
import kotlinx.coroutines.channels.Channel
@ -26,7 +26,7 @@ class RepoScreenModel(
val events = _events.receiveAsFlow()
init {
coroutineScope.launchIO {
screenModelScope.launchIO {
getSourceRepos.subscribe()
.collectLatest { repos ->
mutableState.update {
@ -44,7 +44,7 @@ class RepoScreenModel(
* @param name The name of the repo to create.
*/
fun createRepo(name: String) {
coroutineScope.launchIO {
screenModelScope.launchIO {
when (createSourceRepo.await(name)) {
is CreateSourceRepo.Result.InvalidName -> _events.send(RepoEvent.InvalidName)
else -> {}
@ -58,7 +58,7 @@ class RepoScreenModel(
* @param repos The list of repos to delete.
*/
fun deleteRepos(repos: List<String>) {
coroutineScope.launchIO {
screenModelScope.launchIO {
deleteSourceRepos.await(repos)
}
}

View File

@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.ui.category.sources
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.source.interactor.CreateSourceCategory
import eu.kanade.domain.source.interactor.DeleteSourceCategory
import eu.kanade.domain.source.interactor.GetSourceCategories
@ -28,7 +28,7 @@ class SourceCategoryScreenModel(
val events = _events.receiveAsFlow()
init {
coroutineScope.launchIO {
screenModelScope.launchIO {
getSourceCategories.subscribe()
.collectLatest { categories ->
mutableState.update {
@ -46,7 +46,7 @@ class SourceCategoryScreenModel(
* @param name The name of the category to create.
*/
fun createCategory(name: String) {
coroutineScope.launchIO {
screenModelScope.launchIO {
when (createSourceCategory.await(name)) {
is CreateSourceCategory.Result.InvalidName -> _events.send(SourceCategoryEvent.InvalidName)
else -> {}
@ -60,7 +60,7 @@ class SourceCategoryScreenModel(
* @param categories The list of categories to delete.
*/
fun deleteCategory(categories: String) {
coroutineScope.launchIO {
screenModelScope.launchIO {
deleteSourceCategory.await(categories)
}
}
@ -72,7 +72,7 @@ class SourceCategoryScreenModel(
* @param categoryNew The new name of the category.
*/
fun renameCategory(categoryOld: String, categoryNew: String) {
coroutineScope.launchIO {
screenModelScope.launchIO {
when (renameSourceCategory.await(categoryOld, categoryNew)) {
is CreateSourceCategory.Result.InvalidName -> _events.send(SourceCategoryEvent.InvalidName)
else -> {}

View File

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

View File

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

View File

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

View File

@ -10,7 +10,7 @@ import androidx.compose.ui.util.fastAny
import androidx.compose.ui.util.fastForEach
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
@ -146,14 +146,14 @@ class LibraryScreenModel(
// SY <--
) : StateScreenModel<LibraryScreenModel.State>(State()) {
var activeCategoryIndex: Int by libraryPreferences.lastUsedCategory().asState(coroutineScope)
var activeCategoryIndex: Int by libraryPreferences.lastUsedCategory().asState(screenModelScope)
// SY -->
val favoritesSync = FavoritesSyncHelper(preferences.context)
// SY <--
init {
coroutineScope.launchIO {
screenModelScope.launchIO {
combine(
state.map { it.searchQuery }.distinctUntilChanged().debounce(SEARCH_DEBOUNCE_MILLIS),
getLibraryFlow(),
@ -213,7 +213,7 @@ class LibraryScreenModel(
)
}
}
.launchIn(coroutineScope)
.launchIn(screenModelScope)
combine(
getLibraryItemPreferencesFlow(),
@ -235,7 +235,7 @@ class LibraryScreenModel(
state.copy(hasActiveFilters = it)
}
}
.launchIn(coroutineScope)
.launchIn(screenModelScope)
// SY -->
combine(
@ -251,7 +251,7 @@ class LibraryScreenModel(
state.copy(showSyncExh = it)
}
}
.launchIn(coroutineScope)
.launchIn(screenModelScope)
libraryPreferences.groupLibraryBy().changes()
.onEach {
@ -259,7 +259,7 @@ class LibraryScreenModel(
state.copy(groupType = it)
}
}
.launchIn(coroutineScope)
.launchIn(screenModelScope)
// SY <--
}
@ -620,7 +620,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 ->
// SY -->
if (manga.source == MERGED_SOURCE_ID) {
@ -714,7 +714,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,
@ -733,7 +733,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) {
@ -775,7 +775,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 }
@ -789,11 +789,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? {
@ -1075,7 +1075,7 @@ class LibraryScreenModel(
}
fun openChangeCategoryDialog() {
coroutineScope.launchIO {
screenModelScope.launchIO {
// Create a copy of selected manga
val mangaList = state.value.selection.map { it.manga }
@ -1205,7 +1205,7 @@ class LibraryScreenModel(
}
fun runSync() {
favoritesSync.runSync(coroutineScope)
favoritesSync.runSync(screenModelScope)
}
fun onAcceptSyncWarning() {

View File

@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.library
import androidx.compose.runtime.getValue
import cafe.adriel.voyager.core.model.ScreenModel
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.tachiyomi.data.track.TrackerManager
@ -31,7 +31,7 @@ class LibrarySettingsScreenModel(
get() = trackerManager.trackers.filter { it.isLoggedIn }
// SY -->
val grouping by libraryPreferences.groupLibraryBy().asState(coroutineScope)
val grouping by libraryPreferences.groupLibraryBy().asState(screenModelScope)
// SY <--
fun toggleFilter(preference: (LibraryPreferences) -> Preference<TriState>) {
@ -49,14 +49,14 @@ class LibrarySettingsScreenModel(
}
fun setSort(category: Category?, mode: LibrarySort.Type, direction: LibrarySort.Direction) {
coroutineScope.launchIO {
screenModelScope.launchIO {
setSortModeForCategory.await(category, mode, direction)
}
}
// SY -->
fun setGrouping(grouping: Int) {
coroutineScope.launchIO {
screenModelScope.launchIO {
libraryPreferences.groupLibraryBy().set(grouping)
}
}

View File

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

View File

@ -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
@ -191,9 +191,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()
@ -234,7 +234,7 @@ class MangaScreenModel(
}
init {
coroutineScope.launchIO {
screenModelScope.launchIO {
getMangaAndChapters.subscribe(mangaId)
.distinctUntilChanged()
// SY -->
@ -317,7 +317,7 @@ class MangaScreenModel(
observeDownloads()
coroutineScope.launchIO {
screenModelScope.launchIO {
val manga = getMangaAndChapters.awaitManga(mangaId)
// SY -->
val chapters = (if (manga.source == MERGED_SOURCE_ID) getMergedChapterByMangaId.await(mangaId) else getMangaAndChapters.awaitChapters(mangaId))
@ -372,7 +372,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() },
@ -386,7 +386,7 @@ class MangaScreenModel(
}
fun fetchAllFromSource(manualFetch: Boolean = true) {
coroutineScope.launch {
screenModelScope.launch {
updateSuccessState { it.copy(isRefreshingData = true) }
val fetchFromSourceTasks = listOf(
async { fetchMangaFromSource(manualFetch) },
@ -414,7 +414,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 })
}
}
@ -464,7 +464,7 @@ class MangaScreenModel(
lastUpdate = manga.lastUpdate + 1,
)
(sourceManager.get(LocalSource.ID) as LocalSource).updateMangaInfo(manga.toSManga())
coroutineScope.launchNonCancellable {
screenModelScope.launchNonCancellable {
updateManga.await(
MangaUpdate(
manga.id,
@ -639,7 +639,7 @@ class MangaScreenModel(
}
fun updateMergeSettings(mergedMangaReferences: List<MergedMangaReference>) {
coroutineScope.launchNonCancellable {
screenModelScope.launchNonCancellable {
if (mergedMangaReferences.isNotEmpty()) {
updateMergedSettings.awaitAll(
mergedMangaReferences.map {
@ -658,7 +658,7 @@ class MangaScreenModel(
}
fun deleteMerge(reference: MergedMangaReference) {
coroutineScope.launchNonCancellable {
screenModelScope.launchNonCancellable {
deleteMergeById.await(reference.id)
}
}
@ -667,7 +667,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),
@ -690,7 +690,7 @@ class MangaScreenModel(
checkDuplicate: Boolean = true,
) {
val state = successState ?: return
coroutineScope.launchIO {
screenModelScope.launchIO {
val manga = state.manga
if (isFavorited) {
@ -745,7 +745,7 @@ class MangaScreenModel(
fun showChangeCategoryDialog() {
val manga = successState?.manga ?: return
coroutineScope.launch {
screenModelScope.launch {
val categories = getCategories()
val selection = getMangaCategoryIds(manga)
updateSuccessState { successState ->
@ -767,7 +767,7 @@ class MangaScreenModel(
}
fun setFetchInterval(manga: Manga, interval: Int) {
coroutineScope.launchIO {
screenModelScope.launchIO {
updateManga.awaitUpdateFetchInterval(
// Custom intervals are negative
manga.copy(fetchInterval = -interval),
@ -825,7 +825,7 @@ class MangaScreenModel(
moveMangaToCategory(categories)
if (manga.favorite) return
coroutineScope.launchIO {
screenModelScope.launchIO {
updateManga.awaitUpdateFavorite(manga.id, true)
}
}
@ -841,7 +841,7 @@ class MangaScreenModel(
}
private fun moveMangaToCategory(categoryIds: List<Long>) {
coroutineScope.launchIO {
screenModelScope.launchIO {
setMangaCategories.await(mangaId, categoryIds)
}
}
@ -864,7 +864,7 @@ class MangaScreenModel(
val isMergedSource = source is MergedSource
val mergedIds = if (isMergedSource) successState?.mergedData?.manga?.keys.orEmpty() else emptySet()
// SY <--
coroutineScope.launchIO {
screenModelScope.launchIO {
downloadManager.statusFlow()
.filter { /* SY --> */ if (isMergedSource) it.manga.id in mergedIds else /* SY <-- */ it.manga.id == successState?.manga?.id }
.catch { error -> logcat(LogPriority.ERROR, error) }
@ -875,7 +875,7 @@ class MangaScreenModel(
}
}
coroutineScope.launchIO {
screenModelScope.launchIO {
downloadManager.progressFlow()
.filter { /* SY --> */ if (isMergedSource) it.manga.id in mergedIds else /* SY <-- */ it.manga.id == successState?.manga?.id }
.catch { error -> logcat(LogPriority.ERROR, error) }
@ -954,7 +954,7 @@ class MangaScreenModel(
// SY -->
private fun getPagePreviews(manga: Manga, source: Source) {
coroutineScope.launchIO {
screenModelScope.launchIO {
when (val result = getPagePreviews.await(manga, source, 1)) {
is GetPagePreviews.Result.Error -> updateSuccessState {
it.copy(pagePreviewsState = PagePreviewState.Error(result.error))
@ -1002,7 +1002,7 @@ class MangaScreenModel(
with(context) { e.formattedMessage }
}
coroutineScope.launch {
screenModelScope.launch {
snackbarHostState.showSnackbar(message = message)
}
val newManga = mangaRepository.getMangaById(mangaId)
@ -1014,7 +1014,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)
}
}
@ -1096,7 +1096,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),
@ -1167,7 +1167,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(),
@ -1200,7 +1200,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) }
@ -1215,7 +1215,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(
@ -1231,7 +1231,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) || manga.isEhBasedManga()) return@launchNonCancellable
@ -1251,7 +1251,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)
}
}
@ -1269,7 +1269,7 @@ class MangaScreenModel(
TriState.ENABLED_NOT -> Manga.CHAPTER_SHOW_NOT_DOWNLOADED
}
coroutineScope.launchNonCancellable {
screenModelScope.launchNonCancellable {
setMangaChapterFlags.awaitSetDownloadedFilter(manga, flag)
}
}
@ -1287,7 +1287,7 @@ class MangaScreenModel(
TriState.ENABLED_NOT -> Manga.CHAPTER_SHOW_NOT_BOOKMARKED
}
coroutineScope.launchNonCancellable {
screenModelScope.launchNonCancellable {
setMangaChapterFlags.awaitSetBookmarkFilter(manga, flag)
}
}
@ -1295,7 +1295,7 @@ class MangaScreenModel(
// SY -->
fun setScanlatorFilter(filteredScanlators: List<String>) {
val manga = manga ?: return
coroutineScope.launchIO {
screenModelScope.launchIO {
setMangaFilteredScanlators.awaitSetFilteredScanlators(manga, filteredScanlators)
}
}
@ -1308,7 +1308,7 @@ class MangaScreenModel(
fun setDisplayMode(mode: Long) {
val manga = successState?.manga ?: return
coroutineScope.launchNonCancellable {
screenModelScope.launchNonCancellable {
setMangaChapterFlags.awaitSetDisplayMode(manga, mode)
}
}
@ -1320,14 +1320,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()
@ -1432,7 +1432,7 @@ class MangaScreenModel(
val state = successState
val manga = state?.manga ?: return
coroutineScope.launchIO {
screenModelScope.launchIO {
getTracks.subscribe(manga.id)
.catch { logcat(LogPriority.ERROR, it) }
.map { tracks ->

View File

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

View File

@ -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
@ -99,12 +99,12 @@ private class MoreScreenModel(
// SY <--
) : 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)
// SY -->
val showNavUpdates by uiPreferences.showNavUpdates().asState(coroutineScope)
val showNavHistory by uiPreferences.showNavHistory().asState(coroutineScope)
val showNavUpdates by uiPreferences.showNavUpdates().asState(screenModelScope)
val showNavHistory by uiPreferences.showNavHistory().asState(screenModelScope)
// SY <--
private var _state: MutableStateFlow<DownloadQueueState> = MutableStateFlow(DownloadQueueState.Stopped)
@ -112,7 +112,7 @@ private class MoreScreenModel(
init {
// Handle running/paused status change and queue progress updating
coroutineScope.launchIO {
screenModelScope.launchIO {
combine(
downloadManager.isDownloaderRunning,
downloadManager.queueState,

View File

@ -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
@ -103,7 +103,7 @@ class StatsScreenModel(
)
}
// SY -->
}.launchIn(coroutineScope)
}.launchIn(screenModelScope)
// SY <--
}

View File

@ -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
@ -71,11 +71,11 @@ 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)
// SY -->
val preserveReadingPosition by readerPreferences.preserveReadingPosition().asState(coroutineScope)
val preserveReadingPosition by readerPreferences.preserveReadingPosition().asState(screenModelScope)
// SY <--
// First and last selected index in list
@ -83,7 +83,7 @@ class UpdatesScreenModel(
private val selectedChapterIds: HashSet<Long> = HashSet()
init {
coroutineScope.launchIO {
screenModelScope.launchIO {
// Set date limit for recent chapters
val calendar = Calendar.getInstance().apply {
time = Date()
@ -109,7 +109,7 @@ class UpdatesScreenModel(
}
}
coroutineScope.launchIO {
screenModelScope.launchIO {
merge(downloadManager.statusFlow(), downloadManager.progressFlow())
.catch { logcat(LogPriority.ERROR, it) }
.collect(this@UpdatesScreenModel::updateDownloadState)
@ -143,7 +143,7 @@ class UpdatesScreenModel(
fun updateLibrary(): Boolean {
val started = LibraryUpdateJob.startNow(Injekt.get<Application>())
coroutineScope.launch {
screenModelScope.launch {
_events.send(Event.LibraryUpdateTriggered(started))
}
return started
@ -175,7 +175,7 @@ class UpdatesScreenModel(
fun downloadChapters(items: List<UpdatesItem>, action: ChapterDownloadAction) {
if (items.isEmpty()) return
coroutineScope.launch {
screenModelScope.launch {
when (action) {
ChapterDownloadAction.START -> {
downloadChapters(items)
@ -215,7 +215,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
@ -231,7 +231,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) }
@ -245,7 +245,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
@ -264,7 +264,7 @@ class UpdatesScreenModel(
* @param updatesItem list of chapters
*/
fun deleteChapters(updatesItem: List<UpdatesItem>) {
coroutineScope.launchNonCancellable {
screenModelScope.launchNonCancellable {
updatesItem
.groupBy { it.update.mangaId }
.entries

View File

@ -4,7 +4,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
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.manga.interactor.GetPagePreviews
import eu.kanade.domain.manga.model.PagePreview
import eu.kanade.tachiyomi.source.Source
@ -35,7 +35,7 @@ class PagePreviewScreenModel(
var pageDialogOpen by mutableStateOf(false)
init {
coroutineScope.launchIO {
screenModelScope.launchIO {
val manga = getManga.await(mangaId)!!
val chapter = getChapterByMangaId.await(mangaId).minByOrNull { it.sourceOrder }
if (chapter == null) {

View File

@ -2,7 +2,7 @@ package exh.ui.batchadd
import android.content.Context
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 exh.GalleryAddEvent
import exh.GalleryAdder
@ -62,7 +62,7 @@ class BatchAddScreenModel(
xLogE("Batch add error", throwable)
}
coroutineScope.launch(Dispatchers.IO + handler) {
screenModelScope.launch(Dispatchers.IO + handler) {
val succeeded = mutableListOf<String>()
val failed = mutableListOf<String>()

View File

@ -1,7 +1,7 @@
package exh.ui.metadata
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.online.MetadataSource
import exh.metadata.metadata.RaisedSearchMetadata
import exh.source.getMainSource
@ -26,11 +26,11 @@ class MetadataViewScreenModel(
val manga = _manga.asStateFlow()
init {
coroutineScope.launchIO {
screenModelScope.launchIO {
_manga.value = getManga.await(mangaId)
}
coroutineScope.launchIO {
screenModelScope.launchIO {
val metadataSource = sourceManager.get(sourceId)?.getMainSource<MetadataSource<*, *>>()
if (metadataSource == null) {
mutableState.value = MetadataViewState.SourceNotFound

View File

@ -1,7 +1,7 @@
package exh.ui.smartsearch
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.CatalogueSource
import eu.kanade.tachiyomi.ui.browse.source.SourcesScreen
import exh.smartsearch.SmartSearchEngine
@ -24,7 +24,7 @@ class SmartSearchScreenModel(
val source = sourceManager.get(sourceId) as CatalogueSource
init {
coroutineScope.launchIO {
screenModelScope.launchIO {
val result = try {
val resultManga = smartSearchEngine.smartSearch(source, config.origTitle)
if (resultManga != null) {

View File

@ -5,7 +5,7 @@ shizuku_version = "12.2.0"
sqlite = "2.4.0"
sqldelight = "2.0.0"
leakcanary = "2.12"
voyager = "1.0.0-rc07"
voyager = "1.0.0-rc08"
richtext = "0.17.0"
[libraries]

View File

@ -79,6 +79,14 @@ abstract class DelegatedHttpSource(val delegate: HttpSource) : HttpSource() {
override fun chapterListParse(response: Response) =
throw UnsupportedOperationException("Should never be called!")
/**
* Parses the response from the site and returns a SChapter Object.
*
* @param response the response from the site.
*/
override fun chapterPageParse(response: Response) =
throw UnsupportedOperationException("Should never be called!")
/**
* Parses the response from the site and returns a list of pages.
*

View File

@ -83,6 +83,14 @@ class EnhancedHttpSource(
override fun chapterListParse(response: Response) =
throw UnsupportedOperationException("Should never be called!")
/**
* Parses the response from the site and returns a SChapter Object.
*
* @param response the response from the site.
*/
override fun chapterPageParse(response: Response) =
throw UnsupportedOperationException("Should never be called!")
/**
* Parses the response from the site and returns a list of pages.
*