diff --git a/app/src/main/java/exh/md/similar/MangaDexSimilarPagingSource.kt b/app/src/main/java/exh/md/similar/MangaDexSimilarPagingSource.kt index 7458ecfc2..d873ee410 100644 --- a/app/src/main/java/exh/md/similar/MangaDexSimilarPagingSource.kt +++ b/app/src/main/java/exh/md/similar/MangaDexSimilarPagingSource.kt @@ -2,24 +2,37 @@ package exh.md.similar import dev.icerock.moko.resources.StringResource import eu.kanade.domain.manga.model.toSManga +import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.MetadataMangasPage -import eu.kanade.tachiyomi.source.online.all.MangaDex +import exh.md.handlers.SimilarHandler +import exh.md.service.MangaDexService +import exh.md.service.SimilarService +import exh.md.utils.MdLang import exh.recs.sources.RecommendationPagingSource -import exh.source.getMainSource +import exh.recs.sources.SourceCatalogue import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope import tachiyomi.data.source.NoResultsException import tachiyomi.domain.manga.model.Manga import tachiyomi.i18n.sy.SYMR +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get /** * MangaDexSimilarPagingSource inherited from the general Pager. */ -class MangaDexSimilarPagingSource( +internal class MangaDexSimilarPagingSource( manga: Manga, - private val mangaDex: MangaDex, -) : RecommendationPagingSource(mangaDex, manga) { + // KMK --> + private val sourceCatalogue: SourceCatalogue, + // KMK <-- +) : RecommendationPagingSource( + // KMK --> + sourceCatalogue.source, + // KMK <-- + manga, +) { override val name: String get() = "MangaDex" @@ -28,12 +41,40 @@ class MangaDexSimilarPagingSource( get() = SYMR.strings.similar_titles override val associatedSourceId: Long - get() = mangaDex.getMainSource().id + // KMK --> + get() = sourceCatalogue.sourceId + + private val client by lazy { Injekt.get().client } + + private val mdLang by lazy { + sourceCatalogue.source?.lang?.let { lang -> + MdLang.fromExt(lang) + } ?: MdLang.ENGLISH + } + + private val mangadexService by lazy { + MangaDexService(client) + } + private val similarService by lazy { + SimilarService(client) + } + private val similarHandler by lazy { + SimilarHandler(mdLang.lang, mangadexService, similarService) + } + // KMK <-- override suspend fun requestNextPage(currentPage: Int): MangasPage { val mangasPage = coroutineScope { - val similarPageDef = async { mangaDex.getMangaSimilar(manga.toSManga()) } - val relatedPageDef = async { mangaDex.getMangaRelated(manga.toSManga()) } + val similarPageDef = async { + // KMK --> + similarHandler.getSimilar(manga.toSManga()) + // KMK <-- + } + val relatedPageDef = async { + // KMK --> + similarHandler.getRelated(manga.toSManga()) + // KMK <-- + } val similarPage = similarPageDef.await() val relatedPage = relatedPageDef.await() diff --git a/app/src/main/java/exh/recs/BrowseRecommendsScreenModel.kt b/app/src/main/java/exh/recs/BrowseRecommendsScreenModel.kt index c4c08c549..4f8e73922 100644 --- a/app/src/main/java/exh/recs/BrowseRecommendsScreenModel.kt +++ b/app/src/main/java/exh/recs/BrowseRecommendsScreenModel.kt @@ -1,13 +1,12 @@ package exh.recs -import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel import exh.recs.sources.RecommendationPagingSource +import exh.recs.sources.SourceCatalogue import kotlinx.coroutines.flow.update import kotlinx.coroutines.runBlocking import tachiyomi.domain.manga.interactor.GetManga -import tachiyomi.domain.source.service.SourceManager import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get @@ -16,23 +15,19 @@ class BrowseRecommendsScreenModel( sourceId: Long, private val recommendationSourceName: String, private val getManga: GetManga = Injekt.get(), - // KMK --> - sourceManager: SourceManager = Injekt.get(), - // KMK <-- ) : BrowseSourceScreenModel(sourceId, null) { val manga = runBlocking { getManga.await(mangaId) }!! // KMK --> - val source_ = sourceManager.get(sourceId) - ?.let { it as CatalogueSource } + private val sourceCatalogue = SourceCatalogue(sourceId) // KMK <-- val recommendationSource: RecommendationPagingSource get() = RecommendationPagingSource.createSources( manga, // KMK --> - source_, + sourceCatalogue, // KMK <-- ).first { it::class.qualifiedName == recommendationSourceName diff --git a/app/src/main/java/exh/recs/RecommendsScreen.kt b/app/src/main/java/exh/recs/RecommendsScreen.kt index 7523da73a..093e0d063 100644 --- a/app/src/main/java/exh/recs/RecommendsScreen.kt +++ b/app/src/main/java/exh/recs/RecommendsScreen.kt @@ -57,7 +57,7 @@ class RecommendsScreen(val mangaId: Long, val sourceId: Long) : Screen() { val onClickItem = { manga: Manga -> when (manga.source) { - -1L -> navigator.push( + RECOMMENDS_SOURCE -> navigator.push( SourcesScreen(SourcesScreen.SmartSearchConfig(manga.ogTitle)), ) else -> { @@ -75,7 +75,7 @@ class RecommendsScreen(val mangaId: Long, val sourceId: Long) : Screen() { val onLongClickItem = { manga: Manga -> when (manga.source) { - -1L -> 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 -> { // KMK --> scope.launchIO { diff --git a/app/src/main/java/exh/recs/RecommendsScreenModel.kt b/app/src/main/java/exh/recs/RecommendsScreenModel.kt index 566e08280..bfeea0290 100644 --- a/app/src/main/java/exh/recs/RecommendsScreenModel.kt +++ b/app/src/main/java/exh/recs/RecommendsScreenModel.kt @@ -6,8 +6,8 @@ import androidx.compose.runtime.produceState import cafe.adriel.voyager.core.model.StateScreenModel import eu.kanade.domain.manga.model.toDomainManga import eu.kanade.presentation.util.ioCoroutineScope -import eu.kanade.tachiyomi.source.CatalogueSource import exh.recs.sources.RecommendationPagingSource +import exh.recs.sources.SourceCatalogue import kotlinx.collections.immutable.PersistentMap import kotlinx.collections.immutable.mutate import kotlinx.collections.immutable.persistentMapOf @@ -25,21 +25,18 @@ import kotlinx.coroutines.withContext import tachiyomi.domain.manga.interactor.GetManga import tachiyomi.domain.manga.interactor.NetworkToLocalManga import tachiyomi.domain.manga.model.Manga -import tachiyomi.domain.source.service.SourceManager import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get open class RecommendsScreenModel( val mangaId: Long, val sourceId: Long, - sourceManager: SourceManager = Injekt.get(), private val getManga: GetManga = Injekt.get(), internal val networkToLocalManga: NetworkToLocalManga = Injekt.get(), ) : StateScreenModel(State()) { - val source = sourceManager.get(sourceId) - // KMK --> - ?.let { it as CatalogueSource } + // KMK --> + private val sourceCatalogue = SourceCatalogue(sourceId) // KMK <-- private val coroutineDispatcher = Dispatchers.IO.limitedParallelism(5) @@ -56,7 +53,12 @@ open class RecommendsScreenModel( ioCoroutineScope.launch { val manga = getManga.await(mangaId)!! mutableState.update { it.copy(manga = manga) } - val recommendationSources = RecommendationPagingSource.createSources(manga, source) + val recommendationSources = RecommendationPagingSource.createSources( + manga, + // KMK --> + sourceCatalogue, + // KMK <-- + ) updateItems( recommendationSources @@ -80,7 +82,7 @@ open class RecommendsScreenModel( // 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 ?: -1) + it.toDomainManga(recSourceId ?: RECOMMENDS_SOURCE) // KMK <-- } @@ -155,3 +157,5 @@ sealed interface RecommendationItemResult { return !onlyShowHasResults || (this is Success && !this.isEmpty) } } + +const val RECOMMENDS_SOURCE = -1L diff --git a/app/src/main/java/exh/recs/sources/ComickPagingSource.kt b/app/src/main/java/exh/recs/sources/ComickPagingSource.kt index 84e9dd960..9674060d2 100644 --- a/app/src/main/java/exh/recs/sources/ComickPagingSource.kt +++ b/app/src/main/java/exh/recs/sources/ComickPagingSource.kt @@ -25,10 +25,17 @@ import uy.kohesive.injekt.injectLazy fun CatalogueSource.isComickSource() = name == "Comick" -class ComickPagingSource( +internal class ComickPagingSource( manga: Manga, - private val comickSource: CatalogueSource, -) : RecommendationPagingSource(comickSource, manga) { + // KMK --> + private val sourceCatalogue: SourceCatalogue, + // KMK <-- +) : RecommendationPagingSource( + // KMK --> + sourceCatalogue.source, + // KMK <-- + manga, +) { override val name: String get() = "Comick" @@ -37,7 +44,9 @@ class ComickPagingSource( get() = SYMR.strings.community_recommendations override val associatedSourceId: Long - get() = comickSource.id + // KMK --> + get() = sourceCatalogue.sourceId + // KMK <-- private val client by lazy { Injekt.get().client } private val json by injectLazy() diff --git a/app/src/main/java/exh/recs/sources/RecommendationPagingSource.kt b/app/src/main/java/exh/recs/sources/RecommendationPagingSource.kt index 11f1439f5..2bbed8000 100644 --- a/app/src/main/java/exh/recs/sources/RecommendationPagingSource.kt +++ b/app/src/main/java/exh/recs/sources/RecommendationPagingSource.kt @@ -6,10 +6,10 @@ import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.SManga -import eu.kanade.tachiyomi.source.online.all.MangaDex import exh.md.similar.MangaDexSimilarPagingSource import exh.pref.DelegateSourcePreferences -import exh.source.getMainSource +import exh.source.COMICK_IDS +import exh.source.MANGADEX_IDS import exh.source.isMdBasedSource import kotlinx.serialization.json.Json import logcat.LogPriority @@ -17,6 +17,7 @@ import tachiyomi.core.common.util.system.logcat import tachiyomi.data.source.NoResultsException import tachiyomi.data.source.SourcePagingSource import tachiyomi.domain.manga.model.Manga +import tachiyomi.domain.source.service.SourceManager import tachiyomi.domain.track.interactor.GetTracks import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get @@ -44,7 +45,15 @@ abstract class RecommendationPagingSource( open val associatedSourceId: Long? = null companion object { - fun createSources(manga: Manga, source: CatalogueSource?): List { + internal fun createSources( + manga: Manga, + // KMK --> + sourceCatalogue: SourceCatalogue, + // KMK <-- + ): List { + // KMK --> + val source = sourceCatalogue.source + // KMK <-- return buildList { add(AniListPagingSource(manga, source)) add(MangaUpdatesCommunityPagingSource(manga, source)) @@ -54,22 +63,36 @@ abstract class RecommendationPagingSource( // Only include MangaDex if the delegate sources are enabled and the source is MD-based if ( // KMK --> - source != null && + sourceCatalogue.isMangaDexSource() || // KMK <-- - source.isMdBasedSource() && + source?.isMdBasedSource() /* KMK --> */ == true /* KMK <-- */ && Injekt.get().delegateSources().get() ) { - add(MangaDexSimilarPagingSource(manga, source.getMainSource() as MangaDex)) + add( + MangaDexSimilarPagingSource( + manga, + // KMK --> + sourceCatalogue, + // KMK <-- + ), + ) } // Only include Comick if the source manga is from there if ( // KMK --> - source != null && + sourceCatalogue.isComickSource() || // KMK <-- - source.isComickSource() + source?.isComickSource() /* KMK --> */ == true /* KMK <-- */ ) { - add(ComickPagingSource(manga, source)) + add( + ComickPagingSource( + manga, + // KMK --> + sourceCatalogue, + // KMK <-- + ), + ) } }.sortedWith(compareBy({ it.name }, { it.category.resourceId })) } @@ -123,3 +146,17 @@ abstract class TrackerRecommendationPagingSource( return MangasPage(recs, false) } } + +// KMK --> +internal class SourceCatalogue( + internal val sourceId: Long, + sourceManager: SourceManager = Injekt.get(), +) { + val source = sourceManager.get(sourceId) + ?.let { it as CatalogueSource } + + fun isComickSource(): Boolean = sourceId in COMICK_IDS + + fun isMangaDexSource(): Boolean = sourceId in MANGADEX_IDS +} +// KMK <-- diff --git a/source-api/src/commonMain/kotlin/exh/source/SourceIds.kt b/source-api/src/commonMain/kotlin/exh/source/SourceIds.kt index 07bf5ceb0..2e68ea2d8 100644 --- a/source-api/src/commonMain/kotlin/exh/source/SourceIds.kt +++ b/source-api/src/commonMain/kotlin/exh/source/SourceIds.kt @@ -14,3 +14,113 @@ const val MERGED_SOURCE_ID = LEWD_SOURCE_SERIES + 69 const val NHENTAI_OLD_ID = 6907L const val TSUMINO_OLD_ID = 6909L const val HBROWSE_OLD_ID = 6912L + +// KMK --> +val COMICK_IDS = setOf( + 982606170401027267, // all + 2971557565147974499, // en + 8729626158695297897, // pt-BR + 5846182885417171581, // ru + 9126078936214680667, // fr + 3182432228546767958, // es-419 + 7005108854993254607, // pl + 7186425300860782365, // tr + 8807318985460553537, // it + 9052019484488287695, // es + 5506707690027487154, // id + 7838940669485160901, // hu + 9191587139933034493, // vi + 3140511316190656180, // zh-Hant + 8266599095155001097, // ar + 7552236568334706863, // de + 1071494508319622063, // zh-Hans + 2159382907508433047, // ca + 8981320463367739957, // bg + 4246541831082737053, // th + 3146252372540608964, // fa + 3505068018066717349, // uk + 2147260678391898600, // mn + 6676949771764486043, // ro + 5354540502202034685, // he + 4731643595200952045, // ms + 8549617092958820123, // tl + 8288710818308434509, // ja + 5176570178081213805, // hi + 9199495862098963317, // my + 3493720175703105662, // ko + 2651978322082769022, // cs + 4153491877797434408, // pt + 6104206360977276112, // nl + 979314012722687145, // sv + 3598159956413889411, // bn + 5932005504194733317, // no + 1792260331167396074, // lt + 6190162673651111756, // el + 571668187470919545, // sr + 7137437402245830147, // da +) + +val MANGADEX_IDS = setOf( + 2499283573021220255, // en + 4638673959522768501, // af + 987803387023224960, // sq + 3339599426223341161, // ar + 9127464796236242233, // az + 1553736397938752611, // eu + 3601180820582582605, // be + 4150470519566206911, // bn + 5463447640980279236, // bg + 1347402746269051958, // my + 5860541308324630662, // ca + 5148895169070562838, // zh-Hans + 1493666528525752601, // zh-Hant + 2072928884077964642, // cv + 8548374501079910130, // hr + 3578612018159256808, // cs + 425785191804166217, // da + 6750440049024086587, // nl + 2819252027406613931, // eo + 8773024089257004344, // et + 8578871918181236609, // fil + 8254121249433835847, // fi + 4505830566611664829, // fr + 8952567078513962586, // ka + 5098537545549490547, // de + 3260701926561129943, // el + 1424273154577029558, // he + 6840513937945146538, // hi + 4284949320785450865, // hu + 3686775439235747344, // ga + 3807502156582598786, // id + 1952071260038453057, // it + 1573550798452063564, // jv + 1411768577036936240, // ja + 8884149958776527952, // kk + 3285208643537017688, // ko + 764587568075398530, // la + 737986167355114438, // lt + 1471784905273036181, // ms + 5967745367608513818, // mn + 954368055061084457, // ne + 4872213291993424667, // no + 3781216447842245147, // fa + 8033579885162383068, // pl + 2655149515337070132, // pt-BR + 5189216366882819742, // pt + 4774459486579224459, // ro + 2098905203823335614, // ru + 3507378005483435886, // sr + 2875503798326600410, // sk + 4938773340256184018, // es-419 + 6400665728063187402, // es + 1145824452519314725, // sv + 4273071356706429527, // ta + 6886894829142702925, // te + 1713554459881080228, // th + 3846770256925560569, // tr + 5779037855201976894, // uk + 72800122520214493, // ur + 2838715564514827672, // uz + 9194073792736219759, // vi +) +// KMK <--