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