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/BulkSelectionToolbar.kt b/app/src/main/java/eu/kanade/presentation/components/BulkSelectionToolbar.kt index 26b54fcf0..c6689ebda 100644 --- a/app/src/main/java/eu/kanade/presentation/components/BulkSelectionToolbar.kt +++ b/app/src/main/java/eu/kanade/presentation/components/BulkSelectionToolbar.kt @@ -4,6 +4,8 @@ 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 @@ -31,7 +33,6 @@ fun BulkSelectionToolbar( actions = persistentListOf() .builder() .apply { - /* if (onSelectAll != null) { add( AppBar.Action( @@ -50,7 +51,6 @@ 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 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/feed/FeedScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/feed/FeedScreenModel.kt index 8267fffdb..15fd3e179 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 @@ -60,7 +60,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(), @@ -302,9 +302,9 @@ open class FeedScreenModel( val result = withIOContext { itemUI.copy( results = page.map { - // KMK --> - it.toDomainManga(itemUI.source!!.id) + networkToLocalManga.await(it.toDomainManga(itemUI.source!!.id)) } + // KMK --> .filter { !hideInLibraryFeedItems.get() || !it.favorite }, // KMK <-- ) @@ -342,10 +342,8 @@ 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 cddb04a18..814247870 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.stack.StackEvent @@ -40,7 +39,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 @@ -58,7 +56,6 @@ fun feedTab( val state by screenModel.state.collectAsState() // KMK --> - val scope = rememberCoroutineScope() val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState() val showingFeedOrderScreen = rememberSaveable { mutableStateOf(false) } @@ -171,27 +168,21 @@ fun feedTab( // KMK --> onLongClickFeed = screenModel::openActionsDialog, // KMK <-- - onClickManga = { + onClickManga = { manga -> // KMK --> - scope.launchIO { - val manga = screenModel.networkToLocalManga.getLocal(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.getLocal(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 49fa8af42..f075301ac 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 @@ -15,7 +14,6 @@ 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() { @@ -30,7 +28,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() @@ -53,33 +50,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.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) + 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 bc70c141c..b117c08e0 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 @@ -35,7 +34,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 @@ -69,7 +67,6 @@ data class SourceSearchScreen( // KMK --> val context = LocalContext.current - val scope = rememberCoroutineScope() val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() } val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState() @@ -168,26 +165,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.getLocal(it) - if (bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.toggleSelection(manga) - } else { - // KMK <-- - openMigrateDialog(manga) - } - } - }, - onMangaLongClick = { - // KMK --> - scope.launchIO { - val manga = screenModel.networkToLocalManga.getLocal(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 6c55426c2..4929db0c1 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 @@ -353,36 +353,32 @@ data class BrowseSourceScreen( onWebViewClick = onWebViewClick, onHelpClick = { uriHandler.openUri(Constants.URL_HELP) }, onLocalSourceHelpClick = onHelpClick, - onMangaClick = { + onMangaClick = { manga -> // KMK --> - scope.launchIO { - val manga = screenModel.networkToLocalManga.getLocal(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.getLocal(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 duplicateManga = screenModel.getDuplicateLibraryManga(manga) when { manga.favorite -> screenModel.setDialog( 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 0fc6965bd..14b022efc 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 @@ -39,6 +39,7 @@ 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 @@ -99,7 +100,7 @@ open class BrowseSourceScreenModel( private val setMangaCategories: SetMangaCategories = Injekt.get(), private val setMangaDefaultChapterFlags: SetMangaDefaultChapterFlags = Injekt.get(), private val getManga: GetManga = Injekt.get(), - val networkToLocalManga: NetworkToLocalManga = Injekt.get(), + private val networkToLocalManga: NetworkToLocalManga = Injekt.get(), private val updateManga: UpdateManga = Injekt.get(), private val addTracks: AddTracks = Injekt.get(), private val getIncognitoState: GetIncognitoState = Injekt.get(), @@ -207,13 +208,9 @@ open class BrowseSourceScreenModel( // SY <-- }.flow.map { pagingData -> pagingData.map { (it, metadata) -> - // KMK --> - it.toDomainManga(sourceId) - .let { manga -> - getManga.subscribe(manga.url, manga.source) - .map { it ?: manga } - } - // KMK <-- + networkToLocalManga.await(it.toDomainManga(sourceId)) + .let { localManga -> getManga.subscribe(localManga.url, localManga.source) } + .filterNotNull() // SY --> .combineMetadata(metadata) // SY <-- 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 958900bcb..3507febcb 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 @@ -44,7 +43,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 @@ -71,7 +69,6 @@ class SourceFeedScreen(val sourceId: Long) : Screen() { val context = LocalContext.current // KMK --> - val scope = rememberCoroutineScope() screenModel.source.let { if (it is StubSource) { MissingSourceScreen( @@ -130,16 +127,13 @@ class SourceFeedScreen(val sourceId: Long) : Screen() { // onClickDelete = screenModel::openDeleteFeed, onLongClickFeed = screenModel::openActionsDialog, // KMK <-- - onClickManga = { + onClickManga = { manga -> // KMK --> - scope.launchIO { - val manga = screenModel.networkToLocalManga.getLocal(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) }, @@ -173,14 +167,11 @@ class SourceFeedScreen(val sourceId: Long) : Screen() { .filterIsInstance() .isNotEmpty() }, - onLongClickManga = { - scope.launchIO { - val manga = screenModel.networkToLocalManga.getLocal(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 e747bcde0..37d8ba975 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 @@ -63,7 +63,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(), @@ -212,9 +212,7 @@ open class SourceFeedScreenModel( val titles = withIOContext { page.map { - // KMK --> - it.toDomainManga(source.id) - // KMK <-- + networkToLocalManga.await(it.toDomainManga(source.id)) } } @@ -249,10 +247,8 @@ 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 fb3dace70..0bcb6eb4f 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 @@ -24,7 +23,6 @@ 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( @@ -53,7 +51,6 @@ class GlobalSearchScreen( } // KMK --> - val scope = rememberCoroutineScope() val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() } val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState() @@ -73,12 +70,7 @@ class GlobalSearchScreen( is SearchItemResult.Success -> { val manga = result.result.singleOrNull() if (manga != null) { - // KMK --> - scope.launchIO { - val localManga = screenModel.networkToLocalManga.getLocal(manga) - // KMK <-- - navigator.replace(MangaScreen(localManga.id, true)) - } + navigator.replace(MangaScreen(manga.id, true)) } else { // Backoff to result screen showSingleLoadingScreen = false @@ -99,28 +91,22 @@ class GlobalSearchScreen( onClickSource = { navigator.push(BrowseSourceScreen(it.id, state.searchQuery)) }, - onClickItem = { + onClickItem = { manga -> // KMK --> - scope.launchIO { - val manga = screenModel.networkToLocalManga.getLocal(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.getLocal(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 d94edf5c8..f2246b47c 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.map +import kotlinx.coroutines.flow.filterNotNull 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(), - 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,11 +83,9 @@ 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 <-- } } } @@ -189,9 +187,7 @@ abstract class SearchScreenModel( } val titles = page.mangas.map { - // KMK --> - it.toDomainManga(source.id) - // KMK <-- + networkToLocalManga.await(it.toDomainManga(source.id)) } 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 d0fc37f99..4a642c666 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 @@ -397,18 +397,8 @@ class MangaScreen( } showRelatedMangasScreen() }, - 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) - } - }, + 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 c80bca0f5..17be57192 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,6 +95,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 @@ -193,7 +194,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(), @@ -703,12 +704,10 @@ 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 <-- } } } @@ -1153,9 +1152,7 @@ class MangaScreenModel( /* Push found related mangas into collection */ val relatedManga = RelatedManga.Success.fromPair(pair) { mangaList -> mangaList.map { - // KMK --> - it.toDomainManga(state.source.id) - // KMK <-- + networkToLocalManga.await(it.toDomainManga(state.source.id)) } } @@ -2013,13 +2010,13 @@ 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) { val stripedList = relatedManga.mangaList.mapNotNull { - if (!mangaHashes.contains(it.url.hashCode())) { - mangaHashes.add(it.url.hashCode()) + if (!mangaIds.contains(it.id)) { + mangaIds.add(it.id) 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 089844cef..8941994e9 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 @@ -89,24 +88,18 @@ fun RelatedMangasScreen( columns = getColumnsPreference(LocalConfiguration.current.orientation), displayMode = displayMode, contentPadding = paddingValues, - onMangaClick = { - scope.launchIO { - val manga = screenModel.networkToLocalManga.getLocal(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.getLocal(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 196687d48..9fb4ef413 100644 --- a/app/src/main/java/exh/md/follows/MangaDexFollowsScreen.kt +++ b/app/src/main/java/exh/md/follows/MangaDexFollowsScreen.kt @@ -123,26 +123,22 @@ class MangaDexFollowsScreen(private val sourceId: Long) : Screen() { onWebViewClick = null, onHelpClick = null, onLocalSourceHelpClick = null, - onMangaClick = { + onMangaClick = { manga -> // KMK --> - scope.launchIO { - val manga = screenModel.networkToLocalManga.getLocal(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.getLocal(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 duplicateManga = screenModel.getDuplicateLibraryManga(manga) when { manga.favorite -> screenModel.setDialog( diff --git a/app/src/main/java/exh/recs/BrowseRecommendsScreen.kt b/app/src/main/java/exh/recs/BrowseRecommendsScreen.kt index c5176b34d..3fd03bb6e 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 @@ -29,7 +28,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 @@ -56,7 +54,6 @@ class BrowseRecommendsScreen( } // KMK --> - val scope = rememberCoroutineScope() val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() } val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState() @@ -78,14 +75,14 @@ class BrowseRecommendsScreen( ) } + // KMK --> val onLongClickItem = { manga: Manga -> when (isExternalSource) { true -> WebViewActivity.newIntent(context, manga.url, title = manga.title).let(context::startActivity) - false -> onClickItem(manga) + false -> navigator.push(MangaScreen(manga.id, true)) } } - // KMK --> val mangaList = screenModel.mangaPagerFlowFlow.collectAsLazyPagingItems() // KMK <-- @@ -147,29 +144,23 @@ class BrowseRecommendsScreen( onWebViewClick = null, onHelpClick = null, onLocalSourceHelpClick = null, - onMangaClick = { + onMangaClick = { manga -> // KMK --> - scope.launchIO { - val manga = screenModel.networkToLocalManga.getLocal(it) - if (bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.toggleSelection(manga) - } else { - // KMK <-- - onClickItem(manga) - } + if (bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.toggleSelection(manga) + } else { + // KMK <-- + onClickItem(manga) } }, - onMangaLongClick = { + onMangaLongClick = { manga -> // KMK --> - scope.launchIO { - val manga = screenModel.networkToLocalManga.getLocal(it) - if (!bulkFavoriteState.selectionMode) { - bulkFavoriteScreenModel.addRemoveManga(manga, haptic) - } else { - // KMK <-- - onLongClickItem(manga) - } + if (!bulkFavoriteState.selectionMode) { + bulkFavoriteScreenModel.addRemoveManga(manga, haptic) + } else { + 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 093e0d063..1d8bc141d 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 @@ -22,7 +21,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 @@ -44,7 +42,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() @@ -56,21 +53,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.getLocal(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 -> @@ -78,13 +66,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.getLocal(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 bfeea0290..6fafd8ddb 100644 --- a/app/src/main/java/exh/recs/RecommendsScreenModel.kt +++ b/app/src/main/java/exh/recs/RecommendsScreenModel.kt @@ -79,11 +79,13 @@ open class RecommendsScreenModel( val titles = page.mangas.map { val recSourceId = recSource.associatedSourceId - // KMK --> - // If the recommendation is associated with a source, resolve it - // Otherwise, skip this step. The user will be prompted to choose a source via SmartSearch - it.toDomainManga(recSourceId ?: RECOMMENDS_SOURCE) - // KMK <-- + if (recSourceId != null) { + // If the recommendation is associated with a source, resolve it + networkToLocalManga.await(it.toDomainManga(recSourceId)) + } else { + // Otherwise, skip this step. The user will be prompted to choose a source via SmartSearch + it.toDomainManga(RECOMMENDS_SOURCE) + } } if (isActive) { 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 798da17e5..255951568 100644 --- a/domain/src/main/java/tachiyomi/domain/manga/interactor/NetworkToLocalManga.kt +++ b/domain/src/main/java/tachiyomi/domain/manga/interactor/NetworkToLocalManga.kt @@ -25,14 +25,6 @@ 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) }