Support RecommendsScreen even if MangaDex/Comick is not installed
This commit is contained in:
parent
343cd3727c
commit
c7c76d22dd
7 changed files with 235 additions and 39 deletions
|
|
@ -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<NetworkHelper>().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()
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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<RecommendsScreenModel.State>(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
|
||||
|
|
|
|||
|
|
@ -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<NetworkHelper>().client }
|
||||
private val json by injectLazy<Json>()
|
||||
|
|
|
|||
|
|
@ -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<RecommendationPagingSource> {
|
||||
internal fun createSources(
|
||||
manga: Manga,
|
||||
// KMK -->
|
||||
sourceCatalogue: SourceCatalogue,
|
||||
// KMK <--
|
||||
): List<RecommendationPagingSource> {
|
||||
// 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<DelegateSourcePreferences>().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 <--
|
||||
|
|
|
|||
|
|
@ -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 <--
|
||||
|
|
|
|||
Loading…
Reference in a new issue