From 3d2ad327bc8f984e1dacb628b9b0b3e31d694068 Mon Sep 17 00:00:00 2001 From: Cuong-Tran Date: Sat, 31 May 2025 11:41:20 +0700 Subject: [PATCH] chore(manga-repository): Revert (in-memory) fast browsing (#965) * Revert "fix(manga-repository): Fix selected entries while bulk-selection won't show as selected (#927)" This reverts commit 303a266720451967d0dc902cc0649eaaaf7cdee3. * Revert "refactor(network-to-local): simplify networkToLocalManga (#910)" This reverts commit d33efced68a98b065ff8c19df74d8b2ce9a53451. * Revert "chore(network-local-manga): Reintroduce (in-memory) fast browsing (#909)" This reverts commit 3310784faf3bf817c0dee7c94ba68f8da8f4918c. * Add updateInfo parameter to insertNetworkManga method --- .../presentation/browse/GlobalSearchScreen.kt | 18 +----- .../browse/MigrateSearchScreen.kt | 18 +----- .../presentation/browse/SourceFeedScreen.kt | 18 +----- .../RelatedMangasComfortableGrid.kt | 2 +- .../components/RelatedMangasCompactGrid.kt | 2 +- .../browse/components/RelatedMangasList.kt | 2 +- .../presentation/components/TabbedScreen.kt | 16 +---- .../manga/components/RelatedMangasRow.kt | 2 +- .../ui/browse/BulkFavoriteScreenModel.kt | 5 -- .../ui/browse/feed/FeedScreenModel.kt | 9 +-- .../tachiyomi/ui/browse/feed/FeedTab.kt | 31 ++++----- .../migration/search/MigrateSearchScreen.kt | 41 +++++------- .../migration/search/SourceSearchScreen.kt | 40 +++--------- .../source/browse/BrowseSourceScreen.kt | 63 +++++++------------ .../source/browse/BrowseSourceScreenModel.kt | 4 -- .../ui/browse/source/feed/SourceFeedScreen.kt | 31 ++++----- .../source/feed/SourceFeedScreenModel.kt | 9 +-- .../source/globalsearch/GlobalSearchScreen.kt | 40 ++++-------- .../source/globalsearch/SearchScreenModel.kt | 10 ++- .../kanade/tachiyomi/ui/manga/MangaScreen.kt | 14 +---- .../tachiyomi/ui/manga/MangaScreenModel.kt | 14 ++--- .../tachiyomi/ui/manga/RelatedMangasScreen.kt | 42 ++++--------- .../exh/md/follows/MangaDexFollowsScreen.kt | 43 +++++-------- .../java/exh/recs/BrowseRecommendsScreen.kt | 52 ++++----------- .../main/java/exh/recs/RecommendsScreen.kt | 36 ++++------- .../java/exh/recs/RecommendsScreenModel.kt | 12 ++-- .../data/manga/MangaRepositoryImpl.kt | 8 +-- .../data/source/EHentaiPagingSource.kt | 4 +- .../data/source/SourcePagingSource.kt | 4 +- .../main/sqldelight/tachiyomi/data/mangas.sq | 15 +++-- .../manga/interactor/NetworkToLocalManga.kt | 8 +-- .../manga/repository/MangaRepository.kt | 2 +- 32 files changed, 186 insertions(+), 429 deletions(-) diff --git a/app/src/main/java/eu/kanade/presentation/browse/GlobalSearchScreen.kt b/app/src/main/java/eu/kanade/presentation/browse/GlobalSearchScreen.kt index 36a3ac166..54ce83c29 100644 --- a/app/src/main/java/eu/kanade/presentation/browse/GlobalSearchScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/browse/GlobalSearchScreen.kt @@ -6,7 +6,6 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import eu.kanade.domain.source.model.installedExtension import eu.kanade.presentation.browse.components.GlobalSearchCardRow @@ -22,7 +21,6 @@ import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchScreenModel import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SourceFilter import eu.kanade.tachiyomi.util.system.LocaleHelper import kotlinx.collections.immutable.ImmutableMap -import tachiyomi.core.common.util.lang.launchIO import tachiyomi.domain.manga.model.Manga import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.domain.source.model.Source as DomainSource @@ -45,7 +43,6 @@ fun GlobalSearchScreen( // KMK <-- ) { // KMK --> - val scope = rememberCoroutineScope() val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState() // KMK <-- @@ -62,24 +59,13 @@ fun GlobalSearchScreen( state.filteredItems.values .filterIsInstance() .flatMap { it.result } - .let { - scope.launchIO { - bulkFavoriteScreenModel.networkToLocalManga(it) - .forEach { bulkFavoriteScreenModel.select(it) } - } - } + .forEach { bulkFavoriteScreenModel.select(it) } }, onReverseSelection = { state.filteredItems.values .filterIsInstance() .flatMap { it.result } - .let { - scope.launchIO { - bulkFavoriteScreenModel.reverseSelection( - bulkFavoriteScreenModel.networkToLocalManga(it), - ) - } - } + .let { bulkFavoriteScreenModel.reverseSelection(it) } }, ) } else { diff --git a/app/src/main/java/eu/kanade/presentation/browse/MigrateSearchScreen.kt b/app/src/main/java/eu/kanade/presentation/browse/MigrateSearchScreen.kt index 0a96969fa..831c2afb0 100644 --- a/app/src/main/java/eu/kanade/presentation/browse/MigrateSearchScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/browse/MigrateSearchScreen.kt @@ -4,7 +4,6 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.runtime.rememberCoroutineScope import eu.kanade.presentation.browse.components.GlobalSearchToolbar import eu.kanade.presentation.components.BulkSelectionToolbar import eu.kanade.tachiyomi.source.CatalogueSource @@ -12,7 +11,6 @@ import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchItemResult import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchScreenModel import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SourceFilter -import tachiyomi.core.common.util.lang.launchIO import tachiyomi.domain.manga.model.Manga import tachiyomi.presentation.core.components.material.Scaffold @@ -35,7 +33,6 @@ fun MigrateSearchScreen( // KMK <-- ) { // KMK --> - val scope = rememberCoroutineScope() val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState() // KMK <-- @@ -52,24 +49,13 @@ fun MigrateSearchScreen( state.filteredItems.values .filterIsInstance() .flatMap { it.result } - .let { - scope.launchIO { - bulkFavoriteScreenModel.networkToLocalManga(it) - .forEach { bulkFavoriteScreenModel.select(it) } - } - } + .forEach { bulkFavoriteScreenModel.select(it) } }, onReverseSelection = { state.filteredItems.values .filterIsInstance() .flatMap { it.result } - .let { - scope.launchIO { - bulkFavoriteScreenModel.reverseSelection( - bulkFavoriteScreenModel.networkToLocalManga(it), - ) - } - } + .let { bulkFavoriteScreenModel.reverseSelection(it) } }, ) } else { diff --git a/app/src/main/java/eu/kanade/presentation/browse/SourceFeedScreen.kt b/app/src/main/java/eu/kanade/presentation/browse/SourceFeedScreen.kt index 0e5a8f202..d805f3b43 100644 --- a/app/src/main/java/eu/kanade/presentation/browse/SourceFeedScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/browse/SourceFeedScreen.kt @@ -10,7 +10,6 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import dev.icerock.moko.resources.StringResource import eu.kanade.presentation.browse.components.BrowseSourceFloatingActionButton @@ -27,7 +26,6 @@ import eu.kanade.presentation.components.SearchToolbar import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf -import tachiyomi.core.common.util.lang.launchIO import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.source.model.FeedSavedSearch import tachiyomi.domain.source.model.SavedSearch @@ -114,7 +112,6 @@ fun SourceFeedScreen( // KMK <-- ) { // KMK --> - val scope = rememberCoroutineScope() val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState() // KMK <-- @@ -130,23 +127,12 @@ fun SourceFeedScreen( onSelectAll = { items.mapNotNull { it.results } .flatten() - .let { - scope.launchIO { - bulkFavoriteScreenModel.networkToLocalManga(it) - .forEach { bulkFavoriteScreenModel.select(it) } - } - } + .forEach { bulkFavoriteScreenModel.select(it) } }, onReverseSelection = { items.mapNotNull { it.results } .flatten() - .let { - scope.launchIO { - bulkFavoriteScreenModel.reverseSelection( - bulkFavoriteScreenModel.networkToLocalManga(it), - ) - } - } + .let { bulkFavoriteScreenModel.reverseSelection(it) } }, ) } else { diff --git a/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasComfortableGrid.kt b/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasComfortableGrid.kt index 52cac4641..4b910b642 100644 --- a/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasComfortableGrid.kt +++ b/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasComfortableGrid.kt @@ -80,7 +80,7 @@ fun RelatedMangasComfortableGrid( ) } items( - key = { "related-comfort-${relatedManga.mangaList[it].url.hashCode()}" }, + key = { "related-comfort-${relatedManga.mangaList[it].id}" }, count = relatedManga.mangaList.size, ) { index -> val manga by getManga(relatedManga.mangaList[index]) diff --git a/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasCompactGrid.kt b/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasCompactGrid.kt index c4158b471..054f556b9 100644 --- a/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasCompactGrid.kt +++ b/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasCompactGrid.kt @@ -79,7 +79,7 @@ fun RelatedMangasCompactGrid( ) } items( - key = { "related-compact-${relatedManga.mangaList[it].url.hashCode()}" }, + key = { "related-compact-${relatedManga.mangaList[it].id}" }, count = relatedManga.mangaList.size, ) { index -> val manga by getManga(relatedManga.mangaList[index]) diff --git a/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasList.kt b/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasList.kt index d0b05e667..a7b639e3e 100644 --- a/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasList.kt +++ b/app/src/main/java/eu/kanade/presentation/browse/components/RelatedMangasList.kt @@ -82,7 +82,7 @@ fun RelatedMangasList( ) } items( - key = { "related-list-${relatedManga.mangaList[it].url.hashCode()}" }, + key = { "related-list-${relatedManga.mangaList[it].id}" }, count = relatedManga.mangaList.size, ) { index -> val manga by getManga(relatedManga.mangaList[index]) diff --git a/app/src/main/java/eu/kanade/presentation/components/TabbedScreen.kt b/app/src/main/java/eu/kanade/presentation/components/TabbedScreen.kt index 012ead418..5799bcf96 100644 --- a/app/src/main/java/eu/kanade/presentation/components/TabbedScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/components/TabbedScreen.kt @@ -29,7 +29,6 @@ import eu.kanade.tachiyomi.ui.browse.feed.FeedScreenModel import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.launch -import tachiyomi.core.common.util.lang.launchIO import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.TabText import tachiyomi.presentation.core.i18n.stringResource @@ -69,25 +68,14 @@ fun TabbedScreen( feedState.items?.let { result -> result.mapNotNull { it.results } .flatten() - .let { - scope.launchIO { - bulkFavoriteScreenModel.networkToLocalManga(it) - .forEach { bulkFavoriteScreenModel.select(it) } - } - } + .forEach { bulkFavoriteScreenModel.select(it) } } }, onReverseSelection = { feedState.items?.let { result -> result.mapNotNull { it.results } .flatten() - .let { - scope.launchIO { - bulkFavoriteScreenModel.reverseSelection( - bulkFavoriteScreenModel.networkToLocalManga(it), - ) - } - } + .let { bulkFavoriteScreenModel.reverseSelection(it) } } }, ) diff --git a/app/src/main/java/eu/kanade/presentation/manga/components/RelatedMangasRow.kt b/app/src/main/java/eu/kanade/presentation/manga/components/RelatedMangasRow.kt index 7baad53ae..428a8ef2c 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/components/RelatedMangasRow.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/components/RelatedMangasRow.kt @@ -66,7 +66,7 @@ fun RelatedMangaCardRow( contentPadding = PaddingValues(MaterialTheme.padding.small), horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.extraSmall), ) { - items(mangas, key = { "related-row-${it.url.hashCode()}" }) { + items(mangas, key = { "related-row-${it.id}" }) { val manga by getManga(it) MangaItem( title = manga.title, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/BulkFavoriteScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/BulkFavoriteScreenModel.kt index 848a99130..bb9d2f8cb 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/BulkFavoriteScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/BulkFavoriteScreenModel.kt @@ -34,7 +34,6 @@ import tachiyomi.domain.category.model.Category import tachiyomi.domain.chapter.interactor.SetMangaDefaultChapterFlags import tachiyomi.domain.library.service.LibraryPreferences import tachiyomi.domain.manga.interactor.GetDuplicateLibraryManga -import tachiyomi.domain.manga.interactor.NetworkToLocalManga import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.MangaWithChapterCount import tachiyomi.domain.manga.model.toMangaUpdate @@ -54,10 +53,6 @@ class BulkFavoriteScreenModel( private val coverCache: CoverCache = Injekt.get(), private val setMangaDefaultChapterFlags: SetMangaDefaultChapterFlags = Injekt.get(), private val addTracks: AddTracks = Injekt.get(), - - // KMK --> - val networkToLocalManga: NetworkToLocalManga = Injekt.get(), - // KMK <-- ) : StateScreenModel(initialState) { fun backHandler() { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/feed/FeedScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/feed/FeedScreenModel.kt index c97e9f807..72af525c3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/feed/FeedScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/feed/FeedScreenModel.kt @@ -61,7 +61,7 @@ open class FeedScreenModel( val sourceManager: SourceManager = Injekt.get(), val sourcePreferences: SourcePreferences = Injekt.get(), private val getManga: GetManga = Injekt.get(), - val networkToLocalManga: NetworkToLocalManga = Injekt.get(), + private val networkToLocalManga: NetworkToLocalManga = Injekt.get(), getFeedSavedSearchGlobal: GetFeedSavedSearchGlobal = Injekt.get(), private val getSavedSearchGlobalFeed: GetSavedSearchGlobalFeed = Injekt.get(), private val countFeedSavedSearchGlobal: CountFeedSavedSearchGlobal = Injekt.get(), @@ -305,8 +305,8 @@ open class FeedScreenModel( results = page .map { it.toDomainManga(itemUI.source!!.id) } .distinctBy { it.url } + .let { networkToLocalManga(it) } // KMK --> - // .let { networkToLocalManga(it) } .filter { !hideInLibraryFeedItems.get() || !it.favorite }, // KMK <-- ) @@ -344,11 +344,8 @@ open class FeedScreenModel( return produceState(initialValue = initialManga) { getManga.subscribe(initialManga.url, initialManga.source) .collectLatest { manga -> - /* KMK --> if (manga == null) return@collectLatest KMK <-- */ + if (manga == null) return@collectLatest value = manga - // KMK --> - ?: initialManga - // KMK <-- } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/feed/FeedTab.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/feed/FeedTab.kt index 0e1d7042f..aa575335b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/feed/FeedTab.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/feed/FeedTab.kt @@ -13,7 +13,6 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.platform.LocalHapticFeedback import cafe.adriel.voyager.core.screen.Screen @@ -37,7 +36,6 @@ import eu.kanade.tachiyomi.ui.manga.MangaScreen import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch -import tachiyomi.core.common.util.lang.launchIO import tachiyomi.domain.source.interactor.GetRemoteManga import tachiyomi.i18n.MR import tachiyomi.i18n.kmk.KMR @@ -55,7 +53,6 @@ fun Screen.feedTab( val state by screenModel.state.collectAsState() // KMK --> - val scope = rememberCoroutineScope() val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState() val showingFeedOrderScreen = rememberSaveable { mutableStateOf(false) } @@ -168,27 +165,21 @@ fun Screen.feedTab( // KMK --> onLongClickFeed = screenModel::openActionsDialog, // KMK <-- - onClickManga = { + onClickManga = { manga -> // KMK --> - scope.launchIO { - val manga = screenModel.networkToLocalManga(it) - if (bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.toggleSelection(manga) - } else { - // KMK <-- - navigator.push(MangaScreen(manga.id, true)) - } + if (bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.toggleSelection(manga) + } else { + // KMK <-- + navigator.push(MangaScreen(manga.id, true)) } }, // KMK --> - onLongClickManga = { - scope.launchIO { - val manga = screenModel.networkToLocalManga(it) - if (!bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.addRemoveManga(manga, haptic) - } else { - navigator.push(MangaScreen(manga.id, true)) - } + onLongClickManga = { manga -> + if (!bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.addRemoveManga(manga, haptic) + } else { + navigator.push(MangaScreen(manga.id, true)) } }, selection = bulkFavoriteState.selection, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateSearchScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateSearchScreen.kt index 578b26802..2024aea6d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateSearchScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateSearchScreen.kt @@ -4,7 +4,6 @@ import androidx.activity.compose.BackHandler import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.runtime.rememberCoroutineScope import cafe.adriel.voyager.core.model.rememberScreenModel import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.currentOrThrow @@ -14,7 +13,6 @@ import eu.kanade.presentation.util.Screen import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigrationListScreen import eu.kanade.tachiyomi.ui.manga.MangaScreen -import tachiyomi.core.common.util.lang.launchIO /** * Manual search [validSources] for manga to migrate to. @@ -32,7 +30,6 @@ class MigrateSearchScreen(private val mangaId: Long, private val validSources: L val dialogState by dialogScreenModel.state.collectAsState() // KMK --> - val scope = rememberCoroutineScope() val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() } val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState() @@ -55,33 +52,23 @@ class MigrateSearchScreen(private val mangaId: Long, private val validSources: L navigator.push(SourceSearchScreen(dialogState.manga!!, it.id, state.searchQuery)) // SY <-- }, - onClickItem = { + onClickItem = { manga -> // KMK --> - scope.launchIO { - val manga = screenModel.networkToLocalManga(it) - if (bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.toggleSelection(manga) - } else - // KMK <-- - { - // SY --> - navigator.items - .filterIsInstance() - .last() - .newSelectedItem = mangaId to manga.id - navigator.popUntil { it is MigrationListScreen } - // SY <-- - } - } - }, - onLongClickItem = { - // KMK --> - scope.launchIO { - val manga = screenModel.networkToLocalManga(it) + if (bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.toggleSelection(manga) + } else // KMK <-- - navigator.push(MangaScreen(manga.id, true)) - } + { + // SY --> + navigator.items + .filterIsInstance() + .last() + .newSelectedItem = mangaId to manga.id + navigator.popUntil { it is MigrationListScreen } + // SY <-- + } }, + onLongClickItem = { navigator.push(MangaScreen(it.id, true)) }, // KMK --> bulkFavoriteScreenModel = bulkFavoriteScreenModel, hasPinnedSources = screenModel.hasPinnedSources(), diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SourceSearchScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SourceSearchScreen.kt index 3c907a6fe..f8a8fd34b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SourceSearchScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SourceSearchScreen.kt @@ -7,7 +7,6 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalUriHandler @@ -34,7 +33,6 @@ import eu.kanade.tachiyomi.util.system.toast import kotlinx.collections.immutable.persistentListOf import mihon.presentation.core.util.collectAsLazyPagingItems import tachiyomi.core.common.Constants -import tachiyomi.core.common.util.lang.launchIO import tachiyomi.domain.manga.model.Manga import tachiyomi.i18n.sy.SYMR import tachiyomi.presentation.core.components.material.Scaffold @@ -68,7 +66,6 @@ data class SourceSearchScreen( // KMK --> val context = LocalContext.current - val scope = rememberCoroutineScope() val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() } val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState() @@ -92,23 +89,12 @@ data class SourceSearchScreen( onSelectAll = { mangaList.itemSnapshotList.items .map { it.value.first } - .let { - scope.launchIO { - bulkFavoriteScreenModel.networkToLocalManga(it) - .forEach { bulkFavoriteScreenModel.select(it) } - } - } + .forEach { bulkFavoriteScreenModel.select(it) } }, onReverseSelection = { mangaList.itemSnapshotList.items .map { it.value.first } - .let { - scope.launchIO { - bulkFavoriteScreenModel.reverseSelection( - bulkFavoriteScreenModel.networkToLocalManga(it), - ) - } - } + .let { bulkFavoriteScreenModel.reverseSelection(it) } }, ) } else { @@ -175,26 +161,16 @@ data class SourceSearchScreen( }, onHelpClick = { uriHandler.openUri(Constants.URL_HELP) }, onLocalSourceHelpClick = { uriHandler.openUri(LocalSource.HELP_URL) }, - onMangaClick = { + onMangaClick = { manga -> // KMK --> - scope.launchIO { - val manga = screenModel.networkToLocalManga(it) - if (bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.toggleSelection(manga) - } else { - // KMK <-- - openMigrateDialog(manga) - } - } - }, - onMangaLongClick = { - // KMK --> - scope.launchIO { - val manga = screenModel.networkToLocalManga(it) + if (bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.toggleSelection(manga) + } else { // KMK <-- - navigator.push(MangaScreen(manga.id, true)) + openMigrateDialog(manga) } }, + onMangaLongClick = { navigator.push(MangaScreen(it.id, true)) }, // KMK --> selection = bulkFavoriteState.selection, // KMK <-- diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreen.kt index ca03ae1b1..259bf054b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreen.kt @@ -202,23 +202,12 @@ data class BrowseSourceScreen( onSelectAll = { mangaList.itemSnapshotList.items .map { it.value.first } - .let { - scope.launchIO { - bulkFavoriteScreenModel.networkToLocalManga(it) - .forEach { bulkFavoriteScreenModel.select(it) } - } - } + .forEach { bulkFavoriteScreenModel.select(it) } }, onReverseSelection = { mangaList.itemSnapshotList.items .map { it.value.first } - .let { - scope.launchIO { - bulkFavoriteScreenModel.reverseSelection( - bulkFavoriteScreenModel.networkToLocalManga(it), - ) - } - } + .let { bulkFavoriteScreenModel.reverseSelection(it) } }, ) } else { @@ -367,36 +356,32 @@ data class BrowseSourceScreen( onWebViewClick = onWebViewClick, onHelpClick = { uriHandler.openUri(Constants.URL_HELP) }, onLocalSourceHelpClick = onHelpClick, - onMangaClick = { + onMangaClick = { manga -> // KMK --> - scope.launchIO { - val manga = screenModel.networkToLocalManga(it) - if (bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.toggleSelection(manga) - } else { - // KMK <-- - navigator.push( - MangaScreen( - mangaId = manga.id, - // KMK --> - // Finding the entry to be merged to, so we don't want to expand description - // so that user can see the `Merge to another` button - fromSource = smartSearchConfig == null, - // KMK <-- - smartSearchConfig = smartSearchConfig, - ), - ) - } + if (bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.toggleSelection(manga) + } else { + // KMK <-- + navigator.push( + MangaScreen( + mangaId = manga.id, + // KMK --> + // Finding the entry to be merged to, so we don't want to expand description + // so that user can see the `Merge to another` button + fromSource = smartSearchConfig == null, + // KMK <-- + smartSearchConfig = smartSearchConfig, + ), + ) } }, - onMangaLongClick = { + onMangaLongClick = { manga -> // KMK --> - scope.launchIO { - val manga = screenModel.networkToLocalManga(it) - if (bulkFavoriteState.selectionMode) { - navigator.push(MangaScreen(manga.id, true)) - } else { - // KMK <-- + if (bulkFavoriteState.selectionMode) { + navigator.push(MangaScreen(manga.id, true)) + } else { + // KMK <-- + scope.launchIO { val duplicates = screenModel.getDuplicateLibraryManga(manga) when { manga.favorite -> screenModel.setDialog(BrowseSourceScreenModel.Dialog.RemoveManga(manga)) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt index f32b44999..32176b79b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt @@ -70,7 +70,6 @@ import tachiyomi.domain.library.service.LibraryPreferences import tachiyomi.domain.manga.interactor.GetDuplicateLibraryManga import tachiyomi.domain.manga.interactor.GetFlatMetadataById import tachiyomi.domain.manga.interactor.GetManga -import tachiyomi.domain.manga.interactor.NetworkToLocalManga import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.MangaWithChapterCount import tachiyomi.domain.manga.model.toMangaUpdate @@ -115,9 +114,6 @@ open class BrowseSourceScreenModel( private val extensionManager: ExtensionManager = Injekt.get(), // KMK <-- - // KMK --> - val networkToLocalManga: NetworkToLocalManga = Injekt.get(), - // KMK <-- // SY --> unsortedPreferences: UnsortedPreferences = Injekt.get(), uiPreferences: UiPreferences = Injekt.get(), diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/feed/SourceFeedScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/feed/SourceFeedScreen.kt index 9b7204ece..fa352b258 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/feed/SourceFeedScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/feed/SourceFeedScreen.kt @@ -7,7 +7,6 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalHapticFeedback @@ -40,7 +39,6 @@ import exh.md.follows.MangaDexFollowsScreen import exh.source.anyIs import exh.source.isEhBasedSource import exh.util.nullIfBlank -import tachiyomi.core.common.util.lang.launchIO import tachiyomi.domain.UnsortedPreferences import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.source.interactor.GetRemoteManga @@ -67,7 +65,6 @@ class SourceFeedScreen(val sourceId: Long) : Screen() { val context = LocalContext.current // KMK --> - val scope = rememberCoroutineScope() screenModel.source.let { if (it is StubSource) { MissingSourceScreen( @@ -126,16 +123,13 @@ class SourceFeedScreen(val sourceId: Long) : Screen() { // onClickDelete = screenModel::openDeleteFeed, onLongClickFeed = screenModel::openActionsDialog, // KMK <-- - onClickManga = { + onClickManga = { manga -> // KMK --> - scope.launchIO { - val manga = screenModel.networkToLocalManga(it) - if (bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.toggleSelection(manga) - } else { - // KMK <-- - onMangaClick(navigator, manga) - } + if (bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.toggleSelection(manga) + } else { + // KMK <-- + onMangaClick(navigator, manga) } }, onClickSearch = { onSearchClick(navigator, screenModel.source, it) }, @@ -170,14 +164,11 @@ class SourceFeedScreen(val sourceId: Long) : Screen() { .filterIsInstance() .isNotEmpty() }, - onLongClickManga = { - scope.launchIO { - val manga = screenModel.networkToLocalManga(it) - if (!bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.addRemoveManga(manga, haptic) - } else { - navigator.push(MangaScreen(manga.id, true)) - } + onLongClickManga = { manga -> + if (!bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.addRemoveManga(manga, haptic) + } else { + navigator.push(MangaScreen(manga.id, true)) } }, bulkFavoriteScreenModel = bulkFavoriteScreenModel, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/feed/SourceFeedScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/feed/SourceFeedScreenModel.kt index 1b3754769..67d4ca917 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/feed/SourceFeedScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/feed/SourceFeedScreenModel.kt @@ -74,7 +74,7 @@ open class SourceFeedScreenModel( uiPreferences: UiPreferences = Injekt.get(), private val sourceManager: SourceManager = Injekt.get(), private val getManga: GetManga = Injekt.get(), - val networkToLocalManga: NetworkToLocalManga = Injekt.get(), + private val networkToLocalManga: NetworkToLocalManga = Injekt.get(), private val getFeedSavedSearchBySourceId: GetFeedSavedSearchBySourceId = Injekt.get(), private val getSavedSearchBySourceIdFeed: GetSavedSearchBySourceIdFeed = Injekt.get(), private val countFeedSavedSearchBySourceId: CountFeedSavedSearchBySourceId = Injekt.get(), @@ -251,7 +251,7 @@ open class SourceFeedScreenModel( val titles = withIOContext { page.map { it.toDomainManga(source.id) } .distinctBy { it.url } - /* KMK --> .let { networkToLocalManga(it) } KMK <-- */ + .let { networkToLocalManga(it) } } mutableState.update { state -> @@ -285,11 +285,8 @@ open class SourceFeedScreenModel( return produceState(initialValue = initialManga) { getManga.subscribe(initialManga.url, initialManga.source) .collectLatest { manga -> - /* KMK --> if (manga == null) return@collectLatest KMK <-- */ + if (manga == null) return@collectLatest value = manga - // KMK --> - ?: initialManga - // KMK <-- } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchScreen.kt index 2d52d0147..b7d073347 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchScreen.kt @@ -7,7 +7,6 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.platform.LocalHapticFeedback import cafe.adriel.voyager.core.model.rememberScreenModel @@ -20,7 +19,6 @@ import eu.kanade.presentation.util.Screen import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreen import eu.kanade.tachiyomi.ui.manga.MangaScreen -import tachiyomi.core.common.util.lang.launchIO import tachiyomi.presentation.core.screens.LoadingScreen class GlobalSearchScreen( @@ -49,7 +47,6 @@ class GlobalSearchScreen( } // KMK --> - val scope = rememberCoroutineScope() val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() } val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState() @@ -69,12 +66,7 @@ class GlobalSearchScreen( is SearchItemResult.Success -> { val manga = result.result.singleOrNull() if (manga != null) { - // KMK --> - scope.launchIO { - val localManga = screenModel.networkToLocalManga(manga) - // KMK <-- - navigator.replace(MangaScreen(localManga.id, true)) - } + navigator.replace(MangaScreen(manga.id, true)) } else { // Backoff to result screen showSingleLoadingScreen = false @@ -95,28 +87,22 @@ class GlobalSearchScreen( onClickSource = { navigator.push(BrowseSourceScreen(it.id, state.searchQuery)) }, - onClickItem = { + onClickItem = { manga -> // KMK --> - scope.launchIO { - val manga = screenModel.networkToLocalManga(it) - if (bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.toggleSelection(manga) - } else { - // KMK <-- - navigator.push(MangaScreen(manga.id, true)) - } + if (bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.toggleSelection(manga) + } else { + // KMK <-- + navigator.push(MangaScreen(manga.id, true)) } }, - onLongClickItem = { + onLongClickItem = { manga -> // KMK --> - scope.launchIO { - val manga = screenModel.networkToLocalManga(it) - if (!bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.addRemoveManga(manga, haptic) - } else { - // KMK <-- - navigator.push(MangaScreen(manga.id, true)) - } + if (!bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.addRemoveManga(manga, haptic) + } else { + // KMK <-- + navigator.push(MangaScreen(manga.id, true)) } }, // KMK --> diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/SearchScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/SearchScreenModel.kt index 0781f0c48..4bd01e941 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/SearchScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/SearchScreenModel.kt @@ -19,6 +19,7 @@ import kotlinx.coroutines.asCoroutineDispatcher import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.update import kotlinx.coroutines.isActive import kotlinx.coroutines.launch @@ -39,7 +40,7 @@ abstract class SearchScreenModel( sourcePreferences: SourcePreferences = Injekt.get(), private val sourceManager: SourceManager = Injekt.get(), private val extensionManager: ExtensionManager = Injekt.get(), - val networkToLocalManga: NetworkToLocalManga = Injekt.get(), + private val networkToLocalManga: NetworkToLocalManga = Injekt.get(), private val getManga: GetManga = Injekt.get(), private val preferences: SourcePreferences = Injekt.get(), ) : StateScreenModel(initialState) { @@ -83,12 +84,9 @@ abstract class SearchScreenModel( fun getManga(initialManga: Manga): androidx.compose.runtime.State { return produceState(initialValue = initialManga) { getManga.subscribe(initialManga.url, initialManga.source) - /* KMK --> .filterNotNull() KMK <-- */ + .filterNotNull() .collectLatest { manga -> value = manga - // KMK --> - ?: initialManga - // KMK <-- } } } @@ -192,7 +190,7 @@ abstract class SearchScreenModel( val titles = page.mangas .map { it.toDomainManga(source.id) } .distinctBy { it.url } - /* KMK --> .let { networkToLocalManga(it) } KMK <-- */ + .let { networkToLocalManga(it) } if (isActive) { updateItem(source, SearchItemResult.Success(titles)) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt index 569a49b9e..1a4c7d389 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt @@ -391,18 +391,8 @@ class MangaScreen( } showRelatedMangasScreen() }, - onRelatedMangaClick = { - scope.launchIO { - val manga = screenModel.networkToLocalManga(it) - navigator.push(MangaScreen(manga.id, true)) - } - }, - onRelatedMangaLongClick = { - scope.launchIO { - val manga = screenModel.networkToLocalManga(it) - bulkFavoriteScreenModel.addRemoveManga(manga, haptic) - } - }, + onRelatedMangaClick = { navigator.push(MangaScreen(it.id, true)) }, + onRelatedMangaLongClick = { bulkFavoriteScreenModel.addRemoveManga(it, haptic) }, onSourceClick = { if (successState.source !is StubSource) { val screen = when { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt index 8c7725a6b..c4ca561dc 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt @@ -97,6 +97,7 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChangedBy import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.flatMapConcat import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map @@ -202,7 +203,7 @@ class MangaScreenModel( private val smartSearchMerge: SmartSearchMerge = Injekt.get(), // KMK <-- private val updateMergedSettings: UpdateMergedSettings = Injekt.get(), - val networkToLocalManga: NetworkToLocalManga = Injekt.get(), + private val networkToLocalManga: NetworkToLocalManga = Injekt.get(), private val deleteMergeById: DeleteMergeById = Injekt.get(), private val getFlatMetadata: GetFlatMetadataById = Injekt.get(), private val getPagePreviews: GetPagePreviews = Injekt.get(), @@ -740,13 +741,10 @@ class MangaScreenModel( fun getManga(initialManga: Manga): RuntimeState { return produceState(initialValue = initialManga) { getManga.subscribe(initialManga.url, initialManga.source) - /* KMK --> .filterNotNull() KMK <-- */ + .filterNotNull() .flowWithLifecycle(lifecycle) .collectLatest { manga -> value = manga - // KMK --> - ?: initialManga - // KMK <-- } } } @@ -1220,7 +1218,7 @@ class MangaScreenModel( mangaList .map { it.toDomainManga(state.source.id) } .distinctBy { it.url } - /* KMK --> .let { networkToLocalManga(it) } KMK <-- */ + .let { networkToLocalManga(it, false) } } updateSuccessState { successState -> @@ -2073,14 +2071,14 @@ sealed interface RelatedManga { } internal fun List.removeDuplicates(manga: Manga): List { - val mangaHashes = HashSet().apply { add(manga.url.hashCode()) } + val mangaIds = HashSet().apply { add(manga.id) } return map { relatedManga -> if (relatedManga is Success) { Success( relatedManga.keyword, relatedManga.mangaList - .filter { mangaHashes.add(it.url.hashCode()) }, + .filter { mangaIds.add(it.id) }, ) } else { relatedManga diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/RelatedMangasScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/RelatedMangasScreen.kt index 06f8e6adb..bd5747131 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/RelatedMangasScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/RelatedMangasScreen.kt @@ -22,7 +22,6 @@ import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreen import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchScreen import kotlinx.coroutines.CoroutineScope -import tachiyomi.core.common.util.lang.launchIO import tachiyomi.domain.library.service.LibraryPreferences import tachiyomi.presentation.core.components.material.Scaffold import uy.kohesive.injekt.Injekt @@ -58,25 +57,14 @@ fun RelatedMangasScreen( successState.relatedMangasSorted?.let { result -> result.map { it as RelatedManga.Success } .flatMap { it.mangaList } - .let { - scope.launchIO { - bulkFavoriteScreenModel.networkToLocalManga(it) - .forEach { bulkFavoriteScreenModel.select(it) } - } - } + .forEach { bulkFavoriteScreenModel.select(it) } } }, onReverseSelection = { successState.relatedMangasSorted?.let { result -> result.map { it as RelatedManga.Success } .flatMap { it.mangaList } - .let { - scope.launchIO { - bulkFavoriteScreenModel.reverseSelection( - bulkFavoriteScreenModel.networkToLocalManga(it), - ) - } - } + .let { bulkFavoriteScreenModel.reverseSelection(it) } } }, ) @@ -100,24 +88,18 @@ fun RelatedMangasScreen( columns = getColumnsPreference(LocalConfiguration.current.orientation), displayMode = displayMode, contentPadding = paddingValues, - onMangaClick = { - scope.launchIO { - val manga = screenModel.networkToLocalManga(it) - if (bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.toggleSelection(manga) - } else { - navigator.push(MangaScreen(manga.id, true)) - } + onMangaClick = { manga -> + if (bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.toggleSelection(manga) + } else { + navigator.push(MangaScreen(manga.id, true)) } }, - onMangaLongClick = { - scope.launchIO { - val manga = screenModel.networkToLocalManga(it) - if (!bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.addRemoveManga(manga, haptic) - } else { - navigator.push(MangaScreen(manga.id, true)) - } + onMangaLongClick = { manga -> + if (!bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.addRemoveManga(manga, haptic) + } else { + navigator.push(MangaScreen(manga.id, true)) } }, onKeywordClick = { query -> diff --git a/app/src/main/java/exh/md/follows/MangaDexFollowsScreen.kt b/app/src/main/java/exh/md/follows/MangaDexFollowsScreen.kt index 3e71a73c9..db4cdbe2a 100644 --- a/app/src/main/java/exh/md/follows/MangaDexFollowsScreen.kt +++ b/app/src/main/java/exh/md/follows/MangaDexFollowsScreen.kt @@ -77,23 +77,12 @@ class MangaDexFollowsScreen(private val sourceId: Long) : Screen() { onSelectAll = { mangaList.itemSnapshotList.items .map { it.value.first } - .let { - scope.launchIO { - bulkFavoriteScreenModel.networkToLocalManga(it) - .forEach { bulkFavoriteScreenModel.select(it) } - } - } + .forEach { bulkFavoriteScreenModel.select(it) } }, onReverseSelection = { mangaList.itemSnapshotList.items .map { it.value.first } - .let { - scope.launchIO { - bulkFavoriteScreenModel.reverseSelection( - bulkFavoriteScreenModel.networkToLocalManga(it), - ) - } - } + .let { bulkFavoriteScreenModel.reverseSelection(it) } }, ) } else { @@ -128,26 +117,22 @@ class MangaDexFollowsScreen(private val sourceId: Long) : Screen() { onWebViewClick = null, onHelpClick = null, onLocalSourceHelpClick = null, - onMangaClick = { + onMangaClick = { manga -> // KMK --> - scope.launchIO { - val manga = screenModel.networkToLocalManga(it) - if (bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.toggleSelection(manga) - } else { - // KMK <-- - navigator.push(MangaScreen(manga.id, true)) - } + if (bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.toggleSelection(manga) + } else { + // KMK <-- + navigator.push(MangaScreen(manga.id, true)) } }, - onMangaLongClick = { + onMangaLongClick = { manga -> // KMK --> - scope.launchIO { - val manga = screenModel.networkToLocalManga(it) - if (bulkFavoriteState.selectionMode) { - navigator.push(MangaScreen(manga.id, true)) - } else { - // KMK <-- + if (bulkFavoriteState.selectionMode) { + navigator.push(MangaScreen(manga.id, true)) + } else { + // KMK <-- + scope.launchIO { val duplicates = screenModel.getDuplicateLibraryManga(manga) when { manga.favorite -> screenModel.setDialog(BrowseSourceScreenModel.Dialog.RemoveManga(manga)) diff --git a/app/src/main/java/exh/recs/BrowseRecommendsScreen.kt b/app/src/main/java/exh/recs/BrowseRecommendsScreen.kt index e9461093d..c2e99aced 100644 --- a/app/src/main/java/exh/recs/BrowseRecommendsScreen.kt +++ b/app/src/main/java/exh/recs/BrowseRecommendsScreen.kt @@ -7,7 +7,6 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalHapticFeedback @@ -25,7 +24,6 @@ import eu.kanade.tachiyomi.ui.browse.source.SourcesScreen import eu.kanade.tachiyomi.ui.manga.MangaScreen import eu.kanade.tachiyomi.ui.webview.WebViewActivity import mihon.presentation.core.util.collectAsLazyPagingItems -import tachiyomi.core.common.util.lang.launchIO import tachiyomi.domain.manga.model.Manga import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.screens.LoadingScreen @@ -52,7 +50,6 @@ class BrowseRecommendsScreen( } // KMK --> - val scope = rememberCoroutineScope() val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() } val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState() @@ -97,23 +94,12 @@ class BrowseRecommendsScreen( onSelectAll = { mangaList.itemSnapshotList.items .map { it.value.first } - .let { - scope.launchIO { - bulkFavoriteScreenModel.networkToLocalManga(it) - .forEach { bulkFavoriteScreenModel.select(it) } - } - } + .forEach { bulkFavoriteScreenModel.select(it) } }, onReverseSelection = { mangaList.itemSnapshotList.items .map { it.value.first } - .let { - scope.launchIO { - bulkFavoriteScreenModel.reverseSelection( - bulkFavoriteScreenModel.networkToLocalManga(it), - ) - } - } + .let { bulkFavoriteScreenModel.reverseSelection(it) } }, ) } else { @@ -153,37 +139,23 @@ class BrowseRecommendsScreen( onWebViewClick = null, onHelpClick = null, onLocalSourceHelpClick = null, - onMangaClick = { + onMangaClick = { manga -> // KMK --> - if (isExternalSource) { - onClickItem(it) + if (bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.toggleSelection(manga) } else { - scope.launchIO { - val manga = screenModel.networkToLocalManga(it) - if (bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.toggleSelection(manga) - } else { - // KMK <-- - onClickItem(manga) - } - } + // KMK <-- + onClickItem(manga) } }, - onMangaLongClick = { + onMangaLongClick = { manga -> // KMK --> - if (isExternalSource) { - onLongClickItem(it) + if (!bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.addRemoveManga(manga, haptic) } else { - scope.launchIO { - val manga = screenModel.networkToLocalManga(it) - if (!bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.addRemoveManga(manga, haptic) - } else { - onLongClickItem(manga) - } - } - // KMK <-- + onLongClickItem(manga) } + // KMK <-- }, // KMK --> selection = bulkFavoriteState.selection, diff --git a/app/src/main/java/exh/recs/RecommendsScreen.kt b/app/src/main/java/exh/recs/RecommendsScreen.kt index 140e8f875..caa60822e 100644 --- a/app/src/main/java/exh/recs/RecommendsScreen.kt +++ b/app/src/main/java/exh/recs/RecommendsScreen.kt @@ -4,7 +4,6 @@ import androidx.activity.compose.BackHandler import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalHapticFeedback import cafe.adriel.voyager.core.model.rememberScreenModel @@ -18,7 +17,6 @@ import eu.kanade.tachiyomi.ui.browse.source.SourcesScreen import eu.kanade.tachiyomi.ui.manga.MangaScreen import eu.kanade.tachiyomi.ui.webview.WebViewActivity import exh.recs.components.RecommendsScreen -import tachiyomi.core.common.util.lang.launchIO import tachiyomi.domain.manga.model.Manga import tachiyomi.presentation.core.screens.LoadingScreen @@ -40,7 +38,6 @@ class RecommendsScreen(val mangaId: Long, val sourceId: Long) : Screen() { val state by screenModel.state.collectAsState() // KMK --> - val scope = rememberCoroutineScope() val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() } val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState() @@ -52,21 +49,12 @@ class RecommendsScreen(val mangaId: Long, val sourceId: Long) : Screen() { // KMK <-- val onClickItem = { manga: Manga -> - when (manga.source) { - RECOMMENDS_SOURCE -> navigator.push( - SourcesScreen(SourcesScreen.SmartSearchConfig(manga.ogTitle)), - ) - else -> { - // KMK --> - scope.launchIO { - val localManga = screenModel.networkToLocalManga(manga) - navigator.push( - // KMK <-- - MangaScreen(localManga.id, true), - ) - } - } - } + navigator.push( + when (manga.source) { + RECOMMENDS_SOURCE -> SourcesScreen(SourcesScreen.SmartSearchConfig(manga.ogTitle)) + else -> MangaScreen(manga.id, true) + }, + ) } val onLongClickItem = { manga: Manga -> @@ -74,13 +62,11 @@ class RecommendsScreen(val mangaId: Long, val sourceId: Long) : Screen() { RECOMMENDS_SOURCE -> WebViewActivity.newIntent(context, manga.url, title = manga.title).let(context::startActivity) else -> { // KMK --> - scope.launchIO { - val localManga = screenModel.networkToLocalManga(manga) - bulkFavoriteScreenModel.addRemoveManga( - localManga, - haptic, - ) - } + // Add to favorite + bulkFavoriteScreenModel.addRemoveManga( + manga, + haptic, + ) // KMK <-- } } diff --git a/app/src/main/java/exh/recs/RecommendsScreenModel.kt b/app/src/main/java/exh/recs/RecommendsScreenModel.kt index a153b1740..c63ed52bf 100644 --- a/app/src/main/java/exh/recs/RecommendsScreenModel.kt +++ b/app/src/main/java/exh/recs/RecommendsScreenModel.kt @@ -32,7 +32,7 @@ open class RecommendsScreenModel( val mangaId: Long, val sourceId: Long, private val getManga: GetManga = Injekt.get(), - val networkToLocalManga: NetworkToLocalManga = Injekt.get(), + protected val networkToLocalManga: NetworkToLocalManga = Injekt.get(), ) : StateScreenModel(State()) { // KMK --> @@ -78,14 +78,14 @@ open class RecommendsScreenModel( } val recSourceId = recSource.associatedSourceId - // KMK --> - val titles = page.mangas.map { + val titles = if (recSourceId != null) { // If the recommendation is associated with a source, resolve it + page.mangas.map { it.toDomainManga(recSourceId) } + .let { networkToLocalManga(it) } + } else { // Otherwise, skip this step. The user will be prompted to choose a source via SmartSearch - it.toDomainManga(recSourceId ?: RECOMMENDS_SOURCE) + page.mangas.map { it.toDomainManga(RECOMMENDS_SOURCE) } } - /* KMK --> .let { networkToLocalManga(it) } KMK <-- */ - // KMK <-- .distinctBy { it.url } if (isActive) { diff --git a/data/src/main/java/tachiyomi/data/manga/MangaRepositoryImpl.kt b/data/src/main/java/tachiyomi/data/manga/MangaRepositoryImpl.kt index c3cf97c9a..16425ec2d 100644 --- a/data/src/main/java/tachiyomi/data/manga/MangaRepositoryImpl.kt +++ b/data/src/main/java/tachiyomi/data/manga/MangaRepositoryImpl.kt @@ -118,7 +118,7 @@ class MangaRepositoryImpl( } } - override suspend fun insertNetworkManga(manga: List): List { + override suspend fun insertNetworkManga(manga: List, updateInfo: Boolean): List { return handler.await(inTransaction = true) { manga.map { mangasQueries.insertNetworkManga( @@ -150,10 +150,10 @@ class MangaRepositoryImpl( // SY <-- updateDetails = it.initialized, // KMK --> - // mapper = MangaMapper::mapManga, - ) - mangasQueries.getMangaByUrlAndSource(it.url, it.source, MangaMapper::mapManga) + updateInfo = updateInfo, // KMK <-- + mapper = MangaMapper::mapManga, + ) .executeAsOne() } } diff --git a/data/src/main/java/tachiyomi/data/source/EHentaiPagingSource.kt b/data/src/main/java/tachiyomi/data/source/EHentaiPagingSource.kt index 13d145f28..5ce0000e6 100644 --- a/data/src/main/java/tachiyomi/data/source/EHentaiPagingSource.kt +++ b/data/src/main/java/tachiyomi/data/source/EHentaiPagingSource.kt @@ -23,8 +23,8 @@ abstract class EHentaiPagingSource( val manga = mangasPage.mangas .mapIndexed { index, sManga -> sManga.toDomainManga(source.id) to metadata.getOrNull(index) } .filter { seenManga.add(it.first.url) } - // KMK --> - // .let { pairs -> pairs.zip(networkToLocalManga(pairs.map { it.first })).map { it.second to it.first.second } } + // KMK --> + .let { pairs -> networkToLocalManga(pairs.map { it.first }).zip(pairs.map { it.second }) } // KMK <-- return LoadResult.Page( diff --git a/data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt b/data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt index 790c7a547..a45e4900f 100644 --- a/data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt +++ b/data/src/main/java/tachiyomi/data/source/SourcePagingSource.kt @@ -94,8 +94,8 @@ abstract class BaseSourcePagingSource( // SY --> .mapIndexed { index, sManga -> sManga.toDomainManga(source!!.id) to metadata.getOrNull(index) } .filter { seenManga.add(it.first.url) } - // KMK --> - // .let { pairs -> pairs.zip(networkToLocalManga(pairs.map { it.first })).map { it.second to it.first.second } } + // KMK --> + .let { pairs -> networkToLocalManga(pairs.map { it.first }).zip(pairs.map { it.second }) } // KMK <-- // SY <-- diff --git a/data/src/main/sqldelight/tachiyomi/data/mangas.sq b/data/src/main/sqldelight/tachiyomi/data/mangas.sq index a3ecc40c9..b0b3b4bc1 100644 --- a/data/src/main/sqldelight/tachiyomi/data/mangas.sq +++ b/data/src/main/sqldelight/tachiyomi/data/mangas.sq @@ -242,17 +242,16 @@ insertNetworkManga { status = CASE WHEN :updateDetails THEN :status ELSE status END, update_strategy = CASE WHEN :updateDetails THEN :updateStrategy ELSE update_strategy END, initialized = :updateDetails - WHERE source = :source + WHERE source = :source AND :updateInfo AND url = :url AND favorite = 0; --- KMK : Disabled the following SELECT as it will cause `getMangaByUrlAndSource` flow not triggered --- -- Finally return the manga --- SELECT * --- FROM mangas --- WHERE source = :source --- AND url = :url --- LIMIT 1; + -- Finally return the manga + SELECT * + FROM mangas + WHERE source = :source + AND url = :url + LIMIT 1; } getEhMangaWithMetadata: diff --git a/domain/src/main/java/tachiyomi/domain/manga/interactor/NetworkToLocalManga.kt b/domain/src/main/java/tachiyomi/domain/manga/interactor/NetworkToLocalManga.kt index f909aaca9..f883de235 100644 --- a/domain/src/main/java/tachiyomi/domain/manga/interactor/NetworkToLocalManga.kt +++ b/domain/src/main/java/tachiyomi/domain/manga/interactor/NetworkToLocalManga.kt @@ -7,11 +7,11 @@ class NetworkToLocalManga( private val mangaRepository: MangaRepository, ) { - suspend operator fun invoke(manga: Manga): Manga { - return if (manga.id <= 0) invoke(listOf(manga)).single() else manga + suspend operator fun invoke(manga: Manga, updateInfo: Boolean = true): Manga { + return invoke(listOf(manga), updateInfo).single() } - suspend operator fun invoke(manga: List): List { - return mangaRepository.insertNetworkManga(manga) + suspend operator fun invoke(manga: List, updateInfo: Boolean = true): List { + return mangaRepository.insertNetworkManga(manga, updateInfo) } } diff --git a/domain/src/main/java/tachiyomi/domain/manga/repository/MangaRepository.kt b/domain/src/main/java/tachiyomi/domain/manga/repository/MangaRepository.kt index 770ca9b90..f0982360d 100644 --- a/domain/src/main/java/tachiyomi/domain/manga/repository/MangaRepository.kt +++ b/domain/src/main/java/tachiyomi/domain/manga/repository/MangaRepository.kt @@ -38,7 +38,7 @@ interface MangaRepository { suspend fun updateAll(mangaUpdates: List): Boolean - suspend fun insertNetworkManga(manga: List): List + suspend fun insertNetworkManga(manga: List, updateInfo: Boolean = true): List // SY --> suspend fun getMangaBySourceId(sourceId: Long): List