Update Voyager

This commit is contained in:
arkon 2023-10-22 15:54:31 -04:00
parent 6d1e520c6c
commit 012854dd1e
25 changed files with 136 additions and 137 deletions

View file

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

View file

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

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

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

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

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

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

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

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

View file

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

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

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

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

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

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]