Show Mangadex relations in Mangadex similar
This commit is contained in:
parent
87d9512b1f
commit
77f5acf2dd
@ -9,6 +9,7 @@ import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.data.track.mdlist.MdList
|
||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||
import eu.kanade.tachiyomi.source.model.MetadataMangasPage
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
@ -284,10 +285,14 @@ class MangaDex(delegate: HttpSource, val context: Context) :
|
||||
return mangaHandler.fetchRandomMangaId()
|
||||
}
|
||||
|
||||
suspend fun getMangaSimilar(manga: MangaInfo): MangasPage {
|
||||
suspend fun getMangaSimilar(manga: MangaInfo): MetadataMangasPage {
|
||||
return similarHandler.getSimilar(manga)
|
||||
}
|
||||
|
||||
suspend fun getMangaRelated(manga: MangaInfo): MetadataMangasPage {
|
||||
return similarHandler.getRelated(manga)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val dataSaverPref = "dataSaverV5"
|
||||
|
||||
|
@ -61,6 +61,10 @@ class SourceComfortableGridHolder(private val view: View, private val adapter: F
|
||||
binding.badges.localText.text = itemView.context.resources.getStringArray(R.array.md_follows_options).asList()[it]
|
||||
binding.badges.localText.isVisible = true
|
||||
}
|
||||
metadata.relation?.let {
|
||||
binding.badges.localText.setText(it.resId)
|
||||
binding.badges.localText.isVisible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
// SY <--
|
||||
|
@ -58,6 +58,10 @@ open class SourceCompactGridHolder(private val view: View, private val adapter:
|
||||
binding.badges.localText.text = itemView.context.resources.getStringArray(R.array.md_follows_options).asList()[it]
|
||||
binding.badges.localText.isVisible = true
|
||||
}
|
||||
metadata.relation?.let {
|
||||
binding.badges.localText.setText(it.resId)
|
||||
binding.badges.localText.isVisible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
// SY <--
|
||||
|
@ -58,6 +58,10 @@ class SourceListHolder(private val view: View, adapter: FlexibleAdapter<*>) :
|
||||
binding.localText.text = itemView.context.resources.getStringArray(R.array.md_follows_options).asList()[it]
|
||||
binding.localText.isVisible = true
|
||||
}
|
||||
metadata.relation?.let {
|
||||
binding.localText.setText(it.resId)
|
||||
binding.localText.isVisible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
// SY <--
|
||||
|
@ -18,3 +18,25 @@ data class SimilarMangaMatchListDto(
|
||||
val contentRating: String,
|
||||
val score: Double,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class RelationListDto(
|
||||
val response: String,
|
||||
val data: List<RelationDto>,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class RelationDto(
|
||||
val attributes: RelationAttributesDto,
|
||||
val relationships: List<RelationMangaDto>,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class RelationMangaDto(
|
||||
val id: String
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class RelationAttributesDto(
|
||||
val relation: String,
|
||||
)
|
||||
|
@ -1,11 +1,15 @@
|
||||
package exh.md.handlers
|
||||
|
||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||
import eu.kanade.tachiyomi.source.model.MetadataMangasPage
|
||||
import eu.kanade.tachiyomi.source.model.toSManga
|
||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||
import exh.md.dto.RelationListDto
|
||||
import exh.md.dto.SimilarMangaDto
|
||||
import exh.md.service.MangaDexService
|
||||
import exh.md.service.SimilarService
|
||||
import exh.md.utils.MangaDexRelation
|
||||
import exh.md.utils.MdUtil
|
||||
import exh.metadata.metadata.MangaDexSearchMetadata
|
||||
import tachiyomi.source.model.MangaInfo
|
||||
|
||||
class SimilarHandler(
|
||||
@ -14,14 +18,14 @@ class SimilarHandler(
|
||||
private val similarService: SimilarService
|
||||
) {
|
||||
|
||||
suspend fun getSimilar(manga: MangaInfo): MangasPage {
|
||||
val similarDto = similarService.getSimilarManga(MdUtil.getMangaId(manga.key))
|
||||
suspend fun getSimilar(manga: MangaInfo): MetadataMangasPage {
|
||||
val similarDto = withIOContext { similarService.getSimilarManga(MdUtil.getMangaId(manga.key)) }
|
||||
return similarDtoToMangaListPage(similarDto)
|
||||
}
|
||||
|
||||
private suspend fun similarDtoToMangaListPage(
|
||||
similarMangaDto: SimilarMangaDto,
|
||||
): MangasPage {
|
||||
): MetadataMangasPage {
|
||||
val ids = similarMangaDto.matches.map {
|
||||
it.id
|
||||
}
|
||||
@ -30,6 +34,34 @@ class SimilarHandler(
|
||||
MdUtil.createMangaEntry(it, lang).toSManga()
|
||||
}
|
||||
|
||||
return MangasPage(mangaList, false)
|
||||
return MetadataMangasPage(mangaList, false, List(mangaList.size) { MangaDexSearchMetadata().also { it.relation = MangaDexRelation.SIMILAR } })
|
||||
}
|
||||
|
||||
suspend fun getRelated(manga: MangaInfo): MetadataMangasPage {
|
||||
val relatedListDto = withIOContext { service.relatedManga(MdUtil.getMangaId(manga.key)) }
|
||||
return relatedDtoToMangaListPage(relatedListDto)
|
||||
}
|
||||
|
||||
private suspend fun relatedDtoToMangaListPage(
|
||||
relatedListDto: RelationListDto,
|
||||
): MetadataMangasPage {
|
||||
val ids = relatedListDto.data
|
||||
.mapNotNull { it.relationships.firstOrNull() }
|
||||
.map { it.id }
|
||||
|
||||
val mangaList = service.viewMangas(ids).data.map {
|
||||
MdUtil.createMangaEntry(it, lang).toSManga()
|
||||
}
|
||||
|
||||
return MetadataMangasPage(
|
||||
mangas = mangaList,
|
||||
hasNextPage = false,
|
||||
mangasMetadata = mangaList.map { manga ->
|
||||
MangaDexSearchMetadata().also {
|
||||
it.relation = relatedListDto.data.firstOrNull { it.relationships.any { it.id == MdUtil.getMangaId(manga.url) } }
|
||||
?.attributes?.relation?.let(MangaDexRelation::fromDex)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import exh.md.dto.ChapterDto
|
||||
import exh.md.dto.ChapterListDto
|
||||
import exh.md.dto.MangaDto
|
||||
import exh.md.dto.MangaListDto
|
||||
import exh.md.dto.RelationListDto
|
||||
import exh.md.dto.ResultDto
|
||||
import exh.md.utils.MdApi
|
||||
import exh.md.utils.MdConstants
|
||||
@ -145,6 +146,21 @@ class MangaDexService(
|
||||
): AtHomeDto {
|
||||
return client.newCall(GET(atHomeRequestUrl, headers, CacheControl.FORCE_NETWORK))
|
||||
.await()
|
||||
.parseAs()
|
||||
.parseAs(MdUtil.jsonParser)
|
||||
}
|
||||
|
||||
suspend fun relatedManga(id: String): RelationListDto {
|
||||
return client.newCall(
|
||||
GET(
|
||||
MdApi.manga.toHttpUrl().newBuilder()
|
||||
.apply {
|
||||
addPathSegment(id)
|
||||
addPathSegment("relation")
|
||||
}
|
||||
.build()
|
||||
.toString(),
|
||||
cache = CacheControl.FORCE_NETWORK
|
||||
)
|
||||
).await().parseAs(MdUtil.jsonParser)
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,12 @@ package exh.md.similar
|
||||
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
|
||||
import eu.kanade.tachiyomi.source.model.MetadataMangasPage
|
||||
import eu.kanade.tachiyomi.source.online.all.MangaDex
|
||||
import eu.kanade.tachiyomi.ui.browse.source.browse.NoResultsException
|
||||
import eu.kanade.tachiyomi.ui.browse.source.browse.Pager
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
|
||||
/**
|
||||
* MangaDexSimilarPager inherited from the general Pager.
|
||||
@ -12,7 +15,18 @@ import eu.kanade.tachiyomi.ui.browse.source.browse.Pager
|
||||
class MangaDexSimilarPager(val manga: Manga, val source: MangaDex) : Pager() {
|
||||
|
||||
override suspend fun requestNextPage() {
|
||||
val mangasPage = source.getMangaSimilar(manga.toMangaInfo())
|
||||
val mangasPage = coroutineScope {
|
||||
val similarPageDef = async { source.getMangaSimilar(manga.toMangaInfo()) }
|
||||
val relatedPageDef = async { source.getMangaRelated(manga.toMangaInfo()) }
|
||||
val similarPage = similarPageDef.await()
|
||||
val relatedPage = relatedPageDef.await()
|
||||
|
||||
MetadataMangasPage(
|
||||
relatedPage.mangas + similarPage.mangas,
|
||||
false,
|
||||
relatedPage.mangasMetadata + similarPage.mangasMetadata
|
||||
)
|
||||
}
|
||||
|
||||
if (mangasPage.mangas.isNotEmpty()) {
|
||||
onPageReceived(mangasPage)
|
||||
|
27
app/src/main/java/exh/md/utils/MangaDexRelation.kt
Normal file
27
app/src/main/java/exh/md/utils/MangaDexRelation.kt
Normal file
@ -0,0 +1,27 @@
|
||||
package exh.md.utils
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import eu.kanade.tachiyomi.R
|
||||
|
||||
enum class MangaDexRelation(@StringRes val resId: Int, val mdString: String?) {
|
||||
SIMILAR(R.string.relation_similar, null),
|
||||
MONOCHROME(R.string.relation_monochrome, "monochrome"),
|
||||
MAIN_STORY(R.string.relation_main_story, "main_story"),
|
||||
ADAPTED_FROM(R.string.relation_adapted_from, "adapted_from"),
|
||||
BASED_ON(R.string.relation_based_on, "based_on"),
|
||||
PREQUEL(R.string.relation_prequel, "prequel"),
|
||||
SIDE_STORY(R.string.relation_side_story, "side_story"),
|
||||
DOUJINSHI(R.string.relation_doujinshi, "doujinshi"),
|
||||
SAME_FRANCHISE(R.string.relation_same_franchise, "same_franchise"),
|
||||
SHARED_UNIVERSE(R.string.relation_shared_universe, "shared_universe"),
|
||||
SEQUEL(R.string.relation_sequel, "sequel"),
|
||||
SPIN_OFF(R.string.relation_spin_off, "spin_off"),
|
||||
ALTERNATE_STORY(R.string.relation_alternate_story, "alternate_story"),
|
||||
PRESERIALIZATION(R.string.relation_preserialization, "preserialization"),
|
||||
COLORED(R.string.relation_colored, "colored"),
|
||||
SERIALIZATION(R.string.relation_serialization, "serialization");
|
||||
|
||||
companion object {
|
||||
fun fromDex(mdString: String) = values().find { it.mdString == mdString }
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package exh.metadata.metadata
|
||||
|
||||
import android.content.Context
|
||||
import eu.kanade.tachiyomi.R
|
||||
import exh.md.utils.MangaDexRelation
|
||||
import exh.md.utils.MdUtil
|
||||
import exh.metadata.metadata.base.RaisedSearchMetadata
|
||||
import kotlinx.serialization.Serializable
|
||||
@ -40,6 +41,7 @@ class MangaDexSearchMetadata : RaisedSearchMetadata() {
|
||||
// var missing_chapters: String? = null
|
||||
|
||||
var followStatus: Int? = null
|
||||
var relation: MangaDexRelation? = null
|
||||
|
||||
// var maxChapterNumber: Int? = null
|
||||
|
||||
|
@ -669,6 +669,24 @@
|
||||
<!-- Similar -->
|
||||
<string name="similar">Similar to %1$s</string>
|
||||
<string name="similar_no_results">No Similar Manga found</string>
|
||||
|
||||
<!-- Mangadex relations-->
|
||||
<string name="relation_similar">Similar</string>
|
||||
<string name="relation_monochrome">Monochrome</string>
|
||||
<string name="relation_main_story">Main story</string>
|
||||
<string name="relation_adapted_from">Adapted from</string>
|
||||
<string name="relation_based_on">Based on</string>
|
||||
<string name="relation_prequel">Prequel</string>
|
||||
<string name="relation_side_story">Side story</string>
|
||||
<string name="relation_doujinshi">Doujinshi</string>
|
||||
<string name="relation_same_franchise">Same franchise</string>
|
||||
<string name="relation_shared_universe">Shared universe</string>
|
||||
<string name="relation_sequel">Sequel</string>
|
||||
<string name="relation_spin_off">Spin-off</string>
|
||||
<string name="relation_alternate_story">Alternate story</string>
|
||||
<string name="relation_preserialization">Pre-serialization</string>
|
||||
<string name="relation_colored">Colored</string>
|
||||
<string name="relation_serialization">Serialization</string>
|
||||
|
||||
<!-- Humanize time -->
|
||||
<plurals name="humanize_year">
|
||||
|
Loading…
x
Reference in New Issue
Block a user