mirror of
https://github.com/aniyomiorg/aniyomi.git
synced 2024-11-23 21:27:40 +03:00
parent
a60268e61c
commit
3fba4cbc2b
68 changed files with 504 additions and 347 deletions
|
@ -9,7 +9,7 @@ class SetMangaViewerFlags(
|
|||
private val mangaRepository: MangaRepository,
|
||||
) {
|
||||
|
||||
suspend fun awaitSetMangaReadingMode(id: Long, flag: Long) {
|
||||
suspend fun awaitSetReadingMode(id: Long, flag: Long) {
|
||||
val manga = mangaRepository.getMangaById(id)
|
||||
mangaRepository.updateManga(
|
||||
MangaUpdate(
|
||||
|
@ -19,7 +19,7 @@ class SetMangaViewerFlags(
|
|||
)
|
||||
}
|
||||
|
||||
suspend fun awaitSetOrientationType(id: Long, flag: Long) {
|
||||
suspend fun awaitSetOrientation(id: Long, flag: Long) {
|
||||
val manga = mangaRepository.getMangaById(id)
|
||||
mangaRepository.updateManga(
|
||||
MangaUpdate(
|
||||
|
|
|
@ -47,8 +47,8 @@ import androidx.compose.ui.text.font.FontStyle
|
|||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
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.core.screen.Screen
|
||||
import eu.kanade.core.util.asFlow
|
||||
import eu.kanade.presentation.components.TabbedDialogPaddings
|
||||
|
@ -116,7 +116,7 @@ class EpisodeOptionsDialogScreenModel(
|
|||
private val sourceManager: AnimeSourceManager = Injekt.get()
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
// To show loading state
|
||||
mutableState.update { it.copy(episode = null, anime = null, resultList = null) }
|
||||
|
||||
|
|
|
@ -25,8 +25,10 @@ import androidx.compose.foundation.lazy.items
|
|||
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||
import androidx.compose.material.LocalMinimumInteractiveComponentEnforcement
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Brush
|
||||
import androidx.compose.material.icons.filled.Favorite
|
||||
import androidx.compose.material.icons.filled.HourglassEmpty
|
||||
import androidx.compose.material.icons.filled.PersonOutline
|
||||
import androidx.compose.material.icons.outlined.AttachMoney
|
||||
import androidx.compose.material.icons.outlined.Block
|
||||
import androidx.compose.material.icons.outlined.Close
|
||||
|
@ -473,6 +475,7 @@ private fun AnimeAndSourceTitlesSmall(
|
|||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 16.dp, top = appBarPadding + 16.dp, end = 16.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
ItemCover.Book(
|
||||
|
@ -483,7 +486,9 @@ private fun AnimeAndSourceTitlesSmall(
|
|||
contentDescription = stringResource(R.string.manga_cover),
|
||||
onClick = onCoverClick,
|
||||
)
|
||||
Column(modifier = Modifier.padding(start = 16.dp)) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||
) {
|
||||
Text(
|
||||
text = title.ifBlank { stringResource(R.string.unknown_title) },
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
|
@ -499,40 +504,63 @@ private fun AnimeAndSourceTitlesSmall(
|
|||
onClick = { if (title.isNotBlank()) doSearch(title, true) },
|
||||
),
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(2.dp))
|
||||
Text(
|
||||
text = author?.takeIf { it.isNotBlank() }
|
||||
?: stringResource(R.string.unknown_studio),
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
modifier = Modifier
|
||||
.secondaryItemAlpha()
|
||||
.padding(top = 2.dp)
|
||||
.clickableNoIndication(
|
||||
onLongClick = {
|
||||
if (!author.isNullOrBlank()) {
|
||||
context.copyToClipboard(
|
||||
author,
|
||||
author,
|
||||
)
|
||||
}
|
||||
},
|
||||
onClick = { if (!author.isNullOrBlank()) doSearch(author, true) },
|
||||
),
|
||||
)
|
||||
if (!artist.isNullOrBlank() && author != artist) {
|
||||
|
||||
Row(
|
||||
modifier = Modifier.secondaryItemAlpha(),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.PersonOutline,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(16.dp),
|
||||
)
|
||||
Text(
|
||||
text = artist,
|
||||
text = author?.takeIf { it.isNotBlank() }
|
||||
?: stringResource(R.string.unknown_author),
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
modifier = Modifier
|
||||
.secondaryItemAlpha()
|
||||
.padding(top = 2.dp)
|
||||
.clickableNoIndication(
|
||||
onLongClick = { context.copyToClipboard(artist, artist) },
|
||||
onClick = { doSearch(artist, true) },
|
||||
onLongClick = {
|
||||
if (!author.isNullOrBlank()) {
|
||||
context.copyToClipboard(
|
||||
author,
|
||||
author,
|
||||
)
|
||||
}
|
||||
},
|
||||
onClick = { if (!author.isNullOrBlank()) doSearch(author, true) },
|
||||
),
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
|
||||
if (!artist.isNullOrBlank() && author != artist) {
|
||||
Row(
|
||||
modifier = Modifier.secondaryItemAlpha(),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Brush,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(16.dp),
|
||||
)
|
||||
Text(
|
||||
text = artist,
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
modifier = Modifier
|
||||
.clickableNoIndication(
|
||||
onLongClick = { context.copyToClipboard(artist, artist) },
|
||||
onClick = { doSearch(artist, true) },
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(2.dp))
|
||||
|
||||
Row(
|
||||
modifier = Modifier.secondaryItemAlpha(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
|
|
|
@ -39,6 +39,7 @@ fun ChapterSettingsDialog(
|
|||
onSortModeChanged: (Long) -> Unit,
|
||||
onDisplayModeChanged: (Long) -> Unit,
|
||||
onSetAsDefault: (applyToExistingManga: Boolean) -> Unit,
|
||||
onResetToDefault: () -> Unit,
|
||||
) {
|
||||
var showSetAsDefaultDialog by rememberSaveable { mutableStateOf(false) }
|
||||
if (showSetAsDefaultDialog) {
|
||||
|
@ -63,6 +64,13 @@ fun ChapterSettingsDialog(
|
|||
closeMenu()
|
||||
},
|
||||
)
|
||||
DropdownMenuItem(
|
||||
text = { Text(stringResource(R.string.action_reset)) },
|
||||
onClick = {
|
||||
onResetToDefault()
|
||||
closeMenu()
|
||||
},
|
||||
)
|
||||
},
|
||||
) { page ->
|
||||
Column(
|
||||
|
|
|
@ -25,8 +25,10 @@ import androidx.compose.foundation.lazy.items
|
|||
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||
import androidx.compose.material.LocalMinimumInteractiveComponentEnforcement
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Brush
|
||||
import androidx.compose.material.icons.filled.Favorite
|
||||
import androidx.compose.material.icons.filled.HourglassEmpty
|
||||
import androidx.compose.material.icons.filled.PersonOutline
|
||||
import androidx.compose.material.icons.filled.Warning
|
||||
import androidx.compose.material.icons.outlined.AttachMoney
|
||||
import androidx.compose.material.icons.outlined.Block
|
||||
|
@ -473,6 +475,7 @@ private fun MangaAndSourceTitlesSmall(
|
|||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 16.dp, top = appBarPadding + 16.dp, end = 16.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
ItemCover.Book(
|
||||
|
@ -483,7 +486,9 @@ private fun MangaAndSourceTitlesSmall(
|
|||
contentDescription = stringResource(R.string.manga_cover),
|
||||
onClick = onCoverClick,
|
||||
)
|
||||
Column(modifier = Modifier.padding(start = 16.dp)) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||
) {
|
||||
Text(
|
||||
text = title.ifBlank { stringResource(R.string.unknown_title) },
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
|
@ -499,40 +504,62 @@ private fun MangaAndSourceTitlesSmall(
|
|||
onClick = { if (title.isNotBlank()) doSearch(title, true) },
|
||||
),
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(2.dp))
|
||||
Text(
|
||||
text = author?.takeIf { it.isNotBlank() }
|
||||
?: stringResource(R.string.unknown_author),
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
modifier = Modifier
|
||||
.secondaryItemAlpha()
|
||||
.padding(top = 2.dp)
|
||||
.clickableNoIndication(
|
||||
onLongClick = {
|
||||
if (!author.isNullOrBlank()) {
|
||||
context.copyToClipboard(
|
||||
author,
|
||||
author,
|
||||
)
|
||||
}
|
||||
},
|
||||
onClick = { if (!author.isNullOrBlank()) doSearch(author, true) },
|
||||
),
|
||||
)
|
||||
if (!artist.isNullOrBlank() && author != artist) {
|
||||
Row(
|
||||
modifier = Modifier.secondaryItemAlpha(),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.PersonOutline,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(16.dp),
|
||||
)
|
||||
Text(
|
||||
text = artist,
|
||||
text = author?.takeIf { it.isNotBlank() }
|
||||
?: stringResource(R.string.unknown_author),
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
modifier = Modifier
|
||||
.secondaryItemAlpha()
|
||||
.padding(top = 2.dp)
|
||||
.clickableNoIndication(
|
||||
onLongClick = { context.copyToClipboard(artist, artist) },
|
||||
onClick = { doSearch(artist, true) },
|
||||
onLongClick = {
|
||||
if (!author.isNullOrBlank()) {
|
||||
context.copyToClipboard(
|
||||
author,
|
||||
author,
|
||||
)
|
||||
}
|
||||
},
|
||||
onClick = { if (!author.isNullOrBlank()) doSearch(author, true) },
|
||||
),
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
|
||||
if (!artist.isNullOrBlank() && author != artist) {
|
||||
Row(
|
||||
modifier = Modifier.secondaryItemAlpha(),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Brush,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(16.dp),
|
||||
)
|
||||
Text(
|
||||
text = artist,
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
modifier = Modifier
|
||||
.clickableNoIndication(
|
||||
onLongClick = { context.copyToClipboard(artist, artist) },
|
||||
onClick = { doSearch(artist, true) },
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(2.dp))
|
||||
|
||||
Row(
|
||||
modifier = Modifier.secondaryItemAlpha(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
|
|
|
@ -65,7 +65,7 @@ import okhttp3.Headers
|
|||
import tachiyomi.core.util.lang.launchNonCancellable
|
||||
import tachiyomi.core.util.lang.withUIContext
|
||||
import tachiyomi.core.util.system.logcat
|
||||
import tachiyomi.domain.entries.manga.repository.MangaRepository
|
||||
import tachiyomi.domain.entries.manga.interactor.ResetMangaViewerFlags
|
||||
import tachiyomi.presentation.core.util.collectAsState
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
@ -336,7 +336,7 @@ object SettingsAdvancedScreen : SearchableSettings {
|
|||
subtitle = stringResource(R.string.pref_reset_viewer_flags_summary),
|
||||
onClick = {
|
||||
scope.launchNonCancellable {
|
||||
val success = Injekt.get<MangaRepository>().resetMangaViewerFlags()
|
||||
val success = Injekt.get<ResetMangaViewerFlags>().await()
|
||||
withUIContext {
|
||||
val message = if (success) {
|
||||
R.string.pref_reset_viewer_flags_success
|
||||
|
|
|
@ -64,6 +64,11 @@ object SettingsReaderScreen : SearchableSettings {
|
|||
pref = readerPref.pageTransitions(),
|
||||
title = stringResource(R.string.pref_page_transitions),
|
||||
),
|
||||
Preference.PreferenceItem.SwitchPreference(
|
||||
pref = readerPref.flashOnPageChange(),
|
||||
title = stringResource(R.string.pref_flash_page),
|
||||
subtitle = stringResource(R.string.pref_flash_page_summ),
|
||||
),
|
||||
getDisplayGroup(readerPreferences = readerPref),
|
||||
getReadingGroup(readerPreferences = readerPref),
|
||||
getPagedGroup(readerPreferences = readerPref),
|
||||
|
|
|
@ -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.anime.components.AnimeSourceIcon
|
||||
|
@ -216,7 +216,7 @@ private class ClearAnimeDatabaseScreenModel : StateScreenModel<ClearAnimeDatabas
|
|||
private val database: AnimeDatabase = Injekt.get()
|
||||
|
||||
init {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
getSourcesWithNonLibraryAnime.subscribe()
|
||||
.collectLatest { list ->
|
||||
mutableState.update { old ->
|
||||
|
|
|
@ -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.manga.components.MangaSourceIcon
|
||||
|
@ -216,7 +216,7 @@ private class ClearDatabaseScreenModel : StateScreenModel<ClearDatabaseScreenMod
|
|||
private val database: Database = Injekt.get()
|
||||
|
||||
init {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
getSourcesWithNonLibraryManga.subscribe()
|
||||
.collectLatest { list ->
|
||||
mutableState.update { old ->
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package eu.kanade.presentation.reader
|
||||
|
||||
import androidx.annotation.IntRange
|
||||
import androidx.compose.foundation.Canvas
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.runtime.Composable
|
||||
|
@ -10,7 +11,7 @@ import kotlin.math.abs
|
|||
|
||||
@Composable
|
||||
fun BrightnessOverlay(
|
||||
value: Int,
|
||||
@IntRange(from = -100, to = 100) value: Int,
|
||||
) {
|
||||
if (value >= 0) return
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package eu.kanade.presentation.reader
|
||||
|
||||
import androidx.compose.foundation.Canvas
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
@Stable
|
||||
class DisplayRefreshHost {
|
||||
|
||||
internal var currentDisplayRefresh by mutableStateOf(false)
|
||||
|
||||
fun flash() {
|
||||
currentDisplayRefresh = true
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DisplayRefreshHost(
|
||||
hostState: DisplayRefreshHost,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val currentDisplayRefresh = hostState.currentDisplayRefresh
|
||||
LaunchedEffect(currentDisplayRefresh) {
|
||||
if (currentDisplayRefresh) {
|
||||
delay(200)
|
||||
hostState.currentDisplayRefresh = false
|
||||
}
|
||||
}
|
||||
|
||||
if (currentDisplayRefresh) {
|
||||
Canvas(
|
||||
modifier = modifier.fillMaxSize(),
|
||||
) {
|
||||
drawRect(Color.White)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -68,4 +68,9 @@ internal fun ColumnScope.GeneralPage(screenModel: ReaderSettingsScreenModel) {
|
|||
label = stringResource(R.string.pref_page_transitions),
|
||||
pref = screenModel.preferences.pageTransitions(),
|
||||
)
|
||||
|
||||
CheckboxItem(
|
||||
label = stringResource(R.string.pref_flash_page),
|
||||
pref = screenModel.preferences.flashOnPageChange(),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.anime.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.anime.interactor.GetAnimeExtensionLanguages
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.domain.source.service.ToggleLanguage
|
||||
|
@ -29,7 +29,7 @@ class AnimeExtensionFilterScreenModel(
|
|||
val events: Flow<AnimeExtensionFilterEvent> = _events.receiveAsFlow()
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
combine(
|
||||
getExtensionLanguages.subscribe(),
|
||||
preferences.enabledLanguages().changes(),
|
||||
|
|
|
@ -4,7 +4,7 @@ import android.app.Application
|
|||
import androidx.annotation.StringRes
|
||||
import androidx.compose.runtime.Immutable
|
||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||
import cafe.adriel.voyager.core.model.coroutineScope
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import eu.kanade.domain.extension.anime.interactor.GetAnimeExtensionsByType
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.presentation.components.SEARCH_DEBOUNCE_MILLIS
|
||||
|
@ -84,7 +84,7 @@ class AnimeExtensionsScreenModel(
|
|||
}
|
||||
}
|
||||
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
combine(
|
||||
state.map { it.searchQuery }.distinctUntilChanged().debounce(SEARCH_DEBOUNCE_MILLIS),
|
||||
_currentDownloads,
|
||||
|
@ -136,11 +136,11 @@ class AnimeExtensionsScreenModel(
|
|||
}
|
||||
}
|
||||
}
|
||||
coroutineScope.launchIO { findAvailableExtensions() }
|
||||
screenModelScope.launchIO { findAvailableExtensions() }
|
||||
|
||||
preferences.animeExtensionUpdatesCount().changes()
|
||||
.onEach { mutableState.update { state -> state.copy(updates = it) } }
|
||||
.launchIn(coroutineScope)
|
||||
.launchIn(screenModelScope)
|
||||
}
|
||||
|
||||
fun search(query: String?) {
|
||||
|
@ -150,7 +150,7 @@ class AnimeExtensionsScreenModel(
|
|||
}
|
||||
|
||||
fun updateAllExtensions() {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
state.value.items.values.flatten()
|
||||
.map { it.extension }
|
||||
.filterIsInstance<AnimeExtension.Installed>()
|
||||
|
@ -160,13 +160,13 @@ class AnimeExtensionsScreenModel(
|
|||
}
|
||||
|
||||
fun installExtension(extension: AnimeExtension.Available) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
extensionManager.installExtension(extension).collectToInstallUpdate(extension)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateExtension(extension: AnimeExtension.Installed) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
extensionManager.updateExtension(extension).collectToInstallUpdate(extension)
|
||||
}
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ class AnimeExtensionsScreenModel(
|
|||
}
|
||||
|
||||
fun findAvailableExtensions() {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
mutableState.update { it.copy(isRefreshing = true) }
|
||||
extensionManager.findAvailableExtensions()
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.ui.browse.anime.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.anime.interactor.AnimeExtensionSourceItem
|
||||
import eu.kanade.domain.extension.anime.interactor.GetAnimeExtensionSources
|
||||
import eu.kanade.domain.source.anime.interactor.ToggleAnimeSource
|
||||
|
@ -44,7 +44,7 @@ class AnimeExtensionDetailsScreenModel(
|
|||
val events: Flow<AnimeExtensionDetailsEvent> = _events.receiveAsFlow()
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
launch {
|
||||
extensionManager.installedExtensionsFlow
|
||||
.map { it.firstOrNull { extension -> extension.pkgName == pkgName } }
|
||||
|
|
|
@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.anime.migration.anime
|
|||
|
||||
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.animesource.AnimeSource
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
@ -30,7 +30,7 @@ class MigrateAnimeScreenModel(
|
|||
val events: Flow<MigrationAnimeEvent> = _events.receiveAsFlow()
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
mutableState.update { state ->
|
||||
state.copy(source = sourceManager.getOrStub(sourceId))
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.anime.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.entries.anime.interactor.GetAnime
|
||||
|
@ -16,7 +16,7 @@ class AnimeMigrateSearchScreenDialogScreenModel(
|
|||
) : StateScreenModel<AnimeMigrateSearchScreenDialogScreenModel.State>(State()) {
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
val anime = getAnime.await(animeId)!!
|
||||
|
||||
mutableState.update {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package eu.kanade.tachiyomi.ui.browse.anime.migration.search
|
||||
|
||||
import cafe.adriel.voyager.core.model.coroutineScope
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||
import eu.kanade.tachiyomi.ui.browse.anime.source.globalsearch.AnimeSearchScreenModel
|
||||
import eu.kanade.tachiyomi.ui.browse.anime.source.globalsearch.AnimeSourceFilter
|
||||
|
@ -18,7 +18,7 @@ class MigrateAnimeSearchScreenModel(
|
|||
|
||||
init {
|
||||
extensionFilter = initialExtensionFilter
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
val anime = getAnime.await(animeId)!!
|
||||
mutableState.update {
|
||||
it.copy(
|
||||
|
|
|
@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.anime.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.anime.interactor.GetAnimeSourcesWithFavoriteCount
|
||||
import eu.kanade.domain.source.service.SetMigrateSorting
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
|
@ -30,7 +30,7 @@ class MigrateAnimeSourceScreenModel(
|
|||
val channel = _channel.receiveAsFlow()
|
||||
|
||||
init {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
getSourcesWithFavoriteCount.subscribe()
|
||||
.catch {
|
||||
logcat(LogPriority.ERROR, it)
|
||||
|
@ -48,11 +48,11 @@ class MigrateAnimeSourceScreenModel(
|
|||
|
||||
preferences.migrationSortingDirection().changes()
|
||||
.onEach { mutableState.update { state -> state.copy(sortingDirection = it) } }
|
||||
.launchIn(coroutineScope)
|
||||
.launchIn(screenModelScope)
|
||||
|
||||
preferences.migrationSortingMode().changes()
|
||||
.onEach { mutableState.update { state -> state.copy(sortingMode = it) } }
|
||||
.launchIn(coroutineScope)
|
||||
.launchIn(screenModelScope)
|
||||
}
|
||||
|
||||
fun toggleSortingMode() {
|
||||
|
|
|
@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.anime.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.anime.interactor.GetLanguagesWithAnimeSources
|
||||
import eu.kanade.domain.source.anime.interactor.ToggleAnimeSource
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
|
@ -25,7 +25,7 @@ class AnimeSourcesFilterScreenModel(
|
|||
) : StateScreenModel<AnimeSourcesFilterScreenModel.State>(State.Loading) {
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
combine(
|
||||
getLanguagesWithSources.subscribe(),
|
||||
preferences.enabledLanguages().changes(),
|
||||
|
|
|
@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.anime.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.base.BasePreferences
|
||||
import eu.kanade.domain.source.anime.interactor.GetEnabledAnimeSources
|
||||
import eu.kanade.domain.source.anime.interactor.ToggleAnimeSource
|
||||
|
@ -37,7 +37,7 @@ class AnimeSourcesScreenModel(
|
|||
val events = _events.receiveAsFlow()
|
||||
|
||||
init {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
getEnabledAnimeSources.subscribe()
|
||||
.catch {
|
||||
logcat(LogPriority.ERROR, it)
|
||||
|
|
|
@ -12,7 +12,7 @@ import androidx.paging.cachedIn
|
|||
import androidx.paging.filter
|
||||
import androidx.paging.map
|
||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||
import cafe.adriel.voyager.core.model.coroutineScope
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import eu.kanade.core.preference.asState
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.domain.entries.anime.interactor.UpdateAnime
|
||||
|
@ -72,7 +72,7 @@ class BrowseAnimeSourceScreenModel(
|
|||
private val addTracks: AddAnimeTracks = Injekt.get(),
|
||||
) : StateScreenModel<BrowseAnimeSourceScreenModel.State>(State(Listing.valueOf(listingQuery))) {
|
||||
|
||||
var displayMode by sourcePreferences.sourceDisplayMode().asState(coroutineScope)
|
||||
var displayMode by sourcePreferences.sourceDisplayMode().asState(screenModelScope)
|
||||
|
||||
val source = sourceManager.getOrStub(sourceId)
|
||||
|
||||
|
@ -219,7 +219,7 @@ class BrowseAnimeSourceScreenModel(
|
|||
* @param anime the anime to update.
|
||||
*/
|
||||
fun changeAnimeFavorite(anime: Anime) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
var new = anime.copy(
|
||||
favorite = !anime.favorite,
|
||||
dateAdded = when (anime.favorite) {
|
||||
|
@ -240,7 +240,7 @@ class BrowseAnimeSourceScreenModel(
|
|||
}
|
||||
|
||||
fun addFavorite(anime: Anime) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
val categories = getCategories()
|
||||
val defaultCategoryId = libraryPreferences.defaultAnimeCategory().get()
|
||||
val defaultCategory = categories.find { it.id == defaultCategoryId.toLong() }
|
||||
|
@ -294,7 +294,7 @@ class BrowseAnimeSourceScreenModel(
|
|||
}
|
||||
|
||||
fun moveAnimeToCategories(anime: Anime, categoryIds: List<Long>) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
setAnimeCategories.await(
|
||||
animeId = anime.id,
|
||||
categoryIds = categoryIds.toList(),
|
||||
|
|
|
@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.manga.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.manga.interactor.GetMangaExtensionLanguages
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.domain.source.service.ToggleLanguage
|
||||
|
@ -29,7 +29,7 @@ class MangaExtensionFilterScreenModel(
|
|||
val events: Flow<MangaExtensionFilterEvent> = _events.receiveAsFlow()
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
combine(
|
||||
getExtensionLanguages.subscribe(),
|
||||
preferences.enabledLanguages().changes(),
|
||||
|
|
|
@ -4,7 +4,7 @@ import android.app.Application
|
|||
import androidx.annotation.StringRes
|
||||
import androidx.compose.runtime.Immutable
|
||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||
import cafe.adriel.voyager.core.model.coroutineScope
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import eu.kanade.domain.extension.manga.interactor.GetMangaExtensionsByType
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.presentation.components.SEARCH_DEBOUNCE_MILLIS
|
||||
|
@ -84,7 +84,7 @@ class MangaExtensionsScreenModel(
|
|||
}
|
||||
}
|
||||
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
combine(
|
||||
state.map { it.searchQuery }.distinctUntilChanged().debounce(SEARCH_DEBOUNCE_MILLIS),
|
||||
_currentDownloads,
|
||||
|
@ -137,11 +137,11 @@ class MangaExtensionsScreenModel(
|
|||
}
|
||||
}
|
||||
|
||||
coroutineScope.launchIO { findAvailableExtensions() }
|
||||
screenModelScope.launchIO { findAvailableExtensions() }
|
||||
|
||||
preferences.mangaExtensionUpdatesCount().changes()
|
||||
.onEach { mutableState.update { state -> state.copy(updates = it) } }
|
||||
.launchIn(coroutineScope)
|
||||
.launchIn(screenModelScope)
|
||||
}
|
||||
|
||||
fun search(query: String?) {
|
||||
|
@ -151,7 +151,7 @@ class MangaExtensionsScreenModel(
|
|||
}
|
||||
|
||||
fun updateAllExtensions() {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
state.value.items.values.flatten()
|
||||
.map { it.extension }
|
||||
.filterIsInstance<MangaExtension.Installed>()
|
||||
|
@ -161,13 +161,13 @@ class MangaExtensionsScreenModel(
|
|||
}
|
||||
|
||||
fun installExtension(extension: MangaExtension.Available) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
extensionManager.installExtension(extension).collectToInstallUpdate(extension)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateExtension(extension: MangaExtension.Installed) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
extensionManager.updateExtension(extension).collectToInstallUpdate(extension)
|
||||
}
|
||||
}
|
||||
|
@ -195,7 +195,7 @@ class MangaExtensionsScreenModel(
|
|||
}
|
||||
|
||||
fun findAvailableExtensions() {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
mutableState.update { it.copy(isRefreshing = true) }
|
||||
|
||||
extensionManager.findAvailableExtensions()
|
||||
|
|
|
@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.ui.browse.manga.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.manga.interactor.GetExtensionSources
|
||||
import eu.kanade.domain.extension.manga.interactor.MangaExtensionSourceItem
|
||||
import eu.kanade.domain.source.manga.interactor.ToggleMangaSource
|
||||
|
@ -44,7 +44,7 @@ class MangaExtensionDetailsScreenModel(
|
|||
val events: Flow<MangaExtensionDetailsEvent> = _events.receiveAsFlow()
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
launch {
|
||||
extensionManager.installedExtensionsFlow
|
||||
.map { it.firstOrNull { extension -> extension.pkgName == pkgName } }
|
||||
|
|
|
@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.manga.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.MangaSource
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
@ -30,7 +30,7 @@ class MigrateMangaScreenModel(
|
|||
val events: Flow<MigrationMangaEvent> = _events.receiveAsFlow()
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
mutableState.update { state ->
|
||||
state.copy(source = sourceManager.getOrStub(sourceId))
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.manga.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.entries.manga.interactor.GetManga
|
||||
|
@ -16,7 +16,7 @@ class MangaMigrateSearchScreenDialogScreenModel(
|
|||
) : StateScreenModel<MangaMigrateSearchScreenDialogScreenModel.State>(State()) {
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
val manga = getManga.await(mangaId)!!
|
||||
|
||||
mutableState.update {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package eu.kanade.tachiyomi.ui.browse.manga.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.manga.source.globalsearch.MangaSearchScreenModel
|
||||
import eu.kanade.tachiyomi.ui.browse.manga.source.globalsearch.MangaSourceFilter
|
||||
|
@ -18,7 +18,7 @@ class MigrateMangaSearchScreenModel(
|
|||
|
||||
init {
|
||||
extensionFilter = initialExtensionFilter
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
val manga = getManga.await(mangaId)!!
|
||||
mutableState.update {
|
||||
it.copy(
|
||||
|
|
|
@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.manga.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.manga.interactor.GetMangaSourcesWithFavoriteCount
|
||||
import eu.kanade.domain.source.service.SetMigrateSorting
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
|
@ -30,7 +30,7 @@ class MigrateMangaSourceScreenModel(
|
|||
val channel = _channel.receiveAsFlow()
|
||||
|
||||
init {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
getSourcesWithFavoriteCount.subscribe()
|
||||
.catch {
|
||||
logcat(LogPriority.ERROR, it)
|
||||
|
@ -48,11 +48,11 @@ class MigrateMangaSourceScreenModel(
|
|||
|
||||
preferences.migrationSortingDirection().changes()
|
||||
.onEach { mutableState.update { state -> state.copy(sortingDirection = it) } }
|
||||
.launchIn(coroutineScope)
|
||||
.launchIn(screenModelScope)
|
||||
|
||||
preferences.migrationSortingMode().changes()
|
||||
.onEach { mutableState.update { state -> state.copy(sortingMode = it) } }
|
||||
.launchIn(coroutineScope)
|
||||
.launchIn(screenModelScope)
|
||||
}
|
||||
|
||||
fun toggleSortingMode() {
|
||||
|
|
|
@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.manga.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.manga.interactor.GetLanguagesWithMangaSources
|
||||
import eu.kanade.domain.source.manga.interactor.ToggleMangaSource
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
|
@ -25,7 +25,7 @@ class MangaSourcesFilterScreenModel(
|
|||
) : StateScreenModel<MangaSourcesFilterScreenModel.State>(State.Loading) {
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
combine(
|
||||
getLanguagesWithSources.subscribe(),
|
||||
preferences.enabledLanguages().changes(),
|
||||
|
|
|
@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.manga.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.base.BasePreferences
|
||||
import eu.kanade.domain.source.manga.interactor.GetEnabledMangaSources
|
||||
import eu.kanade.domain.source.manga.interactor.ToggleExcludeFromMangaDataSaver
|
||||
|
@ -44,7 +44,7 @@ class MangaSourcesScreenModel(
|
|||
val events = _events.receiveAsFlow()
|
||||
|
||||
init {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
getEnabledSources.subscribe()
|
||||
.catch {
|
||||
logcat(LogPriority.ERROR, it)
|
||||
|
@ -61,7 +61,7 @@ class MangaSourcesScreenModel(
|
|||
)
|
||||
}
|
||||
}
|
||||
.launchIn(coroutineScope)
|
||||
.launchIn(screenModelScope)
|
||||
// SY <--
|
||||
}
|
||||
|
||||
|
|
|
@ -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.entries.manga.interactor.UpdateManga
|
||||
|
@ -72,7 +72,7 @@ class BrowseMangaSourceScreenModel(
|
|||
private val addTracks: AddMangaTracks = Injekt.get(),
|
||||
) : StateScreenModel<BrowseMangaSourceScreenModel.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 BrowseMangaSourceScreenModel(
|
|||
* @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 BrowseMangaSourceScreenModel(
|
|||
}
|
||||
|
||||
fun addFavorite(manga: Manga) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
val categories = getCategories()
|
||||
val defaultCategoryId = libraryPreferences.defaultMangaCategory().get()
|
||||
val defaultCategory = categories.find { it.id == defaultCategoryId.toLong() }
|
||||
|
@ -296,7 +296,7 @@ class BrowseMangaSourceScreenModel(
|
|||
}
|
||||
|
||||
fun moveMangaToCategories(manga: Manga, categoryIds: List<Long>) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
setMangaCategories.await(
|
||||
mangaId = manga.id,
|
||||
categoryIds = categoryIds.toList(),
|
||||
|
|
|
@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.ui.category.anime
|
|||
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
|
||||
|
@ -37,7 +37,7 @@ class AnimeCategoryScreenModel(
|
|||
val events = _events.receiveAsFlow()
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
val allCategories = if (libraryPreferences.hideHiddenCategoriesSettings().get()) {
|
||||
getVisibleCategories.subscribe()
|
||||
} else {
|
||||
|
@ -55,7 +55,7 @@ class AnimeCategoryScreenModel(
|
|||
}
|
||||
|
||||
fun createCategory(name: String) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
when (createCategoryWithName.await(name)) {
|
||||
is CreateAnimeCategoryWithName.Result.InternalError -> _events.send(
|
||||
AnimeCategoryEvent.InternalError,
|
||||
|
@ -67,7 +67,7 @@ class AnimeCategoryScreenModel(
|
|||
}
|
||||
|
||||
fun hideCategory(category: Category) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
when (hideCategory.await(category)) {
|
||||
is HideAnimeCategory.Result.InternalError -> _events.send(
|
||||
AnimeCategoryEvent.InternalError,
|
||||
|
@ -78,7 +78,7 @@ class AnimeCategoryScreenModel(
|
|||
}
|
||||
|
||||
fun deleteCategory(categoryId: Long) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
when (deleteCategory.await(categoryId = categoryId)) {
|
||||
is DeleteAnimeCategory.Result.InternalError -> _events.send(
|
||||
AnimeCategoryEvent.InternalError,
|
||||
|
@ -89,7 +89,7 @@ class AnimeCategoryScreenModel(
|
|||
}
|
||||
|
||||
fun sortAlphabetically() {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
when (reorderCategory.sortAlphabetically()) {
|
||||
is ReorderAnimeCategory.Result.InternalError -> _events.send(AnimeCategoryEvent.InternalError)
|
||||
else -> {}
|
||||
|
@ -98,7 +98,7 @@ class AnimeCategoryScreenModel(
|
|||
}
|
||||
|
||||
fun moveUp(category: Category) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
when (reorderCategory.moveUp(category)) {
|
||||
is ReorderAnimeCategory.Result.InternalError -> _events.send(
|
||||
AnimeCategoryEvent.InternalError,
|
||||
|
@ -109,7 +109,7 @@ class AnimeCategoryScreenModel(
|
|||
}
|
||||
|
||||
fun moveDown(category: Category) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
when (reorderCategory.moveDown(category)) {
|
||||
is ReorderAnimeCategory.Result.InternalError -> _events.send(
|
||||
AnimeCategoryEvent.InternalError,
|
||||
|
@ -120,7 +120,7 @@ class AnimeCategoryScreenModel(
|
|||
}
|
||||
|
||||
fun renameCategory(category: Category, name: String) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
when (renameCategory.await(category, name)) {
|
||||
is RenameAnimeCategory.Result.InternalError -> _events.send(
|
||||
AnimeCategoryEvent.InternalError,
|
||||
|
|
|
@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.ui.category.manga
|
|||
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
|
||||
|
@ -37,7 +37,7 @@ class MangaCategoryScreenModel(
|
|||
val events = _events.receiveAsFlow()
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
val allCategories = if (libraryPreferences.hideHiddenCategoriesSettings().get()) {
|
||||
getVisibleCategories.subscribe()
|
||||
} else {
|
||||
|
@ -55,7 +55,7 @@ class MangaCategoryScreenModel(
|
|||
}
|
||||
|
||||
fun createCategory(name: String) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
when (createCategoryWithName.await(name)) {
|
||||
is CreateMangaCategoryWithName.Result.InternalError -> _events.send(
|
||||
MangaCategoryEvent.InternalError,
|
||||
|
@ -67,7 +67,7 @@ class MangaCategoryScreenModel(
|
|||
}
|
||||
|
||||
fun hideCategory(category: Category) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
when (hideCategory.await(category)) {
|
||||
is HideMangaCategory.Result.InternalError -> _events.send(
|
||||
MangaCategoryEvent.InternalError,
|
||||
|
@ -78,7 +78,7 @@ class MangaCategoryScreenModel(
|
|||
}
|
||||
|
||||
fun deleteCategory(categoryId: Long) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
when (deleteCategory.await(categoryId = categoryId)) {
|
||||
is DeleteMangaCategory.Result.InternalError -> _events.send(
|
||||
MangaCategoryEvent.InternalError,
|
||||
|
@ -89,7 +89,7 @@ class MangaCategoryScreenModel(
|
|||
}
|
||||
|
||||
fun sortAlphabetically() {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
when (reorderCategory.sortAlphabetically()) {
|
||||
is ReorderMangaCategory.Result.InternalError -> _events.send(MangaCategoryEvent.InternalError)
|
||||
else -> {}
|
||||
|
@ -98,7 +98,7 @@ class MangaCategoryScreenModel(
|
|||
}
|
||||
|
||||
fun moveUp(category: Category) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
when (reorderCategory.moveUp(category)) {
|
||||
is ReorderMangaCategory.Result.InternalError -> _events.send(
|
||||
MangaCategoryEvent.InternalError,
|
||||
|
@ -109,7 +109,7 @@ class MangaCategoryScreenModel(
|
|||
}
|
||||
|
||||
fun moveDown(category: Category) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
when (reorderCategory.moveDown(category)) {
|
||||
is ReorderMangaCategory.Result.InternalError -> _events.send(
|
||||
MangaCategoryEvent.InternalError,
|
||||
|
@ -120,7 +120,7 @@ class MangaCategoryScreenModel(
|
|||
}
|
||||
|
||||
fun renameCategory(category: Category, name: String) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
when (renameCategory.await(category, name)) {
|
||||
is RenameMangaCategory.Result.InternalError -> _events.send(
|
||||
MangaCategoryEvent.InternalError,
|
||||
|
|
|
@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.deeplink.anime
|
|||
|
||||
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.entries.anime.model.toDomainAnime
|
||||
import eu.kanade.domain.entries.anime.model.toSAnime
|
||||
import eu.kanade.domain.items.episode.interactor.SyncEpisodesWithSource
|
||||
|
@ -32,7 +32,7 @@ class DeepLinkAnimeScreenModel(
|
|||
) : StateScreenModel<DeepLinkAnimeScreenModel.State>(State.Loading) {
|
||||
|
||||
init {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
val source = sourceManager.getCatalogueSources()
|
||||
.filterIsInstance<ResolvableAnimeSource>()
|
||||
.firstOrNull { it.getUriType(query) != UriType.Unknown }
|
||||
|
|
|
@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.deeplink.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.domain.entries.manga.model.toDomainManga
|
||||
import eu.kanade.domain.entries.manga.model.toSManga
|
||||
import eu.kanade.domain.items.chapter.interactor.SyncChaptersWithSource
|
||||
|
@ -32,7 +32,7 @@ class DeepLinkMangaScreenModel(
|
|||
) : StateScreenModel<DeepLinkMangaScreenModel.State>(State.Loading) {
|
||||
|
||||
init {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
val source = sourceManager.getCatalogueSources()
|
||||
.filterIsInstance<ResolvableMangaSource>()
|
||||
.firstOrNull { it.getUriType(query) != UriType.Unknown }
|
||||
|
|
|
@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.download.anime
|
|||
|
||||
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.anime.AnimeDownloadManager
|
||||
import eu.kanade.tachiyomi.data.download.anime.model.AnimeDownload
|
||||
|
@ -108,7 +108,7 @@ class AnimeDownloadQueueScreenModel(
|
|||
}
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
downloadManager.queueState
|
||||
.map { downloads ->
|
||||
downloads
|
||||
|
|
|
@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.download.manga
|
|||
|
||||
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.manga.MangaDownloadManager
|
||||
import eu.kanade.tachiyomi.data.download.manga.model.MangaDownload
|
||||
|
@ -114,7 +114,7 @@ class MangaDownloadQueueScreenModel(
|
|||
}
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
downloadManager.queueState
|
||||
.map { downloads ->
|
||||
downloads
|
||||
|
@ -211,7 +211,7 @@ class MangaDownloadQueueScreenModel(
|
|||
* @param download the download to observe its progress.
|
||||
*/
|
||||
private fun launchProgressJob(download: MangaDownload) {
|
||||
val job = coroutineScope.launch {
|
||||
val job = screenModelScope.launch {
|
||||
while (download.pages == null) {
|
||||
delay(50)
|
||||
}
|
||||
|
|
|
@ -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 AnimeCoverScreenModel(
|
|||
) : StateScreenModel<Anime?>(null) {
|
||||
|
||||
init {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
getAnime.subscribe(animeId)
|
||||
.collect { newAnime -> mutableState.update { newAnime } }
|
||||
}
|
||||
}
|
||||
|
||||
fun saveCover(context: Context) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
try {
|
||||
saveCoverInternal(context, temp = false)
|
||||
snackbarHostState.showSnackbar(
|
||||
|
@ -65,7 +65,7 @@ class AnimeCoverScreenModel(
|
|||
}
|
||||
|
||||
fun shareCover(context: Context) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
try {
|
||||
val uri = saveCoverInternal(context, temp = true) ?: return@launch
|
||||
withUIContext {
|
||||
|
@ -117,7 +117,7 @@ class AnimeCoverScreenModel(
|
|||
*/
|
||||
fun editCover(context: Context, data: Uri) {
|
||||
val anime = state.value ?: return
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
context.contentResolver.openInputStream(data)?.use {
|
||||
try {
|
||||
anime.editCover(Injekt.get(), it, updateAnime, coverCache)
|
||||
|
@ -131,7 +131,7 @@ class AnimeCoverScreenModel(
|
|||
|
||||
fun deleteCustomCover(context: Context) {
|
||||
val animeId = state.value?.id ?: return
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
try {
|
||||
coverCache.deleteCustomCover(animeId)
|
||||
updateAnime.awaitUpdateCoverLastModified(animeId)
|
||||
|
@ -143,7 +143,7 @@ class AnimeCoverScreenModel(
|
|||
}
|
||||
|
||||
private fun notifyCoverUpdated(context: Context) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
snackbarHostState.showSnackbar(
|
||||
context.getString(R.string.cover_updated),
|
||||
withDismissAction = true,
|
||||
|
@ -152,7 +152,7 @@ class AnimeCoverScreenModel(
|
|||
}
|
||||
|
||||
private fun notifyFailedCoverUpdate(context: Context, e: Throwable) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
snackbarHostState.showSnackbar(
|
||||
context.getString(R.string.notification_cover_update_failed),
|
||||
withDismissAction = true,
|
||||
|
|
|
@ -7,7 +7,7 @@ import androidx.compose.runtime.Immutable
|
|||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||
import cafe.adriel.voyager.core.model.coroutineScope
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import eu.kanade.core.preference.asState
|
||||
import eu.kanade.core.util.addOrRemove
|
||||
import eu.kanade.domain.entries.anime.interactor.SetAnimeViewerFlags
|
||||
|
@ -135,7 +135,7 @@ class AnimeScreenModel(
|
|||
val alwaysUseExternalPlayer = playerPreferences.alwaysUseExternalPlayer().get()
|
||||
val useExternalDownloader = downloadPreferences.useExternalDownloader().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 isUpdateIntervalEnabled = LibraryPreferences.ENTRY_OUTSIDE_RELEASE_PERIOD in libraryPreferences.autoUpdateItemRestrictions().get()
|
||||
|
@ -161,7 +161,7 @@ class AnimeScreenModel(
|
|||
}
|
||||
|
||||
init {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
combine(
|
||||
getAnimeAndEpisodes.subscribe(animeId).distinctUntilChanged(),
|
||||
downloadCache.changes,
|
||||
|
@ -179,7 +179,7 @@ class AnimeScreenModel(
|
|||
|
||||
observeDownloads()
|
||||
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
val anime = getAnimeAndEpisodes.awaitAnime(animeId)
|
||||
val episodes = getAnimeAndEpisodes.awaitEpisodes(animeId)
|
||||
.toEpisodeItems(anime)
|
||||
|
@ -206,7 +206,7 @@ class AnimeScreenModel(
|
|||
observeTrackers()
|
||||
|
||||
// Fetch info-episodes when needed
|
||||
if (coroutineScope.isActive) {
|
||||
if (screenModelScope.isActive) {
|
||||
val fetchFromSourceTasks = listOf(
|
||||
async { if (needRefreshInfo) fetchAnimeFromSource() },
|
||||
async { if (needRefreshEpisode) fetchEpisodesFromSource() },
|
||||
|
@ -220,7 +220,7 @@ class AnimeScreenModel(
|
|||
}
|
||||
|
||||
fun fetchAllFromSource(manualFetch: Boolean = true) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
updateSuccessState { it.copy(isRefreshingData = true) }
|
||||
val fetchFromSourceTasks = listOf(
|
||||
async { fetchAnimeFromSource(manualFetch) },
|
||||
|
@ -249,7 +249,7 @@ class AnimeScreenModel(
|
|||
if (e is HttpException && e.code == 103) return
|
||||
|
||||
logcat(LogPriority.ERROR, e)
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
snackbarHostState.showSnackbar(message = with(context) { e.formattedMessage })
|
||||
}
|
||||
}
|
||||
|
@ -258,7 +258,7 @@ class AnimeScreenModel(
|
|||
fun toggleFavorite() {
|
||||
toggleFavorite(
|
||||
onRemoved = {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
if (!hasDownloads()) return@launch
|
||||
val result = snackbarHostState.showSnackbar(
|
||||
message = context.getString(R.string.delete_downloads_for_anime),
|
||||
|
@ -281,7 +281,7 @@ class AnimeScreenModel(
|
|||
checkDuplicate: Boolean = true,
|
||||
) {
|
||||
val state = successState ?: return
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
val anime = state.anime
|
||||
|
||||
if (isFavorited) {
|
||||
|
@ -345,7 +345,7 @@ class AnimeScreenModel(
|
|||
|
||||
fun showChangeCategoryDialog() {
|
||||
val anime = successState?.anime ?: return
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
val categories = getCategories()
|
||||
val selection = getAnimeCategoryIds(anime)
|
||||
updateSuccessState { successState ->
|
||||
|
@ -367,7 +367,7 @@ class AnimeScreenModel(
|
|||
}
|
||||
|
||||
fun setFetchInterval(anime: Anime, interval: Int) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
updateAnime.awaitUpdateFetchInterval(
|
||||
// Custom intervals are negative
|
||||
anime.copy(fetchInterval = -interval),
|
||||
|
@ -417,7 +417,7 @@ class AnimeScreenModel(
|
|||
moveAnimeToCategory(categories)
|
||||
if (anime.favorite) return
|
||||
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
updateAnime.awaitUpdateFavorite(anime.id, true)
|
||||
}
|
||||
}
|
||||
|
@ -433,7 +433,7 @@ class AnimeScreenModel(
|
|||
}
|
||||
|
||||
private fun moveAnimeToCategory(categoryIds: List<Long>) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
setAnimeCategories.await(animeId, categoryIds)
|
||||
}
|
||||
}
|
||||
|
@ -452,7 +452,7 @@ class AnimeScreenModel(
|
|||
// Episodes list - start
|
||||
|
||||
private fun observeDownloads() {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
downloadManager.statusFlow()
|
||||
.filter { it.anime.id == successState?.anime?.id }
|
||||
.catch { error -> logcat(LogPriority.ERROR, error) }
|
||||
|
@ -463,7 +463,7 @@ class AnimeScreenModel(
|
|||
}
|
||||
}
|
||||
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
downloadManager.progressFlow()
|
||||
.filter { it.anime.id == successState?.anime?.id }
|
||||
.catch { error -> logcat(LogPriority.ERROR, error) }
|
||||
|
@ -550,7 +550,7 @@ class AnimeScreenModel(
|
|||
with(context) { e.formattedMessage }
|
||||
}
|
||||
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
snackbarHostState.showSnackbar(message = message)
|
||||
}
|
||||
val newAnime = animeRepository.getAnimeById(animeId)
|
||||
|
@ -562,7 +562,7 @@ class AnimeScreenModel(
|
|||
* @throws IllegalStateException if the swipe action is [LibraryPreferences.EpisodeSwipeAction.Disabled]
|
||||
*/
|
||||
fun episodeSwipe(episodeItem: EpisodeItem, swipeAction: LibraryPreferences.EpisodeSwipeAction) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
executeEpisodeSwipeAction(episodeItem, swipeAction)
|
||||
}
|
||||
}
|
||||
|
@ -640,7 +640,7 @@ class AnimeScreenModel(
|
|||
updateSuccessState { state ->
|
||||
state.copy(hasPromptedToAddBefore = true)
|
||||
}
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
val result = snackbarHostState.showSnackbar(
|
||||
message = context.getString(R.string.snack_add_to_anime_library),
|
||||
actionLabel = context.getString(R.string.action_add),
|
||||
|
@ -716,7 +716,7 @@ class AnimeScreenModel(
|
|||
* @param seen whether to mark episodes as seen or unseen.
|
||||
*/
|
||||
fun markEpisodesSeen(episodes: List<Episode>, seen: Boolean) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
setSeenStatus.await(
|
||||
seen = seen,
|
||||
episodes = episodes.toTypedArray(),
|
||||
|
@ -744,7 +744,7 @@ class AnimeScreenModel(
|
|||
* @param episodes the list of episodes to bookmark.
|
||||
*/
|
||||
fun bookmarkEpisodes(episodes: List<Episode>, bookmarked: Boolean) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
episodes
|
||||
.filterNot { it.bookmark == bookmarked }
|
||||
.map { EpisodeUpdate(id = it.id, bookmark = bookmarked) }
|
||||
|
@ -759,7 +759,7 @@ class AnimeScreenModel(
|
|||
* @param episodes the list of episodes to delete.
|
||||
*/
|
||||
fun deleteEpisodes(episodes: List<Episode>) {
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
try {
|
||||
successState?.let { state ->
|
||||
downloadManager.deleteEpisodes(
|
||||
|
@ -775,7 +775,7 @@ class AnimeScreenModel(
|
|||
}
|
||||
|
||||
private fun downloadNewEpisodes(episodes: List<Episode>) {
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
val anime = successState?.anime ?: return@launchNonCancellable
|
||||
val categories = getCategories.await(anime.id).map { it.id }
|
||||
if (episodes.isEmpty() || !anime.shouldDownloadNewEpisodes(
|
||||
|
@ -801,7 +801,7 @@ class AnimeScreenModel(
|
|||
TriState.ENABLED_IS -> Anime.EPISODE_SHOW_UNSEEN
|
||||
TriState.ENABLED_NOT -> Anime.EPISODE_SHOW_SEEN
|
||||
}
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
setAnimeEpisodeFlags.awaitSetUnseenFilter(anime, flag)
|
||||
}
|
||||
}
|
||||
|
@ -819,7 +819,7 @@ class AnimeScreenModel(
|
|||
TriState.ENABLED_NOT -> Anime.EPISODE_SHOW_NOT_DOWNLOADED
|
||||
}
|
||||
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
setAnimeEpisodeFlags.awaitSetDownloadedFilter(anime, flag)
|
||||
}
|
||||
}
|
||||
|
@ -837,7 +837,7 @@ class AnimeScreenModel(
|
|||
TriState.ENABLED_NOT -> Anime.EPISODE_SHOW_NOT_BOOKMARKED
|
||||
}
|
||||
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
setAnimeEpisodeFlags.awaitSetBookmarkFilter(anime, flag)
|
||||
}
|
||||
}
|
||||
|
@ -849,7 +849,7 @@ class AnimeScreenModel(
|
|||
fun setDisplayMode(mode: Long) {
|
||||
val anime = successState?.anime ?: return
|
||||
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
setAnimeEpisodeFlags.awaitSetDisplayMode(anime, mode)
|
||||
}
|
||||
}
|
||||
|
@ -861,14 +861,14 @@ class AnimeScreenModel(
|
|||
fun setSorting(sort: Long) {
|
||||
val anime = successState?.anime ?: return
|
||||
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
setAnimeEpisodeFlags.awaitSetSortingModeOrFlipOrder(anime, sort)
|
||||
}
|
||||
}
|
||||
|
||||
fun setCurrentSettingsAsDefault(applyToExisting: Boolean) {
|
||||
val anime = successState?.anime ?: return
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
libraryPreferences.setEpisodeSettingsDefault(anime)
|
||||
if (applyToExisting) {
|
||||
setAnimeDefaultEpisodeFlags.awaitAll()
|
||||
|
@ -973,7 +973,7 @@ class AnimeScreenModel(
|
|||
|
||||
private fun observeTrackers() {
|
||||
val anime = successState?.anime ?: return
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
getTracks.subscribe(anime.id)
|
||||
.catch { logcat(LogPriority.ERROR, it) }
|
||||
.map { tracks ->
|
||||
|
|
|
@ -34,8 +34,8 @@ import androidx.compose.ui.text.style.TextAlign
|
|||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||
import cafe.adriel.voyager.core.model.coroutineScope
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
import cafe.adriel.voyager.navigator.Navigator
|
||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||
|
@ -193,11 +193,11 @@ data class AnimeTrackInfoDialogHomeScreen(
|
|||
) : StateScreenModel<Model.State>(State()) {
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
refreshTrackers()
|
||||
}
|
||||
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
getTracks.subscribe(animeId)
|
||||
.catch { logcat(LogPriority.ERROR, it) }
|
||||
.distinctUntilChanged()
|
||||
|
@ -214,7 +214,7 @@ data class AnimeTrackInfoDialogHomeScreen(
|
|||
|
||||
fun registerEnhancedTracking(item: AnimeTrackItem) {
|
||||
item.tracker as EnhancedAnimeTracker
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
val anime = Injekt.get<GetAnime>().await(animeId) ?: return@launchNonCancellable
|
||||
try {
|
||||
val matchResult = item.tracker.match(anime) ?: throw Exception()
|
||||
|
@ -307,7 +307,7 @@ private data class TrackStatusSelectorScreen(
|
|||
}
|
||||
|
||||
fun setStatus() {
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
tracker.animeService.setRemoteAnimeStatus(track.toDbTrack(), state.value.selection)
|
||||
}
|
||||
}
|
||||
|
@ -367,7 +367,7 @@ private data class TrackEpisodeSelectorScreen(
|
|||
}
|
||||
|
||||
fun setEpisode() {
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
tracker.animeService.setRemoteLastEpisodeSeen(
|
||||
track.toDbTrack(),
|
||||
state.value.selection,
|
||||
|
@ -424,7 +424,7 @@ private data class TrackScoreSelectorScreen(
|
|||
}
|
||||
|
||||
fun setScore() {
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
tracker.animeService.setRemoteScore(track.toDbTrack(), state.value.selection)
|
||||
}
|
||||
}
|
||||
|
@ -552,7 +552,7 @@ private data class TrackDateSelectorScreen(
|
|||
// Convert to local time
|
||||
val localMillis =
|
||||
millis.convertEpochMillisZone(ZoneOffset.UTC, ZoneOffset.systemDefault())
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
if (start) {
|
||||
tracker.animeService.setRemoteStartDate(track.toDbTrack(), localMillis)
|
||||
} else {
|
||||
|
@ -644,7 +644,7 @@ private data class TrackDateRemoverScreen(
|
|||
fun getName() = tracker.name
|
||||
|
||||
fun removeDate() {
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
if (start) {
|
||||
tracker.animeService.setRemoteStartDate(track.toDbTrack(), 0)
|
||||
} else {
|
||||
|
@ -707,7 +707,7 @@ data class TrackServiceSearchScreen(
|
|||
}
|
||||
|
||||
fun trackingSearch(query: String) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
// To show loading state
|
||||
mutableState.update { it.copy(queryResult = null, selected = null) }
|
||||
|
||||
|
@ -729,7 +729,7 @@ data class TrackServiceSearchScreen(
|
|||
}
|
||||
|
||||
fun registerTracking(item: AnimeTrackSearch) {
|
||||
coroutineScope.launchNonCancellable { tracker.animeService.register(item, animeId) }
|
||||
screenModelScope.launchNonCancellable { tracker.animeService.register(item, animeId) }
|
||||
}
|
||||
|
||||
fun updateSelection(selected: AnimeTrackSearch) {
|
||||
|
@ -833,13 +833,13 @@ private data class TrackerAnimeRemoveScreen(
|
|||
fun isDeletable() = tracker is DeletableAnimeTracker
|
||||
|
||||
fun deleteAnimeFromService() {
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
(tracker as DeletableAnimeTracker).delete(track.toDbTrack())
|
||||
}
|
||||
}
|
||||
|
||||
fun unregisterTracking(serviceId: Long) {
|
||||
coroutineScope.launchNonCancellable { deleteTrack.await(animeId, serviceId) }
|
||||
screenModelScope.launchNonCancellable { deleteTrack.await(animeId, serviceId) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -186,6 +186,7 @@ class MangaScreen(
|
|||
onSortModeChanged = screenModel::setSorting,
|
||||
onDisplayModeChanged = screenModel::setDisplayMode,
|
||||
onSetAsDefault = screenModel::setCurrentSettingsAsDefault,
|
||||
onResetToDefault = screenModel::resetToDefaultSettings,
|
||||
)
|
||||
MangaScreenModel.Dialog.TrackSheet -> {
|
||||
NavigatorAdaptiveSheet(
|
||||
|
|
|
@ -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.entries.manga.interactor.UpdateManga
|
||||
|
@ -129,9 +129,9 @@ class MangaScreenModel(
|
|||
val chapterSwipeStartAction = libraryPreferences.swipeChapterEndAction().get()
|
||||
val chapterSwipeEndAction = libraryPreferences.swipeChapterStartAction().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 skipFiltered by readerPreferences.skipFiltered().asState(coroutineScope)
|
||||
val skipFiltered by readerPreferences.skipFiltered().asState(screenModelScope)
|
||||
|
||||
val isUpdateIntervalEnabled = LibraryPreferences.ENTRY_OUTSIDE_RELEASE_PERIOD in libraryPreferences.autoUpdateItemRestrictions().get()
|
||||
|
||||
|
@ -156,7 +156,7 @@ class MangaScreenModel(
|
|||
}
|
||||
|
||||
init {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
combine(
|
||||
getMangaAndChapters.subscribe(mangaId).distinctUntilChanged(),
|
||||
downloadCache.changes,
|
||||
|
@ -174,7 +174,7 @@ class MangaScreenModel(
|
|||
|
||||
observeDownloads()
|
||||
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
val manga = getMangaAndChapters.awaitManga(mangaId)
|
||||
val chapters = getMangaAndChapters.awaitChapters(mangaId)
|
||||
.toChapterItems(manga)
|
||||
|
@ -202,7 +202,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() },
|
||||
|
@ -216,7 +216,7 @@ class MangaScreenModel(
|
|||
}
|
||||
|
||||
fun fetchAllFromSource(manualFetch: Boolean = true) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
updateSuccessState { it.copy(isRefreshingData = true) }
|
||||
val fetchFromSourceTasks = listOf(
|
||||
async { fetchMangaFromSource(manualFetch) },
|
||||
|
@ -244,7 +244,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 })
|
||||
}
|
||||
}
|
||||
|
@ -253,7 +253,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),
|
||||
|
@ -276,7 +276,7 @@ class MangaScreenModel(
|
|||
checkDuplicate: Boolean = true,
|
||||
) {
|
||||
val state = successState ?: return
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
val manga = state.manga
|
||||
|
||||
if (isFavorited) {
|
||||
|
@ -341,7 +341,7 @@ class MangaScreenModel(
|
|||
|
||||
fun showChangeCategoryDialog() {
|
||||
val manga = successState?.manga ?: return
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
val categories = getCategories()
|
||||
val selection = getMangaCategoryIds(manga)
|
||||
updateSuccessState { successState ->
|
||||
|
@ -363,7 +363,7 @@ class MangaScreenModel(
|
|||
}
|
||||
|
||||
fun setFetchInterval(manga: Manga, interval: Int) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
updateManga.awaitUpdateFetchInterval(
|
||||
// Custom intervals are negative
|
||||
manga.copy(fetchInterval = -interval),
|
||||
|
@ -413,7 +413,7 @@ class MangaScreenModel(
|
|||
moveMangaToCategory(categories)
|
||||
if (manga.favorite) return
|
||||
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
updateManga.awaitUpdateFavorite(manga.id, true)
|
||||
}
|
||||
}
|
||||
|
@ -429,7 +429,7 @@ class MangaScreenModel(
|
|||
}
|
||||
|
||||
private fun moveMangaToCategory(categoryIds: List<Long>) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
setMangaCategories.await(mangaId, categoryIds)
|
||||
}
|
||||
}
|
||||
|
@ -448,7 +448,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) }
|
||||
|
@ -459,7 +459,7 @@ class MangaScreenModel(
|
|||
}
|
||||
}
|
||||
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
downloadManager.progressFlow()
|
||||
.filter { it.manga.id == successState?.manga?.id }
|
||||
.catch { error -> logcat(LogPriority.ERROR, error) }
|
||||
|
@ -546,7 +546,7 @@ class MangaScreenModel(
|
|||
with(context) { e.formattedMessage }
|
||||
}
|
||||
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
snackbarHostState.showSnackbar(message = message)
|
||||
}
|
||||
val newManga = mangaRepository.getMangaById(mangaId)
|
||||
|
@ -558,7 +558,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)
|
||||
}
|
||||
}
|
||||
|
@ -634,7 +634,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_manga_library),
|
||||
actionLabel = context.getString(R.string.action_add),
|
||||
|
@ -706,7 +706,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(),
|
||||
|
@ -730,7 +730,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) }
|
||||
|
@ -745,7 +745,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(
|
||||
|
@ -761,7 +761,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(
|
||||
|
@ -787,7 +787,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)
|
||||
}
|
||||
}
|
||||
|
@ -805,7 +805,7 @@ class MangaScreenModel(
|
|||
TriState.ENABLED_NOT -> Manga.CHAPTER_SHOW_NOT_DOWNLOADED
|
||||
}
|
||||
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
setMangaChapterFlags.awaitSetDownloadedFilter(manga, flag)
|
||||
}
|
||||
}
|
||||
|
@ -823,7 +823,7 @@ class MangaScreenModel(
|
|||
TriState.ENABLED_NOT -> Manga.CHAPTER_SHOW_NOT_BOOKMARKED
|
||||
}
|
||||
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
setMangaChapterFlags.awaitSetBookmarkFilter(manga, flag)
|
||||
}
|
||||
}
|
||||
|
@ -835,7 +835,7 @@ class MangaScreenModel(
|
|||
fun setDisplayMode(mode: Long) {
|
||||
val manga = successState?.manga ?: return
|
||||
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
setMangaChapterFlags.awaitSetDisplayMode(manga, mode)
|
||||
}
|
||||
}
|
||||
|
@ -847,14 +847,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()
|
||||
|
@ -865,6 +865,13 @@ class MangaScreenModel(
|
|||
}
|
||||
}
|
||||
|
||||
fun resetToDefaultSettings() {
|
||||
val manga = successState?.manga ?: return
|
||||
screenModelScope.launchNonCancellable {
|
||||
setMangaDefaultChapterFlags.await(manga)
|
||||
}
|
||||
}
|
||||
|
||||
fun toggleSelection(
|
||||
item: ChapterItem,
|
||||
selected: Boolean,
|
||||
|
@ -960,7 +967,7 @@ class MangaScreenModel(
|
|||
private fun observeTrackers() {
|
||||
val manga = successState?.manga ?: return
|
||||
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
getTracks.subscribe(manga.id)
|
||||
.catch { logcat(LogPriority.ERROR, it) }
|
||||
.map { tracks ->
|
||||
|
|
|
@ -34,8 +34,8 @@ import androidx.compose.ui.text.style.TextAlign
|
|||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||
import cafe.adriel.voyager.core.model.coroutineScope
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
import cafe.adriel.voyager.navigator.Navigator
|
||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||
|
@ -193,11 +193,11 @@ data class MangaTrackInfoDialogHomeScreen(
|
|||
) : StateScreenModel<Model.State>(State()) {
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
refreshTrackers()
|
||||
}
|
||||
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
getTracks.subscribe(mangaId)
|
||||
.catch { logcat(LogPriority.ERROR, it) }
|
||||
.distinctUntilChanged()
|
||||
|
@ -214,7 +214,7 @@ data class MangaTrackInfoDialogHomeScreen(
|
|||
|
||||
fun registerEnhancedTracking(item: MangaTrackItem) {
|
||||
item.tracker as EnhancedMangaTracker
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
val manga = Injekt.get<GetManga>().await(mangaId) ?: return@launchNonCancellable
|
||||
try {
|
||||
val matchResult = item.tracker.match(manga) ?: throw Exception()
|
||||
|
@ -307,7 +307,7 @@ private data class TrackStatusSelectorScreen(
|
|||
}
|
||||
|
||||
fun setStatus() {
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
tracker.mangaService.setRemoteMangaStatus(track.toDbTrack(), state.value.selection)
|
||||
}
|
||||
}
|
||||
|
@ -367,7 +367,7 @@ private data class TrackChapterSelectorScreen(
|
|||
}
|
||||
|
||||
fun setChapter() {
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
tracker.mangaService.setRemoteLastChapterRead(
|
||||
track.toDbTrack(),
|
||||
state.value.selection,
|
||||
|
@ -424,7 +424,7 @@ private data class TrackScoreSelectorScreen(
|
|||
}
|
||||
|
||||
fun setScore() {
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
tracker.mangaService.setRemoteScore(track.toDbTrack(), state.value.selection)
|
||||
}
|
||||
}
|
||||
|
@ -552,7 +552,7 @@ private data class TrackDateSelectorScreen(
|
|||
// Convert to local time
|
||||
val localMillis =
|
||||
millis.convertEpochMillisZone(ZoneOffset.UTC, ZoneOffset.systemDefault())
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
if (start) {
|
||||
tracker.mangaService.setRemoteStartDate(track.toDbTrack(), localMillis)
|
||||
} else {
|
||||
|
@ -644,7 +644,7 @@ private data class TrackDateRemoverScreen(
|
|||
fun getName() = tracker.name
|
||||
|
||||
fun removeDate() {
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
if (start) {
|
||||
tracker.mangaService.setRemoteStartDate(track.toDbTrack(), 0)
|
||||
} else {
|
||||
|
@ -707,7 +707,7 @@ data class TrackServiceSearchScreen(
|
|||
}
|
||||
|
||||
fun trackingSearch(query: String) {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
// To show loading state
|
||||
mutableState.update { it.copy(queryResult = null, selected = null) }
|
||||
|
||||
|
@ -729,7 +729,7 @@ data class TrackServiceSearchScreen(
|
|||
}
|
||||
|
||||
fun registerTracking(item: MangaTrackSearch) {
|
||||
coroutineScope.launchNonCancellable { tracker.mangaService.register(item, mangaId) }
|
||||
screenModelScope.launchNonCancellable { tracker.mangaService.register(item, mangaId) }
|
||||
}
|
||||
|
||||
fun updateSelection(selected: MangaTrackSearch) {
|
||||
|
@ -833,13 +833,13 @@ private data class TrackerMangaRemoveScreen(
|
|||
fun isDeletable() = tracker is DeletableMangaTracker
|
||||
|
||||
fun deleteMangaFromService() {
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
(tracker as DeletableMangaTracker).delete(track.toDbTrack())
|
||||
}
|
||||
}
|
||||
|
||||
fun unregisterTracking(serviceId: Long) {
|
||||
coroutineScope.launchNonCancellable { deleteTrack.await(mangaId, serviceId) }
|
||||
screenModelScope.launchNonCancellable { deleteTrack.await(mangaId, serviceId) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.history.anime
|
|||
|
||||
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.anime.AnimeHistoryUiModel
|
||||
import eu.kanade.tachiyomi.util.lang.toDateKey
|
||||
|
@ -46,7 +46,7 @@ class AnimeHistoryScreenModel(
|
|||
val query: StateFlow<String?> = _query.asStateFlow()
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
_query.collectLatest { query ->
|
||||
getHistory.subscribe(query ?: "")
|
||||
.distinctUntilChanged()
|
||||
|
@ -62,7 +62,7 @@ class AnimeHistoryScreenModel(
|
|||
}
|
||||
|
||||
fun search(query: String?) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
_query.emit(query)
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ class AnimeHistoryScreenModel(
|
|||
}
|
||||
|
||||
fun getNextEpisodeForAnime(animeId: Long, episodeId: Long) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
sendNextEpisodeEvent(getNextEpisodes.await(animeId, episodeId, onlyUnseen = false))
|
||||
}
|
||||
}
|
||||
|
@ -98,19 +98,19 @@ class AnimeHistoryScreenModel(
|
|||
}
|
||||
|
||||
fun removeFromHistory(history: AnimeHistoryWithRelations) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
removeHistory.await(history)
|
||||
}
|
||||
}
|
||||
|
||||
fun removeAllFromHistory(animeId: Long) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
removeHistory.await(animeId)
|
||||
}
|
||||
}
|
||||
|
||||
fun removeAllHistory() {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
val result = removeHistory.awaitAll()
|
||||
if (!result) return@launchIO
|
||||
_events.send(Event.HistoryCleared)
|
||||
|
|
|
@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.history.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.core.util.insertSeparators
|
||||
import eu.kanade.presentation.history.manga.MangaHistoryUiModel
|
||||
import eu.kanade.tachiyomi.util.lang.toDateKey
|
||||
|
@ -46,7 +46,7 @@ class MangaHistoryScreenModel(
|
|||
val query: StateFlow<String?> = _query.asStateFlow()
|
||||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
_query.collectLatest { query ->
|
||||
getHistory.subscribe(query ?: "")
|
||||
.distinctUntilChanged()
|
||||
|
@ -62,7 +62,7 @@ class MangaHistoryScreenModel(
|
|||
}
|
||||
|
||||
fun search(query: String?) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
_query.emit(query)
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ class MangaHistoryScreenModel(
|
|||
}
|
||||
|
||||
fun getNextChapterForManga(mangaId: Long, chapterId: Long) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
sendNextChapterEvent(getNextChapters.await(mangaId, chapterId, onlyUnread = false))
|
||||
}
|
||||
}
|
||||
|
@ -98,19 +98,19 @@ class MangaHistoryScreenModel(
|
|||
}
|
||||
|
||||
fun removeFromHistory(history: MangaHistoryWithRelations) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
removeHistory.await(history)
|
||||
}
|
||||
}
|
||||
|
||||
fun removeAllFromHistory(mangaId: Long) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
removeHistory.await(mangaId)
|
||||
}
|
||||
}
|
||||
|
||||
fun removeAllHistory() {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
val result = removeHistory.awaitAll()
|
||||
if (!result) return@launchIO
|
||||
_events.send(Event.HistoryCleared)
|
||||
|
|
|
@ -6,7 +6,7 @@ import androidx.compose.runtime.setValue
|
|||
import androidx.compose.ui.util.fastAny
|
||||
import androidx.compose.ui.util.fastMap
|
||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||
import cafe.adriel.voyager.core.model.coroutineScope
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import eu.kanade.core.preference.PreferenceMutableState
|
||||
import eu.kanade.core.preference.asState
|
||||
import eu.kanade.core.util.fastDistinctBy
|
||||
|
@ -93,11 +93,11 @@ class AnimeLibraryScreenModel(
|
|||
) : StateScreenModel<AnimeLibraryScreenModel.State>(State()) {
|
||||
|
||||
var activeCategoryIndex: Int by libraryPreferences.lastUsedAnimeCategory().asState(
|
||||
coroutineScope,
|
||||
screenModelScope,
|
||||
)
|
||||
|
||||
init {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
combine(
|
||||
state.map { it.searchQuery }.debounce(SEARCH_DEBOUNCE_MILLIS),
|
||||
getLibraryFlow(),
|
||||
|
@ -142,7 +142,7 @@ class AnimeLibraryScreenModel(
|
|||
)
|
||||
}
|
||||
}
|
||||
.launchIn(coroutineScope)
|
||||
.launchIn(screenModelScope)
|
||||
|
||||
combine(
|
||||
getAnimelibItemPreferencesFlow(),
|
||||
|
@ -164,7 +164,7 @@ class AnimeLibraryScreenModel(
|
|||
state.copy(hasActiveFilters = it)
|
||||
}
|
||||
}
|
||||
.launchIn(coroutineScope)
|
||||
.launchIn(screenModelScope)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -443,7 +443,7 @@ class AnimeLibraryScreenModel(
|
|||
* @param amount the amount to queue or null to queue all
|
||||
*/
|
||||
private fun downloadUnseenEpisodes(animes: List<Anime>, amount: Int?) {
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
animes.forEach { anime ->
|
||||
val episodes = getNextEpisodes.await(anime.id)
|
||||
.fastFilterNot { episode ->
|
||||
|
@ -467,7 +467,7 @@ class AnimeLibraryScreenModel(
|
|||
*/
|
||||
fun markSeenSelection(seen: Boolean) {
|
||||
val animes = state.value.selection.toList()
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
animes.forEach { anime ->
|
||||
setSeenStatus.await(
|
||||
anime = anime.anime,
|
||||
|
@ -486,7 +486,7 @@ class AnimeLibraryScreenModel(
|
|||
* @param deleteEpisodes whether to delete downloaded episodes.
|
||||
*/
|
||||
fun removeAnimes(animeList: List<Anime>, deleteFromLibrary: Boolean, deleteEpisodes: Boolean) {
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
val animeToDelete = animeList.distinctBy { it.id }
|
||||
|
||||
if (deleteFromLibrary) {
|
||||
|
@ -523,7 +523,7 @@ class AnimeLibraryScreenModel(
|
|||
addCategories: List<Long>,
|
||||
removeCategories: List<Long>,
|
||||
) {
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
animeList.forEach { anime ->
|
||||
val categoryIds = getCategories.await(anime.id)
|
||||
.map { it.id }
|
||||
|
@ -537,12 +537,12 @@ class AnimeLibraryScreenModel(
|
|||
}
|
||||
|
||||
fun getDisplayMode(): PreferenceMutableState<LibraryDisplayMode> {
|
||||
return libraryPreferences.displayMode().asState(coroutineScope)
|
||||
return libraryPreferences.displayMode().asState(screenModelScope)
|
||||
}
|
||||
|
||||
fun getColumnsPreferenceForCurrentOrientation(isLandscape: Boolean): PreferenceMutableState<Int> {
|
||||
return (if (isLandscape) libraryPreferences.animeLandscapeColumns() else libraryPreferences.animePortraitColumns()).asState(
|
||||
coroutineScope,
|
||||
screenModelScope,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -646,7 +646,7 @@ class AnimeLibraryScreenModel(
|
|||
}
|
||||
|
||||
fun openChangeCategoryDialog() {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
// Create a copy of selected anime
|
||||
val animeList = state.value.selection.map { it.anime }
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package eu.kanade.tachiyomi.ui.library.anime
|
||||
|
||||
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
|
||||
|
@ -47,7 +47,7 @@ class AnimeLibrarySettingsScreenModel(
|
|||
mode: AnimeLibrarySort.Type,
|
||||
direction: AnimeLibrarySort.Direction,
|
||||
) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
setSortModeForCategory.await(category, mode, direction)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -93,11 +93,11 @@ class MangaLibraryScreenModel(
|
|||
) : StateScreenModel<MangaLibraryScreenModel.State>(State()) {
|
||||
|
||||
var activeCategoryIndex: Int by libraryPreferences.lastUsedMangaCategory().asState(
|
||||
coroutineScope,
|
||||
screenModelScope,
|
||||
)
|
||||
|
||||
init {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
combine(
|
||||
state.map { it.searchQuery }.debounce(SEARCH_DEBOUNCE_MILLIS),
|
||||
getLibraryFlow(),
|
||||
|
@ -142,7 +142,7 @@ class MangaLibraryScreenModel(
|
|||
)
|
||||
}
|
||||
}
|
||||
.launchIn(coroutineScope)
|
||||
.launchIn(screenModelScope)
|
||||
|
||||
combine(
|
||||
getLibraryItemPreferencesFlow(),
|
||||
|
@ -164,7 +164,7 @@ class MangaLibraryScreenModel(
|
|||
state.copy(hasActiveFilters = it)
|
||||
}
|
||||
}
|
||||
.launchIn(coroutineScope)
|
||||
.launchIn(screenModelScope)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -435,7 +435,7 @@ class MangaLibraryScreenModel(
|
|||
* @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 ->
|
||||
|
@ -459,7 +459,7 @@ class MangaLibraryScreenModel(
|
|||
*/
|
||||
fun markReadSelection(read: Boolean) {
|
||||
val mangas = state.value.selection.toList()
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
mangas.forEach { manga ->
|
||||
setReadStatus.await(
|
||||
manga = manga.manga,
|
||||
|
@ -478,7 +478,7 @@ class MangaLibraryScreenModel(
|
|||
* @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) {
|
||||
|
@ -515,7 +515,7 @@ class MangaLibraryScreenModel(
|
|||
addCategories: List<Long>,
|
||||
removeCategories: List<Long>,
|
||||
) {
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
mangaList.forEach { manga ->
|
||||
val categoryIds = getCategories.await(manga.id)
|
||||
.map { it.id }
|
||||
|
@ -529,12 +529,12 @@ class MangaLibraryScreenModel(
|
|||
}
|
||||
|
||||
fun getDisplayMode(): PreferenceMutableState<LibraryDisplayMode> {
|
||||
return libraryPreferences.displayMode().asState(coroutineScope)
|
||||
return libraryPreferences.displayMode().asState(screenModelScope)
|
||||
}
|
||||
|
||||
fun getColumnsPreferenceForCurrentOrientation(isLandscape: Boolean): PreferenceMutableState<Int> {
|
||||
return (if (isLandscape) libraryPreferences.mangaLandscapeColumns() else libraryPreferences.mangaPortraitColumns()).asState(
|
||||
coroutineScope,
|
||||
screenModelScope,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -638,7 +638,7 @@ class MangaLibraryScreenModel(
|
|||
}
|
||||
|
||||
fun openChangeCategoryDialog() {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
// Create a copy of selected manga
|
||||
val mangaList = state.value.selection.map { it.manga }
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package eu.kanade.tachiyomi.ui.library.manga
|
||||
|
||||
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
|
||||
|
@ -47,7 +47,7 @@ class MangaLibrarySettingsScreenModel(
|
|||
mode: MangaLibrarySort.Type,
|
||||
direction: MangaLibrarySort.Direction,
|
||||
) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
setSortModeForCategory.await(category, mode, direction)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -104,8 +104,8 @@ 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,
|
||||
|
@ -114,7 +114,7 @@ private class MoreScreenModel(
|
|||
|
||||
init {
|
||||
// Handle running/paused status change and queue progress updating
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
combine(
|
||||
downloadManager.isDownloaderRunning,
|
||||
downloadManager.queueState,
|
||||
|
|
|
@ -42,6 +42,7 @@ import com.google.android.material.transition.platform.MaterialContainerTransfor
|
|||
import dev.chrisbanes.insetter.applyInsetter
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.presentation.reader.BrightnessOverlay
|
||||
import eu.kanade.presentation.reader.DisplayRefreshHost
|
||||
import eu.kanade.presentation.reader.OrientationModeSelectDialog
|
||||
import eu.kanade.presentation.reader.PageIndicatorText
|
||||
import eu.kanade.presentation.reader.ReaderPageActionsDialog
|
||||
|
@ -122,6 +123,7 @@ class ReaderActivity : BaseActivity() {
|
|||
|
||||
private var menuToggleToast: Toast? = null
|
||||
private var readingModeToast: Toast? = null
|
||||
private val displayRefreshHost = DisplayRefreshHost()
|
||||
|
||||
private val windowInsetsController by lazy { WindowInsetsControllerCompat(window, binding.root) }
|
||||
|
||||
|
@ -203,6 +205,9 @@ class ReaderActivity : BaseActivity() {
|
|||
ReaderViewModel.Event.ReloadViewerChapters -> {
|
||||
viewModel.state.value.viewerChapters?.let(::setChapters)
|
||||
}
|
||||
ReaderViewModel.Event.PageChanged -> {
|
||||
displayRefreshHost.flash()
|
||||
}
|
||||
is ReaderViewModel.Event.SetOrientation -> {
|
||||
setOrientation(event.orientation)
|
||||
}
|
||||
|
@ -329,6 +334,7 @@ class ReaderActivity : BaseActivity() {
|
|||
|
||||
val isHttpSource = viewModel.getSource() is HttpSource
|
||||
val isFullscreen by readerPreferences.fullscreen().collectAsState()
|
||||
val flashOnPageChange by readerPreferences.flashOnPageChange().collectAsState()
|
||||
|
||||
val cropBorderPaged by readerPreferences.cropBorders().collectAsState()
|
||||
val cropBorderWebtoon by readerPreferences.cropBordersWebtoon().collectAsState()
|
||||
|
@ -382,6 +388,12 @@ class ReaderActivity : BaseActivity() {
|
|||
value = state.brightnessOverlayValue,
|
||||
)
|
||||
|
||||
if (flashOnPageChange) {
|
||||
DisplayRefreshHost(
|
||||
hostState = displayRefreshHost,
|
||||
)
|
||||
}
|
||||
|
||||
val onDismissRequest = viewModel::closeDialog
|
||||
when (state.dialog) {
|
||||
is ReaderViewModel.Dialog.Loading -> {
|
||||
|
|
|
@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.reader
|
|||
|
||||
import android.app.Application
|
||||
import android.net.Uri
|
||||
import androidx.annotation.IntRange
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
@ -449,6 +450,8 @@ class ReaderViewModel @JvmOverloads constructor(
|
|||
if (inDownloadRange) {
|
||||
downloadNextChapters()
|
||||
}
|
||||
|
||||
eventChannel.trySend(Event.PageChanged)
|
||||
}
|
||||
|
||||
private fun downloadNextChapters() {
|
||||
|
@ -650,7 +653,7 @@ class ReaderViewModel @JvmOverloads constructor(
|
|||
fun setMangaReadingMode(readingModeType: ReadingModeType) {
|
||||
val manga = manga ?: return
|
||||
runBlocking(Dispatchers.IO) {
|
||||
setMangaViewerFlags.awaitSetMangaReadingMode(
|
||||
setMangaViewerFlags.awaitSetReadingMode(
|
||||
manga.id,
|
||||
readingModeType.flagValue.toLong(),
|
||||
)
|
||||
|
@ -689,7 +692,7 @@ class ReaderViewModel @JvmOverloads constructor(
|
|||
fun setMangaOrientationType(rotationType: OrientationType) {
|
||||
val manga = manga ?: return
|
||||
viewModelScope.launchIO {
|
||||
setMangaViewerFlags.awaitSetOrientationType(manga.id, rotationType.flagValue.toLong())
|
||||
setMangaViewerFlags.awaitSetOrientation(manga.id, rotationType.flagValue.toLong())
|
||||
val currChapters = state.value.viewerChapters
|
||||
if (currChapters != null) {
|
||||
// Save current page
|
||||
|
@ -926,7 +929,7 @@ class ReaderViewModel @JvmOverloads constructor(
|
|||
val viewer: Viewer? = null,
|
||||
val dialog: Dialog? = null,
|
||||
val menuVisible: Boolean = false,
|
||||
val brightnessOverlayValue: Int = 0,
|
||||
@IntRange(from = -100, to = 100) val brightnessOverlayValue: Int = 0,
|
||||
) {
|
||||
val currentChapter: ReaderChapter?
|
||||
get() = viewerChapters?.currChapter
|
||||
|
@ -945,6 +948,7 @@ class ReaderViewModel @JvmOverloads constructor(
|
|||
|
||||
sealed interface Event {
|
||||
data object ReloadViewerChapters : Event
|
||||
data object PageChanged : Event
|
||||
data class SetOrientation(val orientation: Int) : Event
|
||||
data class SetCoverResult(val result: SetAsCoverResult) : Event
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@ class ReaderPreferences(
|
|||
|
||||
fun pageTransitions() = preferenceStore.getBoolean("pref_enable_transitions_key", true)
|
||||
|
||||
fun flashOnPageChange() = preferenceStore.getBoolean("pref_reader_flash", false)
|
||||
|
||||
fun doubleTapAnimSpeed() = preferenceStore.getInt("pref_double_tap_anim_speed", 500)
|
||||
|
||||
fun showPageNumber() = preferenceStore.getBoolean("pref_show_page_number_key", true)
|
||||
|
|
|
@ -111,7 +111,7 @@ class PagerPageHolder(
|
|||
*/
|
||||
private fun setQueued() {
|
||||
progressIndicator.show()
|
||||
errorLayout?.root?.isVisible = false
|
||||
removeErrorLayout()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -119,7 +119,7 @@ class PagerPageHolder(
|
|||
*/
|
||||
private fun setLoading() {
|
||||
progressIndicator.show()
|
||||
errorLayout?.root?.isVisible = false
|
||||
removeErrorLayout()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -127,7 +127,7 @@ class PagerPageHolder(
|
|||
*/
|
||||
private fun setDownloading() {
|
||||
progressIndicator.show()
|
||||
errorLayout?.root?.isVisible = false
|
||||
removeErrorLayout()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -135,7 +135,6 @@ class PagerPageHolder(
|
|||
*/
|
||||
private suspend fun setImage() {
|
||||
progressIndicator.setProgress(0)
|
||||
errorLayout?.root?.isVisible = false
|
||||
|
||||
val streamFn = page.stream ?: return
|
||||
|
||||
|
@ -172,6 +171,7 @@ class PagerPageHolder(
|
|||
pageBackground = background
|
||||
}
|
||||
}
|
||||
removeErrorLayout()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -282,4 +282,12 @@ class PagerPageHolder(
|
|||
errorLayout?.root?.isVisible = true
|
||||
return errorLayout!!
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the decode error layout from the holder, if found.
|
||||
*/
|
||||
private fun removeErrorLayout() {
|
||||
errorLayout?.root?.isVisible = false
|
||||
errorLayout = null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -181,7 +181,6 @@ class WebtoonPageHolder(
|
|||
*/
|
||||
private suspend fun setImage() {
|
||||
progressIndicator.setProgress(0)
|
||||
removeErrorLayout()
|
||||
|
||||
val streamFn = page?.stream ?: return
|
||||
|
||||
|
@ -202,6 +201,7 @@ class WebtoonPageHolder(
|
|||
cropBorders = viewer.config.imageCropBorders,
|
||||
),
|
||||
)
|
||||
removeErrorLayout()
|
||||
}
|
||||
// Suspend the coroutine to close the input stream only when the WebtoonPageHolder is recycled
|
||||
suspendCancellableCoroutine<Nothing> { continuation ->
|
||||
|
@ -234,6 +234,7 @@ class WebtoonPageHolder(
|
|||
*/
|
||||
private fun onImageDecoded() {
|
||||
progressContainer.isVisible = false
|
||||
removeErrorLayout()
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package eu.kanade.tachiyomi.ui.stats.anime
|
||||
|
||||
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
|
||||
|
@ -40,7 +40,7 @@ class AnimeStatsScreenModel(
|
|||
private val loggedInTrackers by lazy { trackerManager.trackers.fastFilter { it.isLoggedIn && it is AnimeTracker } }
|
||||
|
||||
init {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
val animelibAnime = getAnimelibAnime.await()
|
||||
|
||||
val distinctLibraryAnime = animelibAnime.fastDistinctBy { it.id }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package eu.kanade.tachiyomi.ui.stats.manga
|
||||
|
||||
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
|
||||
|
@ -40,7 +40,7 @@ class MangaStatsScreenModel(
|
|||
private val loggedInTrackers by lazy { trackerManager.trackers.fastFilter { it.isLoggedIn && it is MangaTracker } }
|
||||
|
||||
init {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
val libraryManga = getLibraryManga.await()
|
||||
|
||||
val distinctLibraryManga = libraryManga.fastDistinctBy { it.id }
|
||||
|
|
|
@ -2,7 +2,7 @@ package eu.kanade.tachiyomi.ui.storage
|
|||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||
import cafe.adriel.voyager.core.model.coroutineScope
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import eu.kanade.presentation.more.storage.StorageItem
|
||||
import eu.kanade.presentation.more.storage.StorageScreenState
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
@ -36,7 +36,7 @@ abstract class CommonStorageScreenModel<T>(
|
|||
private val selectedCategory = MutableStateFlow(AllCategory)
|
||||
|
||||
init {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
val hideHiddenCategories = libraryPreferences.hideHiddenCategoriesSettings().get()
|
||||
|
||||
combine(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package eu.kanade.tachiyomi.ui.storage.anime
|
||||
|
||||
import cafe.adriel.voyager.core.model.coroutineScope
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import eu.kanade.tachiyomi.data.download.anime.AnimeDownloadCache
|
||||
import eu.kanade.tachiyomi.data.download.anime.AnimeDownloadManager
|
||||
import eu.kanade.tachiyomi.ui.storage.CommonStorageScreenModel
|
||||
|
@ -39,7 +39,7 @@ class AnimeStorageScreenModel(
|
|||
getThumbnail = { anime.thumbnailUrl },
|
||||
) {
|
||||
override fun deleteEntry(id: Long) {
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
val anime = getLibraries.await().find {
|
||||
it.id == id
|
||||
}?.anime ?: return@launchNonCancellable
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package eu.kanade.tachiyomi.ui.storage.manga
|
||||
|
||||
import cafe.adriel.voyager.core.model.coroutineScope
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import eu.kanade.tachiyomi.data.download.manga.MangaDownloadCache
|
||||
import eu.kanade.tachiyomi.data.download.manga.MangaDownloadManager
|
||||
import eu.kanade.tachiyomi.ui.storage.CommonStorageScreenModel
|
||||
|
@ -39,7 +39,7 @@ class MangaStorageScreenModel(
|
|||
getThumbnail = { manga.thumbnailUrl },
|
||||
) {
|
||||
override fun deleteEntry(id: Long) {
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
val manga = getLibraries.await().find {
|
||||
it.id == id
|
||||
}?.manga ?: return@launchNonCancellable
|
||||
|
|
|
@ -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
|
||||
|
@ -67,8 +67,8 @@ class AnimeUpdatesScreenModel(
|
|||
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)
|
||||
|
||||
val useExternalDownloader = downloadPreferences.useExternalDownloader().get()
|
||||
|
||||
|
@ -77,7 +77,7 @@ class AnimeUpdatesScreenModel(
|
|||
private val selectedEpisodeIds: HashSet<Long> = HashSet()
|
||||
|
||||
init {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
// Set date limit for recent episodes
|
||||
val calendar = Calendar.getInstance().apply {
|
||||
time = Date()
|
||||
|
@ -103,7 +103,7 @@ class AnimeUpdatesScreenModel(
|
|||
}
|
||||
}
|
||||
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
merge(downloadManager.statusFlow(), downloadManager.progressFlow())
|
||||
.catch { logcat(LogPriority.ERROR, it) }
|
||||
.collect(this@AnimeUpdatesScreenModel::updateDownloadState)
|
||||
|
@ -135,7 +135,7 @@ class AnimeUpdatesScreenModel(
|
|||
|
||||
fun updateLibrary(): Boolean {
|
||||
val started = AnimeLibraryUpdateJob.startNow(Injekt.get<Application>())
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
_events.send(Event.LibraryUpdateTriggered(started))
|
||||
}
|
||||
return started
|
||||
|
@ -167,7 +167,7 @@ class AnimeUpdatesScreenModel(
|
|||
|
||||
fun downloadEpisodes(items: List<AnimeUpdatesItem>, action: EpisodeDownloadAction) {
|
||||
if (items.isEmpty()) return
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
when (action) {
|
||||
EpisodeDownloadAction.START -> {
|
||||
downloadEpisodes(items)
|
||||
|
@ -211,7 +211,7 @@ class AnimeUpdatesScreenModel(
|
|||
* @param seen whether to mark episodes as seen or unseen.
|
||||
*/
|
||||
fun markUpdatesSeen(updates: List<AnimeUpdatesItem>, seen: Boolean) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
setSeenStatus.await(
|
||||
seen = seen,
|
||||
episodes = updates
|
||||
|
@ -227,7 +227,7 @@ class AnimeUpdatesScreenModel(
|
|||
* @param updates the list of episodes to bookmark.
|
||||
*/
|
||||
fun bookmarkUpdates(updates: List<AnimeUpdatesItem>, bookmark: Boolean) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
updates
|
||||
.filterNot { it.update.bookmark == bookmark }
|
||||
.map { EpisodeUpdate(id = it.update.episodeId, bookmark = bookmark) }
|
||||
|
@ -241,7 +241,7 @@ class AnimeUpdatesScreenModel(
|
|||
* @param updatesItem the list of episodes to download.
|
||||
*/
|
||||
private fun downloadEpisodes(updatesItem: List<AnimeUpdatesItem>, alt: Boolean = false) {
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
val groupedUpdates = updatesItem.groupBy { it.update.animeId }.values
|
||||
for (updates in groupedUpdates) {
|
||||
val animeId = updates.first().update.animeId
|
||||
|
@ -260,7 +260,7 @@ class AnimeUpdatesScreenModel(
|
|||
* @param updatesItem list of episodes
|
||||
*/
|
||||
fun deleteEpisodes(updatesItem: List<AnimeUpdatesItem>) {
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
updatesItem
|
||||
.groupBy { it.update.animeId }
|
||||
.entries
|
||||
|
|
|
@ -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 MangaUpdatesScreenModel(
|
|||
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 MangaUpdatesScreenModel(
|
|||
}
|
||||
}
|
||||
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
merge(downloadManager.statusFlow(), downloadManager.progressFlow())
|
||||
.catch { logcat(LogPriority.ERROR, it) }
|
||||
.collect(this@MangaUpdatesScreenModel::updateDownloadState)
|
||||
|
@ -131,7 +131,7 @@ class MangaUpdatesScreenModel(
|
|||
|
||||
fun updateLibrary(): Boolean {
|
||||
val started = MangaLibraryUpdateJob.startNow(Injekt.get<Application>())
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
_events.send(Event.LibraryUpdateTriggered(started))
|
||||
}
|
||||
return started
|
||||
|
@ -163,7 +163,7 @@ class MangaUpdatesScreenModel(
|
|||
|
||||
fun downloadChapters(items: List<MangaUpdatesItem>, action: ChapterDownloadAction) {
|
||||
if (items.isEmpty()) return
|
||||
coroutineScope.launch {
|
||||
screenModelScope.launch {
|
||||
when (action) {
|
||||
ChapterDownloadAction.START -> {
|
||||
downloadChapters(items)
|
||||
|
@ -203,7 +203,7 @@ class MangaUpdatesScreenModel(
|
|||
* @param read whether to mark chapters as read or unread.
|
||||
*/
|
||||
fun markUpdatesRead(updates: List<MangaUpdatesItem>, read: Boolean) {
|
||||
coroutineScope.launchIO {
|
||||
screenModelScope.launchIO {
|
||||
setReadStatus.await(
|
||||
read = read,
|
||||
chapters = updates
|
||||
|
@ -219,7 +219,7 @@ class MangaUpdatesScreenModel(
|
|||
* @param updates the list of chapters to bookmark.
|
||||
*/
|
||||
fun bookmarkUpdates(updates: List<MangaUpdatesItem>, 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 MangaUpdatesScreenModel(
|
|||
* @param updatesItem the list of chapters to download.
|
||||
*/
|
||||
private fun downloadChapters(updatesItem: List<MangaUpdatesItem>) {
|
||||
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 MangaUpdatesScreenModel(
|
|||
* @param updatesItem list of chapters
|
||||
*/
|
||||
fun deleteChapters(updatesItem: List<MangaUpdatesItem>) {
|
||||
coroutineScope.launchNonCancellable {
|
||||
screenModelScope.launchNonCancellable {
|
||||
updatesItem
|
||||
.groupBy { it.update.mangaId }
|
||||
.entries
|
||||
|
|
|
@ -57,7 +57,8 @@ WHERE _id = :id;
|
|||
getMangaByUrlAndSource:
|
||||
SELECT *
|
||||
FROM mangas
|
||||
WHERE url = :url AND source = :source
|
||||
WHERE url = :url
|
||||
AND source = :source
|
||||
LIMIT 1;
|
||||
|
||||
getFavorites:
|
||||
|
@ -107,7 +108,8 @@ GROUP BY source;
|
|||
|
||||
deleteMangasNotInLibraryBySourceIds:
|
||||
DELETE FROM mangas
|
||||
WHERE favorite = 0 AND source IN :sourceIds;
|
||||
WHERE favorite = 0
|
||||
AND source IN :sourceIds;
|
||||
|
||||
insert:
|
||||
INSERT INTO mangas(source, url, artist, author, description, genre, title, status, thumbnail_url, favorite, last_update, next_update, initialized, viewer, chapter_flags, cover_last_modified, date_added, update_strategy, calculate_interval, last_modified_at)
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -332,6 +332,8 @@
|
|||
<string name="pref_double_tap_zoom">Double tap to zoom</string>
|
||||
<string name="pref_cutout_short">Show content in cutout area</string>
|
||||
<string name="pref_page_transitions">Animate page transitions</string>
|
||||
<string name="pref_flash_page">Flash white on page change</string>
|
||||
<string name="pref_flash_page_summ">Reduces ghosting on e-ink displays</string>
|
||||
<string name="pref_double_tap_anim_speed">Double tap animation speed</string>
|
||||
<string name="pref_show_page_number">Show page number</string>
|
||||
<string name="pref_show_reading_mode">Show reading mode</string>
|
||||
|
|
|
@ -359,7 +359,6 @@ fun VerticalGridFastScroller(
|
|||
},
|
||||
)
|
||||
.height(ThumbLength)
|
||||
.padding(horizontal = 8.dp)
|
||||
.padding(end = endContentPadding)
|
||||
.width(ThumbThickness)
|
||||
.alpha(alpha.value)
|
||||
|
@ -436,7 +435,7 @@ object Scroller {
|
|||
}
|
||||
|
||||
private val ThumbLength = 48.dp
|
||||
private val ThumbThickness = 8.dp
|
||||
private val ThumbThickness = 12.dp
|
||||
private val ThumbShape = RoundedCornerShape(ThumbThickness / 2)
|
||||
private val FadeOutAnimationSpec = tween<Float>(
|
||||
durationMillis = ViewConfiguration.getScrollBarFadeDuration(),
|
||||
|
|
Loading…
Reference in a new issue