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 commit303a266720. * Revert "refactor(network-to-local): simplify networkToLocalManga (#910)" This reverts commitd33efced68. * Revert "chore(network-local-manga): Reintroduce (in-memory) fast browsing (#909)" This reverts commit3310784faf. * Add updateInfo parameter to insertNetworkManga method
This commit is contained in:
parent
ba63b74163
commit
3d2ad327bc
32 changed files with 186 additions and 429 deletions
|
|
@ -6,7 +6,6 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import eu.kanade.domain.source.model.installedExtension
|
import eu.kanade.domain.source.model.installedExtension
|
||||||
import eu.kanade.presentation.browse.components.GlobalSearchCardRow
|
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.ui.browse.source.globalsearch.SourceFilter
|
||||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||||
import kotlinx.collections.immutable.ImmutableMap
|
import kotlinx.collections.immutable.ImmutableMap
|
||||||
import tachiyomi.core.common.util.lang.launchIO
|
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
import tachiyomi.domain.source.model.Source as DomainSource
|
import tachiyomi.domain.source.model.Source as DomainSource
|
||||||
|
|
@ -45,7 +43,6 @@ fun GlobalSearchScreen(
|
||||||
// KMK <--
|
// KMK <--
|
||||||
) {
|
) {
|
||||||
// KMK -->
|
// KMK -->
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
|
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
|
||||||
// KMK <--
|
// KMK <--
|
||||||
|
|
||||||
|
|
@ -62,24 +59,13 @@ fun GlobalSearchScreen(
|
||||||
state.filteredItems.values
|
state.filteredItems.values
|
||||||
.filterIsInstance<SearchItemResult.Success>()
|
.filterIsInstance<SearchItemResult.Success>()
|
||||||
.flatMap { it.result }
|
.flatMap { it.result }
|
||||||
.let {
|
.forEach { bulkFavoriteScreenModel.select(it) }
|
||||||
scope.launchIO {
|
|
||||||
bulkFavoriteScreenModel.networkToLocalManga(it)
|
|
||||||
.forEach { bulkFavoriteScreenModel.select(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
onReverseSelection = {
|
onReverseSelection = {
|
||||||
state.filteredItems.values
|
state.filteredItems.values
|
||||||
.filterIsInstance<SearchItemResult.Success>()
|
.filterIsInstance<SearchItemResult.Success>()
|
||||||
.flatMap { it.result }
|
.flatMap { it.result }
|
||||||
.let {
|
.let { bulkFavoriteScreenModel.reverseSelection(it) }
|
||||||
scope.launchIO {
|
|
||||||
bulkFavoriteScreenModel.reverseSelection(
|
|
||||||
bulkFavoriteScreenModel.networkToLocalManga(it),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import eu.kanade.presentation.browse.components.GlobalSearchToolbar
|
import eu.kanade.presentation.browse.components.GlobalSearchToolbar
|
||||||
import eu.kanade.presentation.components.BulkSelectionToolbar
|
import eu.kanade.presentation.components.BulkSelectionToolbar
|
||||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
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.SearchItemResult
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchScreenModel
|
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SearchScreenModel
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SourceFilter
|
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SourceFilter
|
||||||
import tachiyomi.core.common.util.lang.launchIO
|
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
|
|
||||||
|
|
@ -35,7 +33,6 @@ fun MigrateSearchScreen(
|
||||||
// KMK <--
|
// KMK <--
|
||||||
) {
|
) {
|
||||||
// KMK -->
|
// KMK -->
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
|
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
|
||||||
// KMK <--
|
// KMK <--
|
||||||
|
|
||||||
|
|
@ -52,24 +49,13 @@ fun MigrateSearchScreen(
|
||||||
state.filteredItems.values
|
state.filteredItems.values
|
||||||
.filterIsInstance<SearchItemResult.Success>()
|
.filterIsInstance<SearchItemResult.Success>()
|
||||||
.flatMap { it.result }
|
.flatMap { it.result }
|
||||||
.let {
|
.forEach { bulkFavoriteScreenModel.select(it) }
|
||||||
scope.launchIO {
|
|
||||||
bulkFavoriteScreenModel.networkToLocalManga(it)
|
|
||||||
.forEach { bulkFavoriteScreenModel.select(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
onReverseSelection = {
|
onReverseSelection = {
|
||||||
state.filteredItems.values
|
state.filteredItems.values
|
||||||
.filterIsInstance<SearchItemResult.Success>()
|
.filterIsInstance<SearchItemResult.Success>()
|
||||||
.flatMap { it.result }
|
.flatMap { it.result }
|
||||||
.let {
|
.let { bulkFavoriteScreenModel.reverseSelection(it) }
|
||||||
scope.launchIO {
|
|
||||||
bulkFavoriteScreenModel.reverseSelection(
|
|
||||||
bulkFavoriteScreenModel.networkToLocalManga(it),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import dev.icerock.moko.resources.StringResource
|
import dev.icerock.moko.resources.StringResource
|
||||||
import eu.kanade.presentation.browse.components.BrowseSourceFloatingActionButton
|
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 eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import tachiyomi.core.common.util.lang.launchIO
|
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.domain.source.model.FeedSavedSearch
|
import tachiyomi.domain.source.model.FeedSavedSearch
|
||||||
import tachiyomi.domain.source.model.SavedSearch
|
import tachiyomi.domain.source.model.SavedSearch
|
||||||
|
|
@ -114,7 +112,6 @@ fun SourceFeedScreen(
|
||||||
// KMK <--
|
// KMK <--
|
||||||
) {
|
) {
|
||||||
// KMK -->
|
// KMK -->
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
|
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
|
||||||
// KMK <--
|
// KMK <--
|
||||||
|
|
||||||
|
|
@ -130,23 +127,12 @@ fun SourceFeedScreen(
|
||||||
onSelectAll = {
|
onSelectAll = {
|
||||||
items.mapNotNull { it.results }
|
items.mapNotNull { it.results }
|
||||||
.flatten()
|
.flatten()
|
||||||
.let {
|
.forEach { bulkFavoriteScreenModel.select(it) }
|
||||||
scope.launchIO {
|
|
||||||
bulkFavoriteScreenModel.networkToLocalManga(it)
|
|
||||||
.forEach { bulkFavoriteScreenModel.select(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
onReverseSelection = {
|
onReverseSelection = {
|
||||||
items.mapNotNull { it.results }
|
items.mapNotNull { it.results }
|
||||||
.flatten()
|
.flatten()
|
||||||
.let {
|
.let { bulkFavoriteScreenModel.reverseSelection(it) }
|
||||||
scope.launchIO {
|
|
||||||
bulkFavoriteScreenModel.reverseSelection(
|
|
||||||
bulkFavoriteScreenModel.networkToLocalManga(it),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ fun RelatedMangasComfortableGrid(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
items(
|
items(
|
||||||
key = { "related-comfort-${relatedManga.mangaList[it].url.hashCode()}" },
|
key = { "related-comfort-${relatedManga.mangaList[it].id}" },
|
||||||
count = relatedManga.mangaList.size,
|
count = relatedManga.mangaList.size,
|
||||||
) { index ->
|
) { index ->
|
||||||
val manga by getManga(relatedManga.mangaList[index])
|
val manga by getManga(relatedManga.mangaList[index])
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ fun RelatedMangasCompactGrid(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
items(
|
items(
|
||||||
key = { "related-compact-${relatedManga.mangaList[it].url.hashCode()}" },
|
key = { "related-compact-${relatedManga.mangaList[it].id}" },
|
||||||
count = relatedManga.mangaList.size,
|
count = relatedManga.mangaList.size,
|
||||||
) { index ->
|
) { index ->
|
||||||
val manga by getManga(relatedManga.mangaList[index])
|
val manga by getManga(relatedManga.mangaList[index])
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ fun RelatedMangasList(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
items(
|
items(
|
||||||
key = { "related-list-${relatedManga.mangaList[it].url.hashCode()}" },
|
key = { "related-list-${relatedManga.mangaList[it].id}" },
|
||||||
count = relatedManga.mangaList.size,
|
count = relatedManga.mangaList.size,
|
||||||
) { index ->
|
) { index ->
|
||||||
val manga by getManga(relatedManga.mangaList[index])
|
val manga by getManga(relatedManga.mangaList[index])
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ import eu.kanade.tachiyomi.ui.browse.feed.FeedScreenModel
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import tachiyomi.core.common.util.lang.launchIO
|
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
import tachiyomi.presentation.core.components.material.TabText
|
import tachiyomi.presentation.core.components.material.TabText
|
||||||
import tachiyomi.presentation.core.i18n.stringResource
|
import tachiyomi.presentation.core.i18n.stringResource
|
||||||
|
|
@ -69,25 +68,14 @@ fun TabbedScreen(
|
||||||
feedState.items?.let { result ->
|
feedState.items?.let { result ->
|
||||||
result.mapNotNull { it.results }
|
result.mapNotNull { it.results }
|
||||||
.flatten()
|
.flatten()
|
||||||
.let {
|
.forEach { bulkFavoriteScreenModel.select(it) }
|
||||||
scope.launchIO {
|
|
||||||
bulkFavoriteScreenModel.networkToLocalManga(it)
|
|
||||||
.forEach { bulkFavoriteScreenModel.select(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onReverseSelection = {
|
onReverseSelection = {
|
||||||
feedState.items?.let { result ->
|
feedState.items?.let { result ->
|
||||||
result.mapNotNull { it.results }
|
result.mapNotNull { it.results }
|
||||||
.flatten()
|
.flatten()
|
||||||
.let {
|
.let { bulkFavoriteScreenModel.reverseSelection(it) }
|
||||||
scope.launchIO {
|
|
||||||
bulkFavoriteScreenModel.reverseSelection(
|
|
||||||
bulkFavoriteScreenModel.networkToLocalManga(it),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ fun RelatedMangaCardRow(
|
||||||
contentPadding = PaddingValues(MaterialTheme.padding.small),
|
contentPadding = PaddingValues(MaterialTheme.padding.small),
|
||||||
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.extraSmall),
|
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)
|
val manga by getManga(it)
|
||||||
MangaItem(
|
MangaItem(
|
||||||
title = manga.title,
|
title = manga.title,
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ import tachiyomi.domain.category.model.Category
|
||||||
import tachiyomi.domain.chapter.interactor.SetMangaDefaultChapterFlags
|
import tachiyomi.domain.chapter.interactor.SetMangaDefaultChapterFlags
|
||||||
import tachiyomi.domain.library.service.LibraryPreferences
|
import tachiyomi.domain.library.service.LibraryPreferences
|
||||||
import tachiyomi.domain.manga.interactor.GetDuplicateLibraryManga
|
import tachiyomi.domain.manga.interactor.GetDuplicateLibraryManga
|
||||||
import tachiyomi.domain.manga.interactor.NetworkToLocalManga
|
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.domain.manga.model.MangaWithChapterCount
|
import tachiyomi.domain.manga.model.MangaWithChapterCount
|
||||||
import tachiyomi.domain.manga.model.toMangaUpdate
|
import tachiyomi.domain.manga.model.toMangaUpdate
|
||||||
|
|
@ -54,10 +53,6 @@ class BulkFavoriteScreenModel(
|
||||||
private val coverCache: CoverCache = Injekt.get(),
|
private val coverCache: CoverCache = Injekt.get(),
|
||||||
private val setMangaDefaultChapterFlags: SetMangaDefaultChapterFlags = Injekt.get(),
|
private val setMangaDefaultChapterFlags: SetMangaDefaultChapterFlags = Injekt.get(),
|
||||||
private val addTracks: AddTracks = Injekt.get(),
|
private val addTracks: AddTracks = Injekt.get(),
|
||||||
|
|
||||||
// KMK -->
|
|
||||||
val networkToLocalManga: NetworkToLocalManga = Injekt.get(),
|
|
||||||
// KMK <--
|
|
||||||
) : StateScreenModel<BulkFavoriteScreenModel.State>(initialState) {
|
) : StateScreenModel<BulkFavoriteScreenModel.State>(initialState) {
|
||||||
|
|
||||||
fun backHandler() {
|
fun backHandler() {
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ open class FeedScreenModel(
|
||||||
val sourceManager: SourceManager = Injekt.get(),
|
val sourceManager: SourceManager = Injekt.get(),
|
||||||
val sourcePreferences: SourcePreferences = Injekt.get(),
|
val sourcePreferences: SourcePreferences = Injekt.get(),
|
||||||
private val getManga: GetManga = Injekt.get(),
|
private val getManga: GetManga = Injekt.get(),
|
||||||
val networkToLocalManga: NetworkToLocalManga = Injekt.get(),
|
private val networkToLocalManga: NetworkToLocalManga = Injekt.get(),
|
||||||
getFeedSavedSearchGlobal: GetFeedSavedSearchGlobal = Injekt.get(),
|
getFeedSavedSearchGlobal: GetFeedSavedSearchGlobal = Injekt.get(),
|
||||||
private val getSavedSearchGlobalFeed: GetSavedSearchGlobalFeed = Injekt.get(),
|
private val getSavedSearchGlobalFeed: GetSavedSearchGlobalFeed = Injekt.get(),
|
||||||
private val countFeedSavedSearchGlobal: CountFeedSavedSearchGlobal = Injekt.get(),
|
private val countFeedSavedSearchGlobal: CountFeedSavedSearchGlobal = Injekt.get(),
|
||||||
|
|
@ -305,8 +305,8 @@ open class FeedScreenModel(
|
||||||
results = page
|
results = page
|
||||||
.map { it.toDomainManga(itemUI.source!!.id) }
|
.map { it.toDomainManga(itemUI.source!!.id) }
|
||||||
.distinctBy { it.url }
|
.distinctBy { it.url }
|
||||||
|
.let { networkToLocalManga(it) }
|
||||||
// KMK -->
|
// KMK -->
|
||||||
// .let { networkToLocalManga(it) }
|
|
||||||
.filter { !hideInLibraryFeedItems.get() || !it.favorite },
|
.filter { !hideInLibraryFeedItems.get() || !it.favorite },
|
||||||
// KMK <--
|
// KMK <--
|
||||||
)
|
)
|
||||||
|
|
@ -344,11 +344,8 @@ open class FeedScreenModel(
|
||||||
return produceState(initialValue = initialManga) {
|
return produceState(initialValue = initialManga) {
|
||||||
getManga.subscribe(initialManga.url, initialManga.source)
|
getManga.subscribe(initialManga.url, initialManga.source)
|
||||||
.collectLatest { manga ->
|
.collectLatest { manga ->
|
||||||
/* KMK --> if (manga == null) return@collectLatest KMK <-- */
|
if (manga == null) return@collectLatest
|
||||||
value = manga
|
value = manga
|
||||||
// KMK -->
|
|
||||||
?: initialManga
|
|
||||||
// KMK <--
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
import cafe.adriel.voyager.core.screen.Screen
|
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.collections.immutable.persistentListOf
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import tachiyomi.core.common.util.lang.launchIO
|
|
||||||
import tachiyomi.domain.source.interactor.GetRemoteManga
|
import tachiyomi.domain.source.interactor.GetRemoteManga
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
import tachiyomi.i18n.kmk.KMR
|
import tachiyomi.i18n.kmk.KMR
|
||||||
|
|
@ -55,7 +53,6 @@ fun Screen.feedTab(
|
||||||
val state by screenModel.state.collectAsState()
|
val state by screenModel.state.collectAsState()
|
||||||
|
|
||||||
// KMK -->
|
// KMK -->
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
|
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
|
||||||
val showingFeedOrderScreen = rememberSaveable { mutableStateOf(false) }
|
val showingFeedOrderScreen = rememberSaveable { mutableStateOf(false) }
|
||||||
|
|
||||||
|
|
@ -168,27 +165,21 @@ fun Screen.feedTab(
|
||||||
// KMK -->
|
// KMK -->
|
||||||
onLongClickFeed = screenModel::openActionsDialog,
|
onLongClickFeed = screenModel::openActionsDialog,
|
||||||
// KMK <--
|
// KMK <--
|
||||||
onClickManga = {
|
onClickManga = { manga ->
|
||||||
// KMK -->
|
// KMK -->
|
||||||
scope.launchIO {
|
if (bulkFavoriteState.selectionMode) {
|
||||||
val manga = screenModel.networkToLocalManga(it)
|
bulkFavoriteScreenModel.toggleSelection(manga)
|
||||||
if (bulkFavoriteState.selectionMode) {
|
} else {
|
||||||
bulkFavoriteScreenModel.toggleSelection(manga)
|
// KMK <--
|
||||||
} else {
|
navigator.push(MangaScreen(manga.id, true))
|
||||||
// KMK <--
|
|
||||||
navigator.push(MangaScreen(manga.id, true))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// KMK -->
|
// KMK -->
|
||||||
onLongClickManga = {
|
onLongClickManga = { manga ->
|
||||||
scope.launchIO {
|
if (!bulkFavoriteState.selectionMode) {
|
||||||
val manga = screenModel.networkToLocalManga(it)
|
bulkFavoriteScreenModel.addRemoveManga(manga, haptic)
|
||||||
if (!bulkFavoriteState.selectionMode) {
|
} else {
|
||||||
bulkFavoriteScreenModel.addRemoveManga(manga, haptic)
|
navigator.push(MangaScreen(manga.id, true))
|
||||||
} else {
|
|
||||||
navigator.push(MangaScreen(manga.id, true))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
selection = bulkFavoriteState.selection,
|
selection = bulkFavoriteState.selection,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
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.BulkFavoriteScreenModel
|
||||||
import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigrationListScreen
|
import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigrationListScreen
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
||||||
import tachiyomi.core.common.util.lang.launchIO
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manual search [validSources] for manga to migrate to.
|
* 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()
|
val dialogState by dialogScreenModel.state.collectAsState()
|
||||||
|
|
||||||
// KMK -->
|
// KMK -->
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() }
|
val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() }
|
||||||
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
|
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))
|
navigator.push(SourceSearchScreen(dialogState.manga!!, it.id, state.searchQuery))
|
||||||
// SY <--
|
// SY <--
|
||||||
},
|
},
|
||||||
onClickItem = {
|
onClickItem = { manga ->
|
||||||
// KMK -->
|
// KMK -->
|
||||||
scope.launchIO {
|
if (bulkFavoriteState.selectionMode) {
|
||||||
val manga = screenModel.networkToLocalManga(it)
|
bulkFavoriteScreenModel.toggleSelection(manga)
|
||||||
if (bulkFavoriteState.selectionMode) {
|
} else
|
||||||
bulkFavoriteScreenModel.toggleSelection(manga)
|
|
||||||
} else
|
|
||||||
// KMK <--
|
|
||||||
{
|
|
||||||
// SY -->
|
|
||||||
navigator.items
|
|
||||||
.filterIsInstance<MigrationListScreen>()
|
|
||||||
.last()
|
|
||||||
.newSelectedItem = mangaId to manga.id
|
|
||||||
navigator.popUntil { it is MigrationListScreen }
|
|
||||||
// SY <--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLongClickItem = {
|
|
||||||
// KMK -->
|
|
||||||
scope.launchIO {
|
|
||||||
val manga = screenModel.networkToLocalManga(it)
|
|
||||||
// KMK <--
|
// KMK <--
|
||||||
navigator.push(MangaScreen(manga.id, true))
|
{
|
||||||
}
|
// SY -->
|
||||||
|
navigator.items
|
||||||
|
.filterIsInstance<MigrationListScreen>()
|
||||||
|
.last()
|
||||||
|
.newSelectedItem = mangaId to manga.id
|
||||||
|
navigator.popUntil { it is MigrationListScreen }
|
||||||
|
// SY <--
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
onLongClickItem = { navigator.push(MangaScreen(it.id, true)) },
|
||||||
// KMK -->
|
// KMK -->
|
||||||
bulkFavoriteScreenModel = bulkFavoriteScreenModel,
|
bulkFavoriteScreenModel = bulkFavoriteScreenModel,
|
||||||
hasPinnedSources = screenModel.hasPinnedSources(),
|
hasPinnedSources = screenModel.hasPinnedSources(),
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.ui.platform.LocalConfiguration
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalUriHandler
|
import androidx.compose.ui.platform.LocalUriHandler
|
||||||
|
|
@ -34,7 +33,6 @@ import eu.kanade.tachiyomi.util.system.toast
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
import mihon.presentation.core.util.collectAsLazyPagingItems
|
import mihon.presentation.core.util.collectAsLazyPagingItems
|
||||||
import tachiyomi.core.common.Constants
|
import tachiyomi.core.common.Constants
|
||||||
import tachiyomi.core.common.util.lang.launchIO
|
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.i18n.sy.SYMR
|
import tachiyomi.i18n.sy.SYMR
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
|
|
@ -68,7 +66,6 @@ data class SourceSearchScreen(
|
||||||
|
|
||||||
// KMK -->
|
// KMK -->
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
|
|
||||||
val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() }
|
val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() }
|
||||||
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
|
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
|
||||||
|
|
@ -92,23 +89,12 @@ data class SourceSearchScreen(
|
||||||
onSelectAll = {
|
onSelectAll = {
|
||||||
mangaList.itemSnapshotList.items
|
mangaList.itemSnapshotList.items
|
||||||
.map { it.value.first }
|
.map { it.value.first }
|
||||||
.let {
|
.forEach { bulkFavoriteScreenModel.select(it) }
|
||||||
scope.launchIO {
|
|
||||||
bulkFavoriteScreenModel.networkToLocalManga(it)
|
|
||||||
.forEach { bulkFavoriteScreenModel.select(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
onReverseSelection = {
|
onReverseSelection = {
|
||||||
mangaList.itemSnapshotList.items
|
mangaList.itemSnapshotList.items
|
||||||
.map { it.value.first }
|
.map { it.value.first }
|
||||||
.let {
|
.let { bulkFavoriteScreenModel.reverseSelection(it) }
|
||||||
scope.launchIO {
|
|
||||||
bulkFavoriteScreenModel.reverseSelection(
|
|
||||||
bulkFavoriteScreenModel.networkToLocalManga(it),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -175,26 +161,16 @@ data class SourceSearchScreen(
|
||||||
},
|
},
|
||||||
onHelpClick = { uriHandler.openUri(Constants.URL_HELP) },
|
onHelpClick = { uriHandler.openUri(Constants.URL_HELP) },
|
||||||
onLocalSourceHelpClick = { uriHandler.openUri(LocalSource.HELP_URL) },
|
onLocalSourceHelpClick = { uriHandler.openUri(LocalSource.HELP_URL) },
|
||||||
onMangaClick = {
|
onMangaClick = { manga ->
|
||||||
// KMK -->
|
// KMK -->
|
||||||
scope.launchIO {
|
if (bulkFavoriteState.selectionMode) {
|
||||||
val manga = screenModel.networkToLocalManga(it)
|
bulkFavoriteScreenModel.toggleSelection(manga)
|
||||||
if (bulkFavoriteState.selectionMode) {
|
} else {
|
||||||
bulkFavoriteScreenModel.toggleSelection(manga)
|
|
||||||
} else {
|
|
||||||
// KMK <--
|
|
||||||
openMigrateDialog(manga)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onMangaLongClick = {
|
|
||||||
// KMK -->
|
|
||||||
scope.launchIO {
|
|
||||||
val manga = screenModel.networkToLocalManga(it)
|
|
||||||
// KMK <--
|
// KMK <--
|
||||||
navigator.push(MangaScreen(manga.id, true))
|
openMigrateDialog(manga)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onMangaLongClick = { navigator.push(MangaScreen(it.id, true)) },
|
||||||
// KMK -->
|
// KMK -->
|
||||||
selection = bulkFavoriteState.selection,
|
selection = bulkFavoriteState.selection,
|
||||||
// KMK <--
|
// KMK <--
|
||||||
|
|
|
||||||
|
|
@ -202,23 +202,12 @@ data class BrowseSourceScreen(
|
||||||
onSelectAll = {
|
onSelectAll = {
|
||||||
mangaList.itemSnapshotList.items
|
mangaList.itemSnapshotList.items
|
||||||
.map { it.value.first }
|
.map { it.value.first }
|
||||||
.let {
|
.forEach { bulkFavoriteScreenModel.select(it) }
|
||||||
scope.launchIO {
|
|
||||||
bulkFavoriteScreenModel.networkToLocalManga(it)
|
|
||||||
.forEach { bulkFavoriteScreenModel.select(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
onReverseSelection = {
|
onReverseSelection = {
|
||||||
mangaList.itemSnapshotList.items
|
mangaList.itemSnapshotList.items
|
||||||
.map { it.value.first }
|
.map { it.value.first }
|
||||||
.let {
|
.let { bulkFavoriteScreenModel.reverseSelection(it) }
|
||||||
scope.launchIO {
|
|
||||||
bulkFavoriteScreenModel.reverseSelection(
|
|
||||||
bulkFavoriteScreenModel.networkToLocalManga(it),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -367,36 +356,32 @@ data class BrowseSourceScreen(
|
||||||
onWebViewClick = onWebViewClick,
|
onWebViewClick = onWebViewClick,
|
||||||
onHelpClick = { uriHandler.openUri(Constants.URL_HELP) },
|
onHelpClick = { uriHandler.openUri(Constants.URL_HELP) },
|
||||||
onLocalSourceHelpClick = onHelpClick,
|
onLocalSourceHelpClick = onHelpClick,
|
||||||
onMangaClick = {
|
onMangaClick = { manga ->
|
||||||
// KMK -->
|
// KMK -->
|
||||||
scope.launchIO {
|
if (bulkFavoriteState.selectionMode) {
|
||||||
val manga = screenModel.networkToLocalManga(it)
|
bulkFavoriteScreenModel.toggleSelection(manga)
|
||||||
if (bulkFavoriteState.selectionMode) {
|
} else {
|
||||||
bulkFavoriteScreenModel.toggleSelection(manga)
|
// KMK <--
|
||||||
} else {
|
navigator.push(
|
||||||
// KMK <--
|
MangaScreen(
|
||||||
navigator.push(
|
mangaId = manga.id,
|
||||||
MangaScreen(
|
// KMK -->
|
||||||
mangaId = manga.id,
|
// Finding the entry to be merged to, so we don't want to expand description
|
||||||
// KMK -->
|
// so that user can see the `Merge to another` button
|
||||||
// Finding the entry to be merged to, so we don't want to expand description
|
fromSource = smartSearchConfig == null,
|
||||||
// so that user can see the `Merge to another` button
|
// KMK <--
|
||||||
fromSource = smartSearchConfig == null,
|
smartSearchConfig = smartSearchConfig,
|
||||||
// KMK <--
|
),
|
||||||
smartSearchConfig = smartSearchConfig,
|
)
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onMangaLongClick = {
|
onMangaLongClick = { manga ->
|
||||||
// KMK -->
|
// KMK -->
|
||||||
scope.launchIO {
|
if (bulkFavoriteState.selectionMode) {
|
||||||
val manga = screenModel.networkToLocalManga(it)
|
navigator.push(MangaScreen(manga.id, true))
|
||||||
if (bulkFavoriteState.selectionMode) {
|
} else {
|
||||||
navigator.push(MangaScreen(manga.id, true))
|
// KMK <--
|
||||||
} else {
|
scope.launchIO {
|
||||||
// KMK <--
|
|
||||||
val duplicates = screenModel.getDuplicateLibraryManga(manga)
|
val duplicates = screenModel.getDuplicateLibraryManga(manga)
|
||||||
when {
|
when {
|
||||||
manga.favorite -> screenModel.setDialog(BrowseSourceScreenModel.Dialog.RemoveManga(manga))
|
manga.favorite -> screenModel.setDialog(BrowseSourceScreenModel.Dialog.RemoveManga(manga))
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,6 @@ import tachiyomi.domain.library.service.LibraryPreferences
|
||||||
import tachiyomi.domain.manga.interactor.GetDuplicateLibraryManga
|
import tachiyomi.domain.manga.interactor.GetDuplicateLibraryManga
|
||||||
import tachiyomi.domain.manga.interactor.GetFlatMetadataById
|
import tachiyomi.domain.manga.interactor.GetFlatMetadataById
|
||||||
import tachiyomi.domain.manga.interactor.GetManga
|
import tachiyomi.domain.manga.interactor.GetManga
|
||||||
import tachiyomi.domain.manga.interactor.NetworkToLocalManga
|
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.domain.manga.model.MangaWithChapterCount
|
import tachiyomi.domain.manga.model.MangaWithChapterCount
|
||||||
import tachiyomi.domain.manga.model.toMangaUpdate
|
import tachiyomi.domain.manga.model.toMangaUpdate
|
||||||
|
|
@ -115,9 +114,6 @@ open class BrowseSourceScreenModel(
|
||||||
private val extensionManager: ExtensionManager = Injekt.get(),
|
private val extensionManager: ExtensionManager = Injekt.get(),
|
||||||
// KMK <--
|
// KMK <--
|
||||||
|
|
||||||
// KMK -->
|
|
||||||
val networkToLocalManga: NetworkToLocalManga = Injekt.get(),
|
|
||||||
// KMK <--
|
|
||||||
// SY -->
|
// SY -->
|
||||||
unsortedPreferences: UnsortedPreferences = Injekt.get(),
|
unsortedPreferences: UnsortedPreferences = Injekt.get(),
|
||||||
uiPreferences: UiPreferences = Injekt.get(),
|
uiPreferences: UiPreferences = Injekt.get(),
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
|
|
@ -40,7 +39,6 @@ import exh.md.follows.MangaDexFollowsScreen
|
||||||
import exh.source.anyIs
|
import exh.source.anyIs
|
||||||
import exh.source.isEhBasedSource
|
import exh.source.isEhBasedSource
|
||||||
import exh.util.nullIfBlank
|
import exh.util.nullIfBlank
|
||||||
import tachiyomi.core.common.util.lang.launchIO
|
|
||||||
import tachiyomi.domain.UnsortedPreferences
|
import tachiyomi.domain.UnsortedPreferences
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.domain.source.interactor.GetRemoteManga
|
import tachiyomi.domain.source.interactor.GetRemoteManga
|
||||||
|
|
@ -67,7 +65,6 @@ class SourceFeedScreen(val sourceId: Long) : Screen() {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
// KMK -->
|
// KMK -->
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
screenModel.source.let {
|
screenModel.source.let {
|
||||||
if (it is StubSource) {
|
if (it is StubSource) {
|
||||||
MissingSourceScreen(
|
MissingSourceScreen(
|
||||||
|
|
@ -126,16 +123,13 @@ class SourceFeedScreen(val sourceId: Long) : Screen() {
|
||||||
// onClickDelete = screenModel::openDeleteFeed,
|
// onClickDelete = screenModel::openDeleteFeed,
|
||||||
onLongClickFeed = screenModel::openActionsDialog,
|
onLongClickFeed = screenModel::openActionsDialog,
|
||||||
// KMK <--
|
// KMK <--
|
||||||
onClickManga = {
|
onClickManga = { manga ->
|
||||||
// KMK -->
|
// KMK -->
|
||||||
scope.launchIO {
|
if (bulkFavoriteState.selectionMode) {
|
||||||
val manga = screenModel.networkToLocalManga(it)
|
bulkFavoriteScreenModel.toggleSelection(manga)
|
||||||
if (bulkFavoriteState.selectionMode) {
|
} else {
|
||||||
bulkFavoriteScreenModel.toggleSelection(manga)
|
// KMK <--
|
||||||
} else {
|
onMangaClick(navigator, manga)
|
||||||
// KMK <--
|
|
||||||
onMangaClick(navigator, manga)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onClickSearch = { onSearchClick(navigator, screenModel.source, it) },
|
onClickSearch = { onSearchClick(navigator, screenModel.source, it) },
|
||||||
|
|
@ -170,14 +164,11 @@ class SourceFeedScreen(val sourceId: Long) : Screen() {
|
||||||
.filterIsInstance<SourceFeedUI.SourceSavedSearch>()
|
.filterIsInstance<SourceFeedUI.SourceSavedSearch>()
|
||||||
.isNotEmpty()
|
.isNotEmpty()
|
||||||
},
|
},
|
||||||
onLongClickManga = {
|
onLongClickManga = { manga ->
|
||||||
scope.launchIO {
|
if (!bulkFavoriteState.selectionMode) {
|
||||||
val manga = screenModel.networkToLocalManga(it)
|
bulkFavoriteScreenModel.addRemoveManga(manga, haptic)
|
||||||
if (!bulkFavoriteState.selectionMode) {
|
} else {
|
||||||
bulkFavoriteScreenModel.addRemoveManga(manga, haptic)
|
navigator.push(MangaScreen(manga.id, true))
|
||||||
} else {
|
|
||||||
navigator.push(MangaScreen(manga.id, true))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
bulkFavoriteScreenModel = bulkFavoriteScreenModel,
|
bulkFavoriteScreenModel = bulkFavoriteScreenModel,
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ open class SourceFeedScreenModel(
|
||||||
uiPreferences: UiPreferences = Injekt.get(),
|
uiPreferences: UiPreferences = Injekt.get(),
|
||||||
private val sourceManager: SourceManager = Injekt.get(),
|
private val sourceManager: SourceManager = Injekt.get(),
|
||||||
private val getManga: GetManga = 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 getFeedSavedSearchBySourceId: GetFeedSavedSearchBySourceId = Injekt.get(),
|
||||||
private val getSavedSearchBySourceIdFeed: GetSavedSearchBySourceIdFeed = Injekt.get(),
|
private val getSavedSearchBySourceIdFeed: GetSavedSearchBySourceIdFeed = Injekt.get(),
|
||||||
private val countFeedSavedSearchBySourceId: CountFeedSavedSearchBySourceId = Injekt.get(),
|
private val countFeedSavedSearchBySourceId: CountFeedSavedSearchBySourceId = Injekt.get(),
|
||||||
|
|
@ -251,7 +251,7 @@ open class SourceFeedScreenModel(
|
||||||
val titles = withIOContext {
|
val titles = withIOContext {
|
||||||
page.map { it.toDomainManga(source.id) }
|
page.map { it.toDomainManga(source.id) }
|
||||||
.distinctBy { it.url }
|
.distinctBy { it.url }
|
||||||
/* KMK --> .let { networkToLocalManga(it) } KMK <-- */
|
.let { networkToLocalManga(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
mutableState.update { state ->
|
mutableState.update { state ->
|
||||||
|
|
@ -285,11 +285,8 @@ open class SourceFeedScreenModel(
|
||||||
return produceState(initialValue = initialManga) {
|
return produceState(initialValue = initialManga) {
|
||||||
getManga.subscribe(initialManga.url, initialManga.source)
|
getManga.subscribe(initialManga.url, initialManga.source)
|
||||||
.collectLatest { manga ->
|
.collectLatest { manga ->
|
||||||
/* KMK --> if (manga == null) return@collectLatest KMK <-- */
|
if (manga == null) return@collectLatest
|
||||||
value = manga
|
value = manga
|
||||||
// KMK -->
|
|
||||||
?: initialManga
|
|
||||||
// KMK <--
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
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.BulkFavoriteScreenModel
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreen
|
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreen
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
||||||
import tachiyomi.core.common.util.lang.launchIO
|
|
||||||
import tachiyomi.presentation.core.screens.LoadingScreen
|
import tachiyomi.presentation.core.screens.LoadingScreen
|
||||||
|
|
||||||
class GlobalSearchScreen(
|
class GlobalSearchScreen(
|
||||||
|
|
@ -49,7 +47,6 @@ class GlobalSearchScreen(
|
||||||
}
|
}
|
||||||
|
|
||||||
// KMK -->
|
// KMK -->
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() }
|
val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() }
|
||||||
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
|
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
|
||||||
|
|
||||||
|
|
@ -69,12 +66,7 @@ class GlobalSearchScreen(
|
||||||
is SearchItemResult.Success -> {
|
is SearchItemResult.Success -> {
|
||||||
val manga = result.result.singleOrNull()
|
val manga = result.result.singleOrNull()
|
||||||
if (manga != null) {
|
if (manga != null) {
|
||||||
// KMK -->
|
navigator.replace(MangaScreen(manga.id, true))
|
||||||
scope.launchIO {
|
|
||||||
val localManga = screenModel.networkToLocalManga(manga)
|
|
||||||
// KMK <--
|
|
||||||
navigator.replace(MangaScreen(localManga.id, true))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Backoff to result screen
|
// Backoff to result screen
|
||||||
showSingleLoadingScreen = false
|
showSingleLoadingScreen = false
|
||||||
|
|
@ -95,28 +87,22 @@ class GlobalSearchScreen(
|
||||||
onClickSource = {
|
onClickSource = {
|
||||||
navigator.push(BrowseSourceScreen(it.id, state.searchQuery))
|
navigator.push(BrowseSourceScreen(it.id, state.searchQuery))
|
||||||
},
|
},
|
||||||
onClickItem = {
|
onClickItem = { manga ->
|
||||||
// KMK -->
|
// KMK -->
|
||||||
scope.launchIO {
|
if (bulkFavoriteState.selectionMode) {
|
||||||
val manga = screenModel.networkToLocalManga(it)
|
bulkFavoriteScreenModel.toggleSelection(manga)
|
||||||
if (bulkFavoriteState.selectionMode) {
|
} else {
|
||||||
bulkFavoriteScreenModel.toggleSelection(manga)
|
// KMK <--
|
||||||
} else {
|
navigator.push(MangaScreen(manga.id, true))
|
||||||
// KMK <--
|
|
||||||
navigator.push(MangaScreen(manga.id, true))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLongClickItem = {
|
onLongClickItem = { manga ->
|
||||||
// KMK -->
|
// KMK -->
|
||||||
scope.launchIO {
|
if (!bulkFavoriteState.selectionMode) {
|
||||||
val manga = screenModel.networkToLocalManga(it)
|
bulkFavoriteScreenModel.addRemoveManga(manga, haptic)
|
||||||
if (!bulkFavoriteState.selectionMode) {
|
} else {
|
||||||
bulkFavoriteScreenModel.addRemoveManga(manga, haptic)
|
// KMK <--
|
||||||
} else {
|
navigator.push(MangaScreen(manga.id, true))
|
||||||
// KMK <--
|
|
||||||
navigator.push(MangaScreen(manga.id, true))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// KMK -->
|
// KMK -->
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import kotlinx.coroutines.asCoroutineDispatcher
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.awaitAll
|
import kotlinx.coroutines.awaitAll
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
|
import kotlinx.coroutines.flow.filterNotNull
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.isActive
|
import kotlinx.coroutines.isActive
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
@ -39,7 +40,7 @@ abstract class SearchScreenModel(
|
||||||
sourcePreferences: SourcePreferences = Injekt.get(),
|
sourcePreferences: SourcePreferences = Injekt.get(),
|
||||||
private val sourceManager: SourceManager = Injekt.get(),
|
private val sourceManager: SourceManager = Injekt.get(),
|
||||||
private val extensionManager: ExtensionManager = 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 getManga: GetManga = Injekt.get(),
|
||||||
private val preferences: SourcePreferences = Injekt.get(),
|
private val preferences: SourcePreferences = Injekt.get(),
|
||||||
) : StateScreenModel<SearchScreenModel.State>(initialState) {
|
) : StateScreenModel<SearchScreenModel.State>(initialState) {
|
||||||
|
|
@ -83,12 +84,9 @@ abstract class SearchScreenModel(
|
||||||
fun getManga(initialManga: Manga): androidx.compose.runtime.State<Manga> {
|
fun getManga(initialManga: Manga): androidx.compose.runtime.State<Manga> {
|
||||||
return produceState(initialValue = initialManga) {
|
return produceState(initialValue = initialManga) {
|
||||||
getManga.subscribe(initialManga.url, initialManga.source)
|
getManga.subscribe(initialManga.url, initialManga.source)
|
||||||
/* KMK --> .filterNotNull() KMK <-- */
|
.filterNotNull()
|
||||||
.collectLatest { manga ->
|
.collectLatest { manga ->
|
||||||
value = manga
|
value = manga
|
||||||
// KMK -->
|
|
||||||
?: initialManga
|
|
||||||
// KMK <--
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -192,7 +190,7 @@ abstract class SearchScreenModel(
|
||||||
val titles = page.mangas
|
val titles = page.mangas
|
||||||
.map { it.toDomainManga(source.id) }
|
.map { it.toDomainManga(source.id) }
|
||||||
.distinctBy { it.url }
|
.distinctBy { it.url }
|
||||||
/* KMK --> .let { networkToLocalManga(it) } KMK <-- */
|
.let { networkToLocalManga(it) }
|
||||||
|
|
||||||
if (isActive) {
|
if (isActive) {
|
||||||
updateItem(source, SearchItemResult.Success(titles))
|
updateItem(source, SearchItemResult.Success(titles))
|
||||||
|
|
|
||||||
|
|
@ -391,18 +391,8 @@ class MangaScreen(
|
||||||
}
|
}
|
||||||
showRelatedMangasScreen()
|
showRelatedMangasScreen()
|
||||||
},
|
},
|
||||||
onRelatedMangaClick = {
|
onRelatedMangaClick = { navigator.push(MangaScreen(it.id, true)) },
|
||||||
scope.launchIO {
|
onRelatedMangaLongClick = { bulkFavoriteScreenModel.addRemoveManga(it, haptic) },
|
||||||
val manga = screenModel.networkToLocalManga(it)
|
|
||||||
navigator.push(MangaScreen(manga.id, true))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onRelatedMangaLongClick = {
|
|
||||||
scope.launchIO {
|
|
||||||
val manga = screenModel.networkToLocalManga(it)
|
|
||||||
bulkFavoriteScreenModel.addRemoveManga(manga, haptic)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onSourceClick = {
|
onSourceClick = {
|
||||||
if (successState.source !is StubSource) {
|
if (successState.source !is StubSource) {
|
||||||
val screen = when {
|
val screen = when {
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,7 @@ import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.distinctUntilChangedBy
|
import kotlinx.coroutines.flow.distinctUntilChangedBy
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.filter
|
||||||
|
import kotlinx.coroutines.flow.filterNotNull
|
||||||
import kotlinx.coroutines.flow.flatMapConcat
|
import kotlinx.coroutines.flow.flatMapConcat
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
|
|
@ -202,7 +203,7 @@ class MangaScreenModel(
|
||||||
private val smartSearchMerge: SmartSearchMerge = Injekt.get(),
|
private val smartSearchMerge: SmartSearchMerge = Injekt.get(),
|
||||||
// KMK <--
|
// KMK <--
|
||||||
private val updateMergedSettings: UpdateMergedSettings = Injekt.get(),
|
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 deleteMergeById: DeleteMergeById = Injekt.get(),
|
||||||
private val getFlatMetadata: GetFlatMetadataById = Injekt.get(),
|
private val getFlatMetadata: GetFlatMetadataById = Injekt.get(),
|
||||||
private val getPagePreviews: GetPagePreviews = Injekt.get(),
|
private val getPagePreviews: GetPagePreviews = Injekt.get(),
|
||||||
|
|
@ -740,13 +741,10 @@ class MangaScreenModel(
|
||||||
fun getManga(initialManga: Manga): RuntimeState<Manga> {
|
fun getManga(initialManga: Manga): RuntimeState<Manga> {
|
||||||
return produceState(initialValue = initialManga) {
|
return produceState(initialValue = initialManga) {
|
||||||
getManga.subscribe(initialManga.url, initialManga.source)
|
getManga.subscribe(initialManga.url, initialManga.source)
|
||||||
/* KMK --> .filterNotNull() KMK <-- */
|
.filterNotNull()
|
||||||
.flowWithLifecycle(lifecycle)
|
.flowWithLifecycle(lifecycle)
|
||||||
.collectLatest { manga ->
|
.collectLatest { manga ->
|
||||||
value = manga
|
value = manga
|
||||||
// KMK -->
|
|
||||||
?: initialManga
|
|
||||||
// KMK <--
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1220,7 +1218,7 @@ class MangaScreenModel(
|
||||||
mangaList
|
mangaList
|
||||||
.map { it.toDomainManga(state.source.id) }
|
.map { it.toDomainManga(state.source.id) }
|
||||||
.distinctBy { it.url }
|
.distinctBy { it.url }
|
||||||
/* KMK --> .let { networkToLocalManga(it) } KMK <-- */
|
.let { networkToLocalManga(it, false) }
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSuccessState { successState ->
|
updateSuccessState { successState ->
|
||||||
|
|
@ -2073,14 +2071,14 @@ sealed interface RelatedManga {
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun List<RelatedManga>.removeDuplicates(manga: Manga): List<RelatedManga> {
|
internal fun List<RelatedManga>.removeDuplicates(manga: Manga): List<RelatedManga> {
|
||||||
val mangaHashes = HashSet<Int>().apply { add(manga.url.hashCode()) }
|
val mangaIds = HashSet<Long>().apply { add(manga.id) }
|
||||||
|
|
||||||
return map { relatedManga ->
|
return map { relatedManga ->
|
||||||
if (relatedManga is Success) {
|
if (relatedManga is Success) {
|
||||||
Success(
|
Success(
|
||||||
relatedManga.keyword,
|
relatedManga.keyword,
|
||||||
relatedManga.mangaList
|
relatedManga.mangaList
|
||||||
.filter { mangaHashes.add(it.url.hashCode()) },
|
.filter { mangaIds.add(it.id) },
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
relatedManga
|
relatedManga
|
||||||
|
|
|
||||||
|
|
@ -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.browse.BrowseSourceScreen
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchScreen
|
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchScreen
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import tachiyomi.core.common.util.lang.launchIO
|
|
||||||
import tachiyomi.domain.library.service.LibraryPreferences
|
import tachiyomi.domain.library.service.LibraryPreferences
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
|
|
@ -58,25 +57,14 @@ fun RelatedMangasScreen(
|
||||||
successState.relatedMangasSorted?.let { result ->
|
successState.relatedMangasSorted?.let { result ->
|
||||||
result.map { it as RelatedManga.Success }
|
result.map { it as RelatedManga.Success }
|
||||||
.flatMap { it.mangaList }
|
.flatMap { it.mangaList }
|
||||||
.let {
|
.forEach { bulkFavoriteScreenModel.select(it) }
|
||||||
scope.launchIO {
|
|
||||||
bulkFavoriteScreenModel.networkToLocalManga(it)
|
|
||||||
.forEach { bulkFavoriteScreenModel.select(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onReverseSelection = {
|
onReverseSelection = {
|
||||||
successState.relatedMangasSorted?.let { result ->
|
successState.relatedMangasSorted?.let { result ->
|
||||||
result.map { it as RelatedManga.Success }
|
result.map { it as RelatedManga.Success }
|
||||||
.flatMap { it.mangaList }
|
.flatMap { it.mangaList }
|
||||||
.let {
|
.let { bulkFavoriteScreenModel.reverseSelection(it) }
|
||||||
scope.launchIO {
|
|
||||||
bulkFavoriteScreenModel.reverseSelection(
|
|
||||||
bulkFavoriteScreenModel.networkToLocalManga(it),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
@ -100,24 +88,18 @@ fun RelatedMangasScreen(
|
||||||
columns = getColumnsPreference(LocalConfiguration.current.orientation),
|
columns = getColumnsPreference(LocalConfiguration.current.orientation),
|
||||||
displayMode = displayMode,
|
displayMode = displayMode,
|
||||||
contentPadding = paddingValues,
|
contentPadding = paddingValues,
|
||||||
onMangaClick = {
|
onMangaClick = { manga ->
|
||||||
scope.launchIO {
|
if (bulkFavoriteState.selectionMode) {
|
||||||
val manga = screenModel.networkToLocalManga(it)
|
bulkFavoriteScreenModel.toggleSelection(manga)
|
||||||
if (bulkFavoriteState.selectionMode) {
|
} else {
|
||||||
bulkFavoriteScreenModel.toggleSelection(manga)
|
navigator.push(MangaScreen(manga.id, true))
|
||||||
} else {
|
|
||||||
navigator.push(MangaScreen(manga.id, true))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onMangaLongClick = {
|
onMangaLongClick = { manga ->
|
||||||
scope.launchIO {
|
if (!bulkFavoriteState.selectionMode) {
|
||||||
val manga = screenModel.networkToLocalManga(it)
|
bulkFavoriteScreenModel.addRemoveManga(manga, haptic)
|
||||||
if (!bulkFavoriteState.selectionMode) {
|
} else {
|
||||||
bulkFavoriteScreenModel.addRemoveManga(manga, haptic)
|
navigator.push(MangaScreen(manga.id, true))
|
||||||
} else {
|
|
||||||
navigator.push(MangaScreen(manga.id, true))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onKeywordClick = { query ->
|
onKeywordClick = { query ->
|
||||||
|
|
|
||||||
|
|
@ -77,23 +77,12 @@ class MangaDexFollowsScreen(private val sourceId: Long) : Screen() {
|
||||||
onSelectAll = {
|
onSelectAll = {
|
||||||
mangaList.itemSnapshotList.items
|
mangaList.itemSnapshotList.items
|
||||||
.map { it.value.first }
|
.map { it.value.first }
|
||||||
.let {
|
.forEach { bulkFavoriteScreenModel.select(it) }
|
||||||
scope.launchIO {
|
|
||||||
bulkFavoriteScreenModel.networkToLocalManga(it)
|
|
||||||
.forEach { bulkFavoriteScreenModel.select(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
onReverseSelection = {
|
onReverseSelection = {
|
||||||
mangaList.itemSnapshotList.items
|
mangaList.itemSnapshotList.items
|
||||||
.map { it.value.first }
|
.map { it.value.first }
|
||||||
.let {
|
.let { bulkFavoriteScreenModel.reverseSelection(it) }
|
||||||
scope.launchIO {
|
|
||||||
bulkFavoriteScreenModel.reverseSelection(
|
|
||||||
bulkFavoriteScreenModel.networkToLocalManga(it),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -128,26 +117,22 @@ class MangaDexFollowsScreen(private val sourceId: Long) : Screen() {
|
||||||
onWebViewClick = null,
|
onWebViewClick = null,
|
||||||
onHelpClick = null,
|
onHelpClick = null,
|
||||||
onLocalSourceHelpClick = null,
|
onLocalSourceHelpClick = null,
|
||||||
onMangaClick = {
|
onMangaClick = { manga ->
|
||||||
// KMK -->
|
// KMK -->
|
||||||
scope.launchIO {
|
if (bulkFavoriteState.selectionMode) {
|
||||||
val manga = screenModel.networkToLocalManga(it)
|
bulkFavoriteScreenModel.toggleSelection(manga)
|
||||||
if (bulkFavoriteState.selectionMode) {
|
} else {
|
||||||
bulkFavoriteScreenModel.toggleSelection(manga)
|
// KMK <--
|
||||||
} else {
|
navigator.push(MangaScreen(manga.id, true))
|
||||||
// KMK <--
|
|
||||||
navigator.push(MangaScreen(manga.id, true))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onMangaLongClick = {
|
onMangaLongClick = { manga ->
|
||||||
// KMK -->
|
// KMK -->
|
||||||
scope.launchIO {
|
if (bulkFavoriteState.selectionMode) {
|
||||||
val manga = screenModel.networkToLocalManga(it)
|
navigator.push(MangaScreen(manga.id, true))
|
||||||
if (bulkFavoriteState.selectionMode) {
|
} else {
|
||||||
navigator.push(MangaScreen(manga.id, true))
|
// KMK <--
|
||||||
} else {
|
scope.launchIO {
|
||||||
// KMK <--
|
|
||||||
val duplicates = screenModel.getDuplicateLibraryManga(manga)
|
val duplicates = screenModel.getDuplicateLibraryManga(manga)
|
||||||
when {
|
when {
|
||||||
manga.favorite -> screenModel.setDialog(BrowseSourceScreenModel.Dialog.RemoveManga(manga))
|
manga.favorite -> screenModel.setDialog(BrowseSourceScreenModel.Dialog.RemoveManga(manga))
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.ui.platform.LocalConfiguration
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
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.manga.MangaScreen
|
||||||
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
|
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
|
||||||
import mihon.presentation.core.util.collectAsLazyPagingItems
|
import mihon.presentation.core.util.collectAsLazyPagingItems
|
||||||
import tachiyomi.core.common.util.lang.launchIO
|
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
import tachiyomi.presentation.core.screens.LoadingScreen
|
import tachiyomi.presentation.core.screens.LoadingScreen
|
||||||
|
|
@ -52,7 +50,6 @@ class BrowseRecommendsScreen(
|
||||||
}
|
}
|
||||||
|
|
||||||
// KMK -->
|
// KMK -->
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() }
|
val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() }
|
||||||
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
|
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
|
||||||
|
|
||||||
|
|
@ -97,23 +94,12 @@ class BrowseRecommendsScreen(
|
||||||
onSelectAll = {
|
onSelectAll = {
|
||||||
mangaList.itemSnapshotList.items
|
mangaList.itemSnapshotList.items
|
||||||
.map { it.value.first }
|
.map { it.value.first }
|
||||||
.let {
|
.forEach { bulkFavoriteScreenModel.select(it) }
|
||||||
scope.launchIO {
|
|
||||||
bulkFavoriteScreenModel.networkToLocalManga(it)
|
|
||||||
.forEach { bulkFavoriteScreenModel.select(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
onReverseSelection = {
|
onReverseSelection = {
|
||||||
mangaList.itemSnapshotList.items
|
mangaList.itemSnapshotList.items
|
||||||
.map { it.value.first }
|
.map { it.value.first }
|
||||||
.let {
|
.let { bulkFavoriteScreenModel.reverseSelection(it) }
|
||||||
scope.launchIO {
|
|
||||||
bulkFavoriteScreenModel.reverseSelection(
|
|
||||||
bulkFavoriteScreenModel.networkToLocalManga(it),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -153,37 +139,23 @@ class BrowseRecommendsScreen(
|
||||||
onWebViewClick = null,
|
onWebViewClick = null,
|
||||||
onHelpClick = null,
|
onHelpClick = null,
|
||||||
onLocalSourceHelpClick = null,
|
onLocalSourceHelpClick = null,
|
||||||
onMangaClick = {
|
onMangaClick = { manga ->
|
||||||
// KMK -->
|
// KMK -->
|
||||||
if (isExternalSource) {
|
if (bulkFavoriteState.selectionMode) {
|
||||||
onClickItem(it)
|
bulkFavoriteScreenModel.toggleSelection(manga)
|
||||||
} else {
|
} else {
|
||||||
scope.launchIO {
|
// KMK <--
|
||||||
val manga = screenModel.networkToLocalManga(it)
|
onClickItem(manga)
|
||||||
if (bulkFavoriteState.selectionMode) {
|
|
||||||
bulkFavoriteScreenModel.toggleSelection(manga)
|
|
||||||
} else {
|
|
||||||
// KMK <--
|
|
||||||
onClickItem(manga)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onMangaLongClick = {
|
onMangaLongClick = { manga ->
|
||||||
// KMK -->
|
// KMK -->
|
||||||
if (isExternalSource) {
|
if (!bulkFavoriteState.selectionMode) {
|
||||||
onLongClickItem(it)
|
bulkFavoriteScreenModel.addRemoveManga(manga, haptic)
|
||||||
} else {
|
} else {
|
||||||
scope.launchIO {
|
onLongClickItem(manga)
|
||||||
val manga = screenModel.networkToLocalManga(it)
|
|
||||||
if (!bulkFavoriteState.selectionMode) {
|
|
||||||
bulkFavoriteScreenModel.addRemoveManga(manga, haptic)
|
|
||||||
} else {
|
|
||||||
onLongClickItem(manga)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// KMK <--
|
|
||||||
}
|
}
|
||||||
|
// KMK <--
|
||||||
},
|
},
|
||||||
// KMK -->
|
// KMK -->
|
||||||
selection = bulkFavoriteState.selection,
|
selection = bulkFavoriteState.selection,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
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.manga.MangaScreen
|
||||||
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
|
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
|
||||||
import exh.recs.components.RecommendsScreen
|
import exh.recs.components.RecommendsScreen
|
||||||
import tachiyomi.core.common.util.lang.launchIO
|
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.presentation.core.screens.LoadingScreen
|
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()
|
val state by screenModel.state.collectAsState()
|
||||||
|
|
||||||
// KMK -->
|
// KMK -->
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() }
|
val bulkFavoriteScreenModel = rememberScreenModel { BulkFavoriteScreenModel() }
|
||||||
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
|
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
|
||||||
|
|
||||||
|
|
@ -52,21 +49,12 @@ class RecommendsScreen(val mangaId: Long, val sourceId: Long) : Screen() {
|
||||||
// KMK <--
|
// KMK <--
|
||||||
|
|
||||||
val onClickItem = { manga: Manga ->
|
val onClickItem = { manga: Manga ->
|
||||||
when (manga.source) {
|
navigator.push(
|
||||||
RECOMMENDS_SOURCE -> navigator.push(
|
when (manga.source) {
|
||||||
SourcesScreen(SourcesScreen.SmartSearchConfig(manga.ogTitle)),
|
RECOMMENDS_SOURCE -> SourcesScreen(SourcesScreen.SmartSearchConfig(manga.ogTitle))
|
||||||
)
|
else -> MangaScreen(manga.id, true)
|
||||||
else -> {
|
},
|
||||||
// KMK -->
|
)
|
||||||
scope.launchIO {
|
|
||||||
val localManga = screenModel.networkToLocalManga(manga)
|
|
||||||
navigator.push(
|
|
||||||
// KMK <--
|
|
||||||
MangaScreen(localManga.id, true),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val onLongClickItem = { manga: Manga ->
|
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)
|
RECOMMENDS_SOURCE -> WebViewActivity.newIntent(context, manga.url, title = manga.title).let(context::startActivity)
|
||||||
else -> {
|
else -> {
|
||||||
// KMK -->
|
// KMK -->
|
||||||
scope.launchIO {
|
// Add to favorite
|
||||||
val localManga = screenModel.networkToLocalManga(manga)
|
bulkFavoriteScreenModel.addRemoveManga(
|
||||||
bulkFavoriteScreenModel.addRemoveManga(
|
manga,
|
||||||
localManga,
|
haptic,
|
||||||
haptic,
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
// KMK <--
|
// KMK <--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ open class RecommendsScreenModel(
|
||||||
val mangaId: Long,
|
val mangaId: Long,
|
||||||
val sourceId: Long,
|
val sourceId: Long,
|
||||||
private val getManga: GetManga = Injekt.get(),
|
private val getManga: GetManga = Injekt.get(),
|
||||||
val networkToLocalManga: NetworkToLocalManga = Injekt.get(),
|
protected val networkToLocalManga: NetworkToLocalManga = Injekt.get(),
|
||||||
) : StateScreenModel<RecommendsScreenModel.State>(State()) {
|
) : StateScreenModel<RecommendsScreenModel.State>(State()) {
|
||||||
|
|
||||||
// KMK -->
|
// KMK -->
|
||||||
|
|
@ -78,14 +78,14 @@ open class RecommendsScreenModel(
|
||||||
}
|
}
|
||||||
|
|
||||||
val recSourceId = recSource.associatedSourceId
|
val recSourceId = recSource.associatedSourceId
|
||||||
// KMK -->
|
val titles = if (recSourceId != null) {
|
||||||
val titles = page.mangas.map {
|
|
||||||
// If the recommendation is associated with a source, resolve it
|
// 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
|
// 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 }
|
.distinctBy { it.url }
|
||||||
|
|
||||||
if (isActive) {
|
if (isActive) {
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ class MangaRepositoryImpl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun insertNetworkManga(manga: List<Manga>): List<Manga> {
|
override suspend fun insertNetworkManga(manga: List<Manga>, updateInfo: Boolean): List<Manga> {
|
||||||
return handler.await(inTransaction = true) {
|
return handler.await(inTransaction = true) {
|
||||||
manga.map {
|
manga.map {
|
||||||
mangasQueries.insertNetworkManga(
|
mangasQueries.insertNetworkManga(
|
||||||
|
|
@ -150,10 +150,10 @@ class MangaRepositoryImpl(
|
||||||
// SY <--
|
// SY <--
|
||||||
updateDetails = it.initialized,
|
updateDetails = it.initialized,
|
||||||
// KMK -->
|
// KMK -->
|
||||||
// mapper = MangaMapper::mapManga,
|
updateInfo = updateInfo,
|
||||||
)
|
|
||||||
mangasQueries.getMangaByUrlAndSource(it.url, it.source, MangaMapper::mapManga)
|
|
||||||
// KMK <--
|
// KMK <--
|
||||||
|
mapper = MangaMapper::mapManga,
|
||||||
|
)
|
||||||
.executeAsOne()
|
.executeAsOne()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ abstract class EHentaiPagingSource(
|
||||||
val manga = mangasPage.mangas
|
val manga = mangasPage.mangas
|
||||||
.mapIndexed { index, sManga -> sManga.toDomainManga(source.id) to metadata.getOrNull(index) }
|
.mapIndexed { index, sManga -> sManga.toDomainManga(source.id) to metadata.getOrNull(index) }
|
||||||
.filter { seenManga.add(it.first.url) }
|
.filter { seenManga.add(it.first.url) }
|
||||||
// KMK -->
|
// KMK -->
|
||||||
// .let { pairs -> pairs.zip(networkToLocalManga(pairs.map { it.first })).map { it.second to it.first.second } }
|
.let { pairs -> networkToLocalManga(pairs.map { it.first }).zip(pairs.map { it.second }) }
|
||||||
// KMK <--
|
// KMK <--
|
||||||
|
|
||||||
return LoadResult.Page(
|
return LoadResult.Page(
|
||||||
|
|
|
||||||
|
|
@ -94,8 +94,8 @@ abstract class BaseSourcePagingSource(
|
||||||
// SY -->
|
// SY -->
|
||||||
.mapIndexed { index, sManga -> sManga.toDomainManga(source!!.id) to metadata.getOrNull(index) }
|
.mapIndexed { index, sManga -> sManga.toDomainManga(source!!.id) to metadata.getOrNull(index) }
|
||||||
.filter { seenManga.add(it.first.url) }
|
.filter { seenManga.add(it.first.url) }
|
||||||
// KMK -->
|
// KMK -->
|
||||||
// .let { pairs -> pairs.zip(networkToLocalManga(pairs.map { it.first })).map { it.second to it.first.second } }
|
.let { pairs -> networkToLocalManga(pairs.map { it.first }).zip(pairs.map { it.second }) }
|
||||||
// KMK <--
|
// KMK <--
|
||||||
// SY <--
|
// SY <--
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -242,17 +242,16 @@ insertNetworkManga {
|
||||||
status = CASE WHEN :updateDetails THEN :status ELSE status END,
|
status = CASE WHEN :updateDetails THEN :status ELSE status END,
|
||||||
update_strategy = CASE WHEN :updateDetails THEN :updateStrategy ELSE update_strategy END,
|
update_strategy = CASE WHEN :updateDetails THEN :updateStrategy ELSE update_strategy END,
|
||||||
initialized = :updateDetails
|
initialized = :updateDetails
|
||||||
WHERE source = :source
|
WHERE source = :source AND :updateInfo
|
||||||
AND url = :url
|
AND url = :url
|
||||||
AND favorite = 0;
|
AND favorite = 0;
|
||||||
|
|
||||||
-- KMK : Disabled the following SELECT as it will cause `getMangaByUrlAndSource` flow not triggered
|
-- Finally return the manga
|
||||||
-- -- Finally return the manga
|
SELECT *
|
||||||
-- SELECT *
|
FROM mangas
|
||||||
-- FROM mangas
|
WHERE source = :source
|
||||||
-- WHERE source = :source
|
AND url = :url
|
||||||
-- AND url = :url
|
LIMIT 1;
|
||||||
-- LIMIT 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getEhMangaWithMetadata:
|
getEhMangaWithMetadata:
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,11 @@ class NetworkToLocalManga(
|
||||||
private val mangaRepository: MangaRepository,
|
private val mangaRepository: MangaRepository,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend operator fun invoke(manga: Manga): Manga {
|
suspend operator fun invoke(manga: Manga, updateInfo: Boolean = true): Manga {
|
||||||
return if (manga.id <= 0) invoke(listOf(manga)).single() else manga
|
return invoke(listOf(manga), updateInfo).single()
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend operator fun invoke(manga: List<Manga>): List<Manga> {
|
suspend operator fun invoke(manga: List<Manga>, updateInfo: Boolean = true): List<Manga> {
|
||||||
return mangaRepository.insertNetworkManga(manga)
|
return mangaRepository.insertNetworkManga(manga, updateInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ interface MangaRepository {
|
||||||
|
|
||||||
suspend fun updateAll(mangaUpdates: List<MangaUpdate>): Boolean
|
suspend fun updateAll(mangaUpdates: List<MangaUpdate>): Boolean
|
||||||
|
|
||||||
suspend fun insertNetworkManga(manga: List<Manga>): List<Manga>
|
suspend fun insertNetworkManga(manga: List<Manga>, updateInfo: Boolean = true): List<Manga>
|
||||||
|
|
||||||
// SY -->
|
// SY -->
|
||||||
suspend fun getMangaBySourceId(sourceId: Long): List<Manga>
|
suspend fun getMangaBySourceId(sourceId: Long): List<Manga>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue