diff --git a/app/src/main/java/eu/kanade/presentation/browse/BrowseSourceScreen.kt b/app/src/main/java/eu/kanade/presentation/browse/BrowseSourceScreen.kt index 203fd2ee6..a4fb6daaf 100644 --- a/app/src/main/java/eu/kanade/presentation/browse/BrowseSourceScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/browse/BrowseSourceScreen.kt @@ -12,7 +12,6 @@ import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarResult import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.collectAsState import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.paging.LoadState @@ -24,7 +23,6 @@ import eu.kanade.presentation.browse.components.BrowseSourceList import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.util.formattedMessage import eu.kanade.tachiyomi.source.Source -import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel import exh.metadata.metadata.RaisedSearchMetadata import exh.source.isEhBasedSource import kotlinx.collections.immutable.persistentListOf @@ -62,7 +60,6 @@ fun BrowseSourceContent( onMangaLongClick: (Manga) -> Unit, // KMK --> selection: List, - browseSourceState: BrowseSourceScreenModel.State, // KMK <-- ) { val context = LocalContext.current @@ -138,22 +135,9 @@ fun BrowseSourceContent( LoadingScreen( modifier = Modifier.padding(contentPadding), ) - // KMK --> - browseSourceState.mangaDisplayingList.clear() - // KMK <-- return } - // KMK --> - for (idx in browseSourceState.mangaDisplayingList.size.. - if (!browseSourceState.mangaDisplayingList.map { it.id }.contains(manga.id)) { - browseSourceState.mangaDisplayingList.add(manga) - } - } - } - // KMK <-- - // SY --> if (source?.isEhBasedSource() == true && ehentaiBrowseDisplayMode) { BrowseSourceEHentaiList( 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 4b910b642..52cac4641 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].id}" }, + key = { "related-comfort-${relatedManga.mangaList[it].url.hashCode()}" }, 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 054f556b9..c4158b471 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].id}" }, + key = { "related-compact-${relatedManga.mangaList[it].url.hashCode()}" }, 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 a7b639e3e..d0b05e667 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].id}" }, + key = { "related-list-${relatedManga.mangaList[it].url.hashCode()}" }, count = relatedManga.mangaList.size, ) { index -> val manga by getManga(relatedManga.mangaList[index]) diff --git a/app/src/main/java/eu/kanade/presentation/components/BulkSelectionToolbar.kt b/app/src/main/java/eu/kanade/presentation/components/BulkSelectionToolbar.kt index c6689ebda..26b54fcf0 100644 --- a/app/src/main/java/eu/kanade/presentation/components/BulkSelectionToolbar.kt +++ b/app/src/main/java/eu/kanade/presentation/components/BulkSelectionToolbar.kt @@ -4,8 +4,6 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Favorite -import androidx.compose.material.icons.filled.SelectAll -import androidx.compose.material.icons.outlined.FlipToBack import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -33,6 +31,7 @@ fun BulkSelectionToolbar( actions = persistentListOf() .builder() .apply { + /* if (onSelectAll != null) { add( AppBar.Action( @@ -51,6 +50,7 @@ fun BulkSelectionToolbar( ), ) } + */ if (isRunning) { add( AppBar.ActionCompose( 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 428a8ef2c..7baad53ae 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.id}" }) { + items(mangas, key = { "related-row-${it.url.hashCode()}" }) { val manga by getManga(it) MangaItem( title = manga.title, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/BrowseTab.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/BrowseTab.kt index 4435e42a3..8ea7b5ebe 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/BrowseTab.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/BrowseTab.kt @@ -39,6 +39,7 @@ import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get data object BrowseTab : Tab { + private fun readResolve(): Any = BrowseTab override val options: TabOptions @Composable 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 4e01390e0..8106b48fa 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 @@ -10,6 +10,7 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.hapticfeedback.HapticFeedback import androidx.compose.ui.hapticfeedback.HapticFeedbackType import androidx.compose.ui.util.fastAny +import androidx.compose.ui.util.fastDistinctBy import androidx.compose.ui.util.fastForEach import androidx.compose.ui.util.fastForEachIndexed import cafe.adriel.voyager.core.model.StateScreenModel @@ -113,7 +114,9 @@ class BulkFavoriteScreenModel( mutableState.update { state -> val newSelection = mangas.filterNot { manga -> state.selection.contains(manga) - }.toPersistentList() + } + .fastDistinctBy { it.id } + .toPersistentList() state.copy( selection = newSelection, selectionMode = newSelection.isNotEmpty(), 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 a07963173..d77d06f38 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 @@ -23,6 +23,7 @@ import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.flow.update @@ -58,7 +59,7 @@ open class FeedScreenModel( val sourceManager: SourceManager = Injekt.get(), val sourcePreferences: SourcePreferences = Injekt.get(), private val getManga: GetManga = Injekt.get(), - private val networkToLocalManga: NetworkToLocalManga = Injekt.get(), + val networkToLocalManga: NetworkToLocalManga = Injekt.get(), getFeedSavedSearchGlobal: GetFeedSavedSearchGlobal = Injekt.get(), private val getSavedSearchGlobalFeed: GetSavedSearchGlobalFeed = Injekt.get(), private val countFeedSavedSearchGlobal: CountFeedSavedSearchGlobal = Injekt.get(), @@ -318,9 +319,9 @@ open class FeedScreenModel( val result = withIOContext { itemUI.copy( results = page.map { - networkToLocalManga.await(it.toDomainManga(itemUI.source!!.id)) - } // KMK --> + it.toDomainManga(itemUI.source!!.id) + } .filter { !hideInLibraryFeedItems.get() || !it.favorite }, // KMK <-- ) @@ -355,8 +356,10 @@ open class FeedScreenModel( return produceState(initialValue = initialManga) { getManga.subscribe(initialManga.url, initialManga.source) .collectLatest { manga -> - 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 f4697d243..864427918 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,6 +13,7 @@ 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.stack.StackEvent @@ -40,6 +41,7 @@ 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 @@ -57,6 +59,7 @@ fun feedTab( val state by screenModel.state.collectAsState() // KMK --> + val scope = rememberCoroutineScope() val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState() val showingFeedOrderScreen = rememberSaveable { mutableStateOf(false) } @@ -175,21 +178,27 @@ fun feedTab( // KMK --> onLongClickFeed = screenModel::openActionsDialog, // KMK <-- - onClickManga = { manga -> + onClickManga = { // KMK --> - if (bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.toggleSelection(manga) - } else { - // KMK <-- - navigator.push(MangaScreen(manga.id, true)) + scope.launchIO { + val manga = screenModel.networkToLocalManga.getLocal(it) + if (bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.toggleSelection(manga) + } else { + // KMK <-- + navigator.push(MangaScreen(manga.id, true)) + } } }, // KMK --> - onLongClickManga = { manga -> - if (!bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.addRemoveManga(manga, haptic) - } else { - navigator.push(MangaScreen(manga.id, true)) + onLongClickManga = { + scope.launchIO { + val manga = screenModel.networkToLocalManga.getLocal(it) + 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 61535894d..edf0743b0 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,6 +4,7 @@ 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,6 +15,7 @@ import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel import eu.kanade.tachiyomi.ui.browse.ChangeMangasCategoryDialog import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigrationListScreen import eu.kanade.tachiyomi.ui.manga.MangaScreen +import tachiyomi.core.common.util.lang.launchIO class MigrateSearchScreen(private val mangaId: Long, private val validSources: List) : Screen() { @@ -28,6 +30,7 @@ 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() @@ -52,21 +55,31 @@ class MigrateSearchScreen(private val mangaId: Long, private val validSources: L }, onClickItem = { // KMK --> - if (bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.toggleSelection(it) - } else - // KMK <-- - { - // SY --> - navigator.items - .filterIsInstance() - .last() - .newSelectedItem = mangaId to it.id - navigator.popUntil { it is MigrationListScreen } - // SY <-- - } + scope.launchIO { + val manga = screenModel.networkToLocalManga.getLocal(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.getLocal(it) + // KMK <-- + navigator.push(MangaScreen(manga.id, true)) + } }, - 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 f921fe181..1054a1c13 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,6 +7,7 @@ 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,6 +35,7 @@ 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 @@ -67,6 +69,7 @@ data class SourceSearchScreen( // KMK --> val context = LocalContext.current + val scope = rememberCoroutineScope() val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() } val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState() @@ -74,6 +77,8 @@ data class SourceSearchScreen( BackHandler(enabled = bulkFavoriteState.selectionMode) { bulkFavoriteScreenModel.toggleSelectionMode() } + + val mangaList = screenModel.mangaPagerFlowFlow.collectAsLazyPagingItems() // KMK <-- Scaffold( @@ -86,12 +91,17 @@ data class SourceSearchScreen( onClickClearSelection = bulkFavoriteScreenModel::toggleSelectionMode, onChangeCategoryClick = bulkFavoriteScreenModel::addFavorite, onSelectAll = { - state.mangaDisplayingList.forEach { manga -> - bulkFavoriteScreenModel.select(manga) - } + mangaList.itemSnapshotList.items + .map { it.value.first } + .forEach { manga -> + bulkFavoriteScreenModel.select(manga) + } }, onReverseSelection = { - bulkFavoriteScreenModel.reverseSelection(state.mangaDisplayingList.toList()) + bulkFavoriteScreenModel.reverseSelection( + mangaList.itemSnapshotList.items + .map { it.value.first }, + ) }, ) } else { @@ -138,7 +148,7 @@ data class SourceSearchScreen( } BrowseSourceContent( source = screenModel.source, - mangaList = screenModel.mangaPagerFlowFlow.collectAsLazyPagingItems(), + mangaList = mangaList, columns = screenModel.getColumnsPreference(LocalConfiguration.current.orientation), // SY --> ehentaiBrowseDisplayMode = screenModel.ehentaiBrowseDisplayMode, @@ -158,19 +168,28 @@ data class SourceSearchScreen( }, onHelpClick = { uriHandler.openUri(Constants.URL_HELP) }, onLocalSourceHelpClick = { uriHandler.openUri(LocalSource.HELP_URL) }, - onMangaClick = { manga -> + onMangaClick = { // KMK --> - if (bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.toggleSelection(manga) - } else { - // KMK <-- - openMigrateDialog(manga) + scope.launchIO { + val manga = screenModel.networkToLocalManga.getLocal(it) + if (bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.toggleSelection(manga) + } else { + // KMK <-- + openMigrateDialog(manga) + } + } + }, + onMangaLongClick = { + // KMK --> + scope.launchIO { + val manga = screenModel.networkToLocalManga.getLocal(it) + // KMK <-- + navigator.push(MangaScreen(manga.id, true)) } }, - onMangaLongClick = { navigator.push(MangaScreen(it.id, true)) }, // KMK --> selection = bulkFavoriteState.selection, - browseSourceState = state, // 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 b4fda24de..dd83dfa63 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 @@ -171,6 +171,9 @@ data class BrowseSourceScreen( assistUrl = (screenModel.source as? HttpSource)?.baseUrl } + // KMK --> + val mangaList = screenModel.mangaPagerFlowFlow.collectAsLazyPagingItems() + // KMK <-- Scaffold( topBar = { Column(modifier = Modifier.background(MaterialTheme.colorScheme.surface)) { @@ -182,12 +185,17 @@ data class BrowseSourceScreen( onClickClearSelection = bulkFavoriteScreenModel::toggleSelectionMode, onChangeCategoryClick = bulkFavoriteScreenModel::addFavorite, onSelectAll = { - state.mangaDisplayingList.forEach { manga -> - bulkFavoriteScreenModel.select(manga) - } + mangaList.itemSnapshotList.items + .map { it.value.first } + .forEach { manga -> + bulkFavoriteScreenModel.select(manga) + } }, onReverseSelection = { - bulkFavoriteScreenModel.reverseSelection(state.mangaDisplayingList.toList()) + bulkFavoriteScreenModel.reverseSelection( + mangaList.itemSnapshotList.items + .map { it.value.first }, + ) }, ) } else { @@ -314,7 +322,7 @@ data class BrowseSourceScreen( ) { paddingValues -> BrowseSourceContent( source = screenModel.source, - mangaList = screenModel.mangaPagerFlowFlow.collectAsLazyPagingItems(), + mangaList = mangaList, columns = screenModel.getColumnsPreference(LocalConfiguration.current.orientation), // SY --> ehentaiBrowseDisplayMode = screenModel.ehentaiBrowseDisplayMode, @@ -327,30 +335,34 @@ data class BrowseSourceScreen( onLocalSourceHelpClick = onHelpClick, onMangaClick = { // KMK --> - if (bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.toggleSelection(it) - } else { - // KMK <-- - navigator.push( - MangaScreen( - it.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 - smartSearchConfig != null, - // KMK <-- - smartSearchConfig, - ), - ) + scope.launchIO { + val manga = screenModel.networkToLocalManga.getLocal(it) + if (bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.toggleSelection(manga) + } else { + // KMK <-- + navigator.push( + MangaScreen( + 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 + smartSearchConfig != null, + // KMK <-- + smartSearchConfig, + ), + ) + } } }, - onMangaLongClick = { manga -> + onMangaLongClick = { // KMK --> - if (bulkFavoriteState.selectionMode) { - navigator.push(MangaScreen(manga.id, true)) - } else { - // KMK <-- - scope.launchIO { + scope.launchIO { + val manga = screenModel.networkToLocalManga.getLocal(it) + if (bulkFavoriteState.selectionMode) { + navigator.push(MangaScreen(manga.id, true)) + } else { + // KMK <-- val duplicateManga = screenModel.getDuplicateLibraryManga(manga) when { manga.favorite -> screenModel.setDialog( @@ -370,7 +382,6 @@ data class BrowseSourceScreen( }, // KMK --> selection = bulkFavoriteState.selection, - browseSourceState = state, // KMK <-- ) } 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 678b7e7be..94bc5c6ab 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 @@ -40,7 +40,6 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.emptyFlow -import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf @@ -103,7 +102,7 @@ open class BrowseSourceScreenModel( private val setMangaCategories: SetMangaCategories = Injekt.get(), private val setMangaDefaultChapterFlags: SetMangaDefaultChapterFlags = Injekt.get(), private val getManga: GetManga = Injekt.get(), - private val networkToLocalManga: NetworkToLocalManga = Injekt.get(), + val networkToLocalManga: NetworkToLocalManga = Injekt.get(), private val updateManga: UpdateManga = Injekt.get(), private val addTracks: AddTracks = Injekt.get(), @@ -212,9 +211,13 @@ open class BrowseSourceScreenModel( // SY <-- }.flow.map { pagingData -> pagingData.map { (it, metadata) -> - networkToLocalManga.await(it.toDomainManga(sourceId)) - .let { localManga -> getManga.subscribe(localManga.url, localManga.source) } - .filterNotNull() + // KMK --> + it.toDomainManga(sourceId) + .let { manga -> + getManga.subscribe(manga.url, manga.source) + .map { it ?: manga } + } + // KMK <-- // SY --> .combineMetadata(metadata) // SY <-- @@ -520,9 +523,6 @@ open class BrowseSourceScreenModel( val savedSearches: ImmutableList = persistentListOf(), val filterable: Boolean = true, // SY <-- - // KMK --> - val mangaDisplayingList: MutableSet = mutableSetOf(), - // KMK <-- ) { val isUserQuery get() = listing is Listing.Search && !listing.query.isNullOrEmpty() } 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 ab9522951..8bb9f5523 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,6 +7,7 @@ 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 @@ -43,6 +44,7 @@ import eu.kanade.tachiyomi.util.system.toast import exh.md.follows.MangaDexFollowsScreen import exh.source.isEhBasedSource import exh.util.nullIfBlank +import tachiyomi.core.common.util.lang.launchIO import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.source.interactor.GetRemoteManga import tachiyomi.domain.source.model.SavedSearch @@ -67,6 +69,7 @@ class SourceFeedScreen(val sourceId: Long) : Screen() { val context = LocalContext.current // KMK --> + val scope = rememberCoroutineScope() screenModel.source.let { if (it is StubSource) { MissingSourceScreen( @@ -126,11 +129,14 @@ class SourceFeedScreen(val sourceId: Long) : Screen() { // KMK <-- onClickManga = { // KMK --> - if (bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.toggleSelection(it) - } else { - // KMK <-- - onMangaClick(navigator, it) + scope.launchIO { + val manga = screenModel.networkToLocalManga.getLocal(it) + if (bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.toggleSelection(manga) + } else { + // KMK <-- + onMangaClick(navigator, manga) + } } }, onClickSearch = { onSearchClick(navigator, screenModel.source, it) }, @@ -173,11 +179,14 @@ class SourceFeedScreen(val sourceId: Long) : Screen() { .filterIsInstance() .isNotEmpty() }, - onLongClickManga = { manga -> - if (!bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.addRemoveManga(manga, haptic) - } else { - navigator.push(MangaScreen(manga.id, true)) + onLongClickManga = { + scope.launchIO { + val manga = screenModel.networkToLocalManga.getLocal(it) + 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 cfb31b997..23d3cda84 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 @@ -65,7 +65,7 @@ open class SourceFeedScreenModel( uiPreferences: UiPreferences = Injekt.get(), private val sourceManager: SourceManager = Injekt.get(), private val getManga: GetManga = Injekt.get(), - private val networkToLocalManga: NetworkToLocalManga = Injekt.get(), + val networkToLocalManga: NetworkToLocalManga = Injekt.get(), private val getFeedSavedSearchBySourceId: GetFeedSavedSearchBySourceId = Injekt.get(), private val getSavedSearchBySourceIdFeed: GetSavedSearchBySourceIdFeed = Injekt.get(), private val countFeedSavedSearchBySourceId: CountFeedSavedSearchBySourceId = Injekt.get(), @@ -236,7 +236,9 @@ open class SourceFeedScreenModel( val titles = withIOContext { page.map { - networkToLocalManga.await(it.toDomainManga(source.id)) + // KMK --> + it.toDomainManga(source.id) + // KMK <-- } } @@ -271,8 +273,10 @@ open class SourceFeedScreenModel( return produceState(initialValue = initialManga) { getManga.subscribe(initialManga.url, initialManga.source) .collectLatest { manga -> - 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 dfa772c51..14062df94 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,6 +7,7 @@ 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 @@ -23,6 +24,7 @@ import eu.kanade.tachiyomi.ui.browse.ChangeMangasCategoryDialog import eu.kanade.tachiyomi.ui.browse.RemoveMangaDialog 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( @@ -51,6 +53,7 @@ class GlobalSearchScreen( } // KMK --> + val scope = rememberCoroutineScope() val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() } val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState() @@ -93,20 +96,26 @@ class GlobalSearchScreen( }, onClickItem = { // KMK --> - if (bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.toggleSelection(it) - } else { - // KMK <-- - navigator.push(MangaScreen(it.id, true)) + scope.launchIO { + val manga = screenModel.networkToLocalManga.getLocal(it) + if (bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.toggleSelection(manga) + } else { + // KMK <-- + navigator.push(MangaScreen(manga.id, true)) + } } }, - onLongClickItem = { manga -> + onLongClickItem = { // KMK --> - if (!bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.addRemoveManga(manga, haptic) - } else { - // KMK <-- - navigator.push(MangaScreen(manga.id, true)) + scope.launchIO { + val manga = screenModel.networkToLocalManga.getLocal(it) + 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 f2246b47c..d94edf5c8 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 @@ -20,7 +20,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.map import kotlinx.coroutines.flow.update import kotlinx.coroutines.isActive import kotlinx.coroutines.launch @@ -39,7 +39,7 @@ abstract class SearchScreenModel( sourcePreferences: SourcePreferences = Injekt.get(), private val sourceManager: SourceManager = Injekt.get(), private val extensionManager: ExtensionManager = Injekt.get(), - private val networkToLocalManga: NetworkToLocalManga = Injekt.get(), + val networkToLocalManga: NetworkToLocalManga = Injekt.get(), private val getManga: GetManga = Injekt.get(), private val preferences: SourcePreferences = Injekt.get(), ) : StateScreenModel(initialState) { @@ -83,9 +83,11 @@ abstract class SearchScreenModel( fun getManga(initialManga: Manga): androidx.compose.runtime.State { return produceState(initialValue = initialManga) { getManga.subscribe(initialManga.url, initialManga.source) - .filterNotNull() .collectLatest { manga -> value = manga + // KMK --> + ?: initialManga + // KMK <-- } } } @@ -187,7 +189,9 @@ abstract class SearchScreenModel( } val titles = page.mangas.map { - networkToLocalManga.await(it.toDomainManga(source.id)) + // KMK --> + it.toDomainManga(source.id) + // KMK <-- } if (isActive) { 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 2747f65dc..048143286 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 @@ -32,7 +32,6 @@ import androidx.core.net.toUri import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.lifecycle.compose.collectAsStateWithLifecycle 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 @@ -367,12 +366,22 @@ class MangaScreen( getMangaState = { screenModel.getManga(initialManga = it) }, onRelatedMangasScreenClick = { if (successState.isRelatedMangasFetched == null) { - screenModel.screenModelScope.launchIO { screenModel.fetchRelatedMangasFromSource(onDemand = true) } + scope.launchIO { screenModel.fetchRelatedMangasFromSource(onDemand = true) } } showRelatedMangasScreen() }, - onRelatedMangaClick = { navigator.push(MangaScreen(it.id, true)) }, - onRelatedMangaLongClick = { bulkFavoriteScreenModel.addRemoveManga(it, haptic) }, + onRelatedMangaClick = { + scope.launchIO { + val manga = screenModel.networkToLocalManga.getLocal(it) + navigator.push(MangaScreen(manga.id, true)) + } + }, + onRelatedMangaLongClick = { + scope.launchIO { + val manga = screenModel.networkToLocalManga.getLocal(it) + bulkFavoriteScreenModel.addRemoveManga(manga, 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 dc290ff62..bda3763ab 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 @@ -95,7 +95,6 @@ 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 @@ -191,7 +190,7 @@ class MangaScreenModel( private val smartSearchMerge: SmartSearchMerge = Injekt.get(), // KMK <-- private val updateMergedSettings: UpdateMergedSettings = Injekt.get(), - private val networkToLocalManga: NetworkToLocalManga = Injekt.get(), + val networkToLocalManga: NetworkToLocalManga = Injekt.get(), private val deleteMergeById: DeleteMergeById = Injekt.get(), private val getFlatMetadata: GetFlatMetadataById = Injekt.get(), private val getPagePreviews: GetPagePreviews = Injekt.get(), @@ -702,10 +701,12 @@ class MangaScreenModel( fun getManga(initialManga: Manga): RuntimeState { return produceState(initialValue = initialManga) { getManga.subscribe(initialManga.url, initialManga.source) - .filterNotNull() .flowWithLifecycle(lifecycle) .collectLatest { manga -> value = manga + // KMK --> + ?: initialManga + // KMK <-- } } } @@ -1150,7 +1151,9 @@ class MangaScreenModel( /* Push found related mangas into collection */ val relatedManga = RelatedManga.Success.fromPair(pair) { mangaList -> mangaList.map { - networkToLocalManga.await(it.toDomainManga(state.source.id)) + // KMK --> + it.toDomainManga(state.source.id) + // KMK <-- } } @@ -1985,13 +1988,13 @@ sealed interface RelatedManga { } internal fun List.removeDuplicates(manga: Manga): List { - val mangaIds = HashSet().apply { add(manga.id) } + val mangaHashes = HashSet().apply { add(manga.url.hashCode()) } return map { relatedManga -> if (relatedManga is Success) { val stripedList = relatedManga.mangaList.mapNotNull { - if (!mangaIds.contains(it.id)) { - mangaIds.add(it.id) + if (!mangaHashes.contains(it.url.hashCode())) { + mangaHashes.add(it.url.hashCode()) it } else { null 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 8941994e9..089844cef 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,6 +22,7 @@ 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 @@ -88,18 +89,24 @@ fun RelatedMangasScreen( columns = getColumnsPreference(LocalConfiguration.current.orientation), displayMode = displayMode, contentPadding = paddingValues, - onMangaClick = { manga -> - if (bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.toggleSelection(manga) - } else { - navigator.push(MangaScreen(manga.id, true)) + onMangaClick = { + scope.launchIO { + val manga = screenModel.networkToLocalManga.getLocal(it) + if (bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.toggleSelection(manga) + } else { + navigator.push(MangaScreen(manga.id, true)) + } } }, - onMangaLongClick = { manga -> - if (!bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.addRemoveManga(manga, haptic) - } else { - navigator.push(MangaScreen(manga.id, true)) + onMangaLongClick = { + scope.launchIO { + val manga = screenModel.networkToLocalManga.getLocal(it) + 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 e17804a4c..00c1a52e5 100644 --- a/app/src/main/java/exh/md/follows/MangaDexFollowsScreen.kt +++ b/app/src/main/java/exh/md/follows/MangaDexFollowsScreen.kt @@ -65,6 +65,9 @@ class MangaDexFollowsScreen(private val sourceId: Long) : Screen() { val snackbarHostState = remember { SnackbarHostState() } + // KMK --> + val mangaList = screenModel.mangaPagerFlowFlow.collectAsLazyPagingItems() + // KMK <-- Scaffold( topBar = { scrollBehavior -> // KMK --> @@ -75,12 +78,17 @@ class MangaDexFollowsScreen(private val sourceId: Long) : Screen() { onClickClearSelection = bulkFavoriteScreenModel::toggleSelectionMode, onChangeCategoryClick = bulkFavoriteScreenModel::addFavorite, onSelectAll = { - state.mangaDisplayingList.forEach { manga -> - bulkFavoriteScreenModel.select(manga) - } + mangaList.itemSnapshotList.items + .map { it.value.first } + .forEach { manga -> + bulkFavoriteScreenModel.select(manga) + } }, onReverseSelection = { - bulkFavoriteScreenModel.reverseSelection(state.mangaDisplayingList.toList()) + bulkFavoriteScreenModel.reverseSelection( + mangaList.itemSnapshotList.items + .map { it.value.first }, + ) }, ) } else { @@ -104,7 +112,7 @@ class MangaDexFollowsScreen(private val sourceId: Long) : Screen() { ) { paddingValues -> BrowseSourceContent( source = screenModel.source, - mangaList = screenModel.mangaPagerFlowFlow.collectAsLazyPagingItems(), + mangaList = mangaList, columns = screenModel.getColumnsPreference(LocalConfiguration.current.orientation), // SY --> ehentaiBrowseDisplayMode = screenModel.ehentaiBrowseDisplayMode, @@ -117,20 +125,24 @@ class MangaDexFollowsScreen(private val sourceId: Long) : Screen() { onLocalSourceHelpClick = null, onMangaClick = { // KMK --> - if (bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.toggleSelection(it) - } else { - // KMK <-- - navigator.push(MangaScreen(it.id, true)) + scope.launchIO { + val manga = screenModel.networkToLocalManga.getLocal(it) + if (bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.toggleSelection(manga) + } else { + // KMK <-- + navigator.push(MangaScreen(manga.id, true)) + } } }, - onMangaLongClick = { manga -> + onMangaLongClick = { // KMK --> - if (bulkFavoriteState.selectionMode) { - navigator.push(MangaScreen(manga.id, true)) - } else { - // KMK <-- - scope.launchIO { + scope.launchIO { + val manga = screenModel.networkToLocalManga.getLocal(it) + if (bulkFavoriteState.selectionMode) { + navigator.push(MangaScreen(manga.id, true)) + } else { + // KMK <-- val duplicateManga = screenModel.getDuplicateLibraryManga(manga) when { manga.favorite -> screenModel.setDialog( @@ -150,7 +162,6 @@ class MangaDexFollowsScreen(private val sourceId: Long) : Screen() { }, // KMK --> selection = bulkFavoriteState.selection, - browseSourceState = state, // KMK <-- ) } diff --git a/app/src/main/java/exh/md/similar/MangaDexSimilarScreen.kt b/app/src/main/java/exh/md/similar/MangaDexSimilarScreen.kt index 531820922..08a8df112 100644 --- a/app/src/main/java/exh/md/similar/MangaDexSimilarScreen.kt +++ b/app/src/main/java/exh/md/similar/MangaDexSimilarScreen.kt @@ -7,6 +7,7 @@ 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.LocalHapticFeedback import cafe.adriel.voyager.core.model.rememberScreenModel @@ -25,6 +26,7 @@ import eu.kanade.tachiyomi.ui.browse.ChangeMangasCategoryDialog import eu.kanade.tachiyomi.ui.browse.RemoveMangaDialog import eu.kanade.tachiyomi.ui.manga.MangaScreen import mihon.presentation.core.util.collectAsLazyPagingItems +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 @@ -44,7 +46,7 @@ class MangaDexSimilarScreen(val mangaId: Long, val sourceId: Long) : Screen() { val navigator = LocalNavigator.currentOrThrow // KMK --> - val state by screenModel.state.collectAsState() + val scope = rememberCoroutineScope() val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() } val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState() @@ -61,6 +63,9 @@ class MangaDexSimilarScreen(val mangaId: Long, val sourceId: Long) : Screen() { val snackbarHostState = remember { SnackbarHostState() } + // KMK --> + val mangaList = screenModel.mangaPagerFlowFlow.collectAsLazyPagingItems() + // KMK <-- Scaffold( topBar = { scrollBehavior -> // KMK --> @@ -71,12 +76,17 @@ class MangaDexSimilarScreen(val mangaId: Long, val sourceId: Long) : Screen() { onClickClearSelection = bulkFavoriteScreenModel::toggleSelectionMode, onChangeCategoryClick = bulkFavoriteScreenModel::addFavorite, onSelectAll = { - state.mangaDisplayingList.forEach { manga -> - bulkFavoriteScreenModel.select(manga) - } + mangaList.itemSnapshotList.items + .map { it.value.first } + .forEach { manga -> + bulkFavoriteScreenModel.select(manga) + } }, onReverseSelection = { - bulkFavoriteScreenModel.reverseSelection(state.mangaDisplayingList.toList()) + bulkFavoriteScreenModel.reverseSelection( + mangaList.itemSnapshotList.items + .map { it.value.first }, + ) }, ) } else { @@ -98,7 +108,7 @@ class MangaDexSimilarScreen(val mangaId: Long, val sourceId: Long) : Screen() { ) { paddingValues -> BrowseSourceContent( source = screenModel.source, - mangaList = screenModel.mangaPagerFlowFlow.collectAsLazyPagingItems(), + mangaList = mangaList, columns = screenModel.getColumnsPreference(LocalConfiguration.current.orientation), // SY --> ehentaiBrowseDisplayMode = false, @@ -109,27 +119,32 @@ class MangaDexSimilarScreen(val mangaId: Long, val sourceId: Long) : Screen() { onWebViewClick = null, onHelpClick = null, onLocalSourceHelpClick = null, - onMangaClick = { manga -> + onMangaClick = { // KMK --> - if (bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.toggleSelection(manga) - } else { - // KMK <-- - onMangaClick(manga) + scope.launchIO { + val manga = screenModel.networkToLocalManga.getLocal(it) + if (bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.toggleSelection(manga) + } else { + // KMK <-- + onMangaClick(manga) + } } }, - onMangaLongClick = { manga -> + onMangaLongClick = { // KMK --> - if (!bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.addRemoveManga(manga, haptic) - } else { - // KMK <-- - onMangaClick(manga) + scope.launchIO { + val manga = screenModel.networkToLocalManga.getLocal(it) + if (!bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.addRemoveManga(manga, haptic) + } else { + // KMK <-- + onMangaClick(manga) + } } }, // KMK --> selection = bulkFavoriteState.selection, - browseSourceState = state, // KMK <-- ) } diff --git a/app/src/main/java/exh/recs/RecommendsScreen.kt b/app/src/main/java/exh/recs/RecommendsScreen.kt index ea9e8e9e7..f634f3dfd 100644 --- a/app/src/main/java/exh/recs/RecommendsScreen.kt +++ b/app/src/main/java/exh/recs/RecommendsScreen.kt @@ -7,6 +7,7 @@ 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.LocalHapticFeedback import cafe.adriel.voyager.core.model.rememberScreenModel @@ -26,6 +27,7 @@ import eu.kanade.tachiyomi.ui.browse.ChangeMangasCategoryDialog import eu.kanade.tachiyomi.ui.browse.RemoveMangaDialog import eu.kanade.tachiyomi.ui.browse.source.SourcesScreen 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 @@ -43,7 +45,7 @@ class RecommendsScreen(val mangaId: Long, val sourceId: Long) : Screen() { val navigator = LocalNavigator.currentOrThrow // KMK --> - val state by screenModel.state.collectAsState() + val scope = rememberCoroutineScope() val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() } val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState() @@ -60,6 +62,9 @@ class RecommendsScreen(val mangaId: Long, val sourceId: Long) : Screen() { val snackbarHostState = remember { SnackbarHostState() } + // KMK --> + val mangaList = screenModel.mangaPagerFlowFlow.collectAsLazyPagingItems() + // KMK <-- Scaffold( topBar = { scrollBehavior -> // KMK --> @@ -70,12 +75,17 @@ class RecommendsScreen(val mangaId: Long, val sourceId: Long) : Screen() { onClickClearSelection = bulkFavoriteScreenModel::toggleSelectionMode, onChangeCategoryClick = bulkFavoriteScreenModel::addFavorite, onSelectAll = { - state.mangaDisplayingList.forEach { manga -> - bulkFavoriteScreenModel.select(manga) - } + mangaList.itemSnapshotList.items + .map { it.value.first } + .forEach { manga -> + bulkFavoriteScreenModel.select(manga) + } }, onReverseSelection = { - bulkFavoriteScreenModel.reverseSelection(state.mangaDisplayingList.toList()) + bulkFavoriteScreenModel.reverseSelection( + mangaList.itemSnapshotList.items + .map { it.value.first }, + ) }, ) } else { @@ -97,7 +107,7 @@ class RecommendsScreen(val mangaId: Long, val sourceId: Long) : Screen() { ) { paddingValues -> BrowseSourceContent( source = screenModel.source, - mangaList = screenModel.mangaPagerFlowFlow.collectAsLazyPagingItems(), + mangaList = mangaList, columns = screenModel.getColumnsPreference(LocalConfiguration.current.orientation), // SY --> ehentaiBrowseDisplayMode = false, @@ -108,25 +118,30 @@ class RecommendsScreen(val mangaId: Long, val sourceId: Long) : Screen() { onWebViewClick = null, onHelpClick = null, onLocalSourceHelpClick = null, - onMangaClick = { manga -> + onMangaClick = { // KMK --> - if (bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.toggleSelection(manga) - } else { - // KMK <-- - onMangaClick(manga) + scope.launchIO { + val manga = screenModel.networkToLocalManga.getLocal(it) + if (bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.toggleSelection(manga) + } else { + // KMK <-- + onMangaClick(manga) + } } }, - onMangaLongClick = { manga -> + onMangaLongClick = { // KMK --> - if (!bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.addRemoveManga(manga, haptic) + scope.launchIO { + val manga = screenModel.networkToLocalManga.getLocal(it) + if (!bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.addRemoveManga(manga, haptic) + } } // KMK <-- }, // KMK --> selection = bulkFavoriteState.selection, - browseSourceState = state, // KMK <-- ) } 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 255951568..798da17e5 100644 --- a/domain/src/main/java/tachiyomi/domain/manga/interactor/NetworkToLocalManga.kt +++ b/domain/src/main/java/tachiyomi/domain/manga/interactor/NetworkToLocalManga.kt @@ -25,6 +25,14 @@ class NetworkToLocalManga( } } + // KMK --> + suspend fun getLocal(manga: Manga): Manga = if (manga.id <= 0) { + await(manga) + } else { + manga + } + // KMK <-- + private suspend fun getManga(url: String, sourceId: Long): Manga? { return mangaRepository.getMangaByUrlAndSourceId(url, sourceId) }