[Comick] Cover setting and Score on Description (#18984)
* Add Score to the description
Add option to keep the first cover
* Check to prevent the extra call
* Swap from ★☆ to ●◐○ to make use of the half-symbol
Because the half-star character (⯪) is too new and doesn't show up properly
* Missing Override
* Back to the stars on rating.
No half-symbols but makes more sense and is consistent with the site's usage of the ⭐ star emoji
This commit is contained in:
parent
fb7c211c36
commit
bdc0ea4d06
@ -6,7 +6,7 @@ ext {
|
||||
extName = 'Comick'
|
||||
pkgNameSuffix = 'all.comickfun'
|
||||
extClass = '.ComickFunFactory'
|
||||
extVersionCode = 38
|
||||
extVersionCode = 39
|
||||
isNsfw = true
|
||||
}
|
||||
|
||||
|
@ -82,6 +82,20 @@ abstract class ComickFun(
|
||||
.commit()
|
||||
}
|
||||
}.also(screen::addPreference)
|
||||
|
||||
SwitchPreferenceCompat(screen.context).apply {
|
||||
key = FIRST_COVER_PREF
|
||||
title = "Update Covers"
|
||||
summaryOff = "Prefer first cover"
|
||||
summaryOn = "Keep cover updated"
|
||||
setDefaultValue(FIRST_COVER_DEFAULT)
|
||||
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
preferences.edit()
|
||||
.putBoolean(FIRST_COVER_PREF, newValue as Boolean)
|
||||
.commit()
|
||||
}
|
||||
}.also(screen::addPreference)
|
||||
}
|
||||
|
||||
private val SharedPreferences.ignoredGroups: Set<String>
|
||||
@ -97,6 +111,9 @@ abstract class ComickFun(
|
||||
private val SharedPreferences.includeMuTags: Boolean
|
||||
get() = getBoolean(INCLUDE_MU_TAGS_PREF, INCLUDE_MU_TAGS_DEFAULT)
|
||||
|
||||
private val SharedPreferences.updateCover: Boolean
|
||||
get() = getBoolean(FIRST_COVER_PREF, FIRST_COVER_DEFAULT)
|
||||
|
||||
init {
|
||||
preferences.newLineIgnoredGroups()
|
||||
}
|
||||
@ -283,8 +300,37 @@ abstract class ComickFun(
|
||||
return GET("$apiUrl$mangaUrl?tachiyomi=true", headers)
|
||||
}
|
||||
|
||||
override fun mangaDetailsParse(response: Response): SManga {
|
||||
override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
|
||||
return client.newCall(mangaDetailsRequest(manga))
|
||||
.asObservableSuccess()
|
||||
.map { response ->
|
||||
mangaDetailsParse(response, manga).apply { initialized = true }
|
||||
}
|
||||
}
|
||||
|
||||
override fun mangaDetailsParse(response: Response): SManga =
|
||||
mangaDetailsParse(response, SManga.create())
|
||||
|
||||
private fun mangaDetailsParse(response: Response, manga: SManga): SManga {
|
||||
val mangaData = response.parseAs<Manga>()
|
||||
if (!preferences.updateCover && manga.thumbnail_url != mangaData.comic.cover) {
|
||||
if (manga.thumbnail_url.toString().endsWith("#")) {
|
||||
return mangaData.toSManga(
|
||||
includeMuTags = preferences.includeMuTags,
|
||||
covers = listOf(
|
||||
MDcovers(
|
||||
b2key = manga.thumbnail_url?.removeSuffix("#")
|
||||
?.substringAfterLast("/"),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
val coversUrl =
|
||||
"$apiUrl/comic/${mangaData.comic.slug ?: mangaData.comic.hid}/covers?tachiyomi=true"
|
||||
val covers = client.newCall(GET(coversUrl)).execute()
|
||||
.parseAs<Covers>().md_covers.reversed()
|
||||
return mangaData.toSManga(includeMuTags = preferences.includeMuTags, covers = covers)
|
||||
}
|
||||
return mangaData.toSManga(includeMuTags = preferences.includeMuTags)
|
||||
}
|
||||
|
||||
@ -392,6 +438,8 @@ abstract class ComickFun(
|
||||
private const val INCLUDE_MU_TAGS_PREF = "IncludeMangaUpdatesTags"
|
||||
private const val INCLUDE_MU_TAGS_DEFAULT = false
|
||||
private const val MIGRATED_IGNORED_GROUPS = "MigratedIgnoredGroups"
|
||||
private const val FIRST_COVER_PREF = "DefaultCover"
|
||||
private const val FIRST_COVER_DEFAULT = true
|
||||
private const val limit = 20
|
||||
val dateFormat by lazy {
|
||||
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH).apply {
|
||||
|
@ -4,6 +4,8 @@ import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.math.BigDecimal
|
||||
import java.math.RoundingMode
|
||||
|
||||
@Serializable
|
||||
data class SearchManga(
|
||||
@ -29,41 +31,57 @@ data class Manga(
|
||||
val genres: List<Name> = emptyList(),
|
||||
val demographic: String? = null,
|
||||
) {
|
||||
fun toSManga(includeMuTags: Boolean = false) = SManga.create().apply {
|
||||
// appennding # at end as part of migration from slug to hid
|
||||
url = "/comic/${comic.hid}#"
|
||||
title = comic.title
|
||||
description = comic.desc?.beautifyDescription()
|
||||
if (comic.altTitles.isNotEmpty()) {
|
||||
if (description.isNullOrEmpty()) {
|
||||
description = "Alternative Titles:\n"
|
||||
} else {
|
||||
description += "\n\nAlternative Titles:\n"
|
||||
}
|
||||
|
||||
description += comic.altTitles.mapNotNull { title ->
|
||||
title.title?.let { "• $it" }
|
||||
}.joinToString("\n")
|
||||
}
|
||||
status = comic.status.parseStatus(comic.translationComplete)
|
||||
thumbnail_url = parseCover(comic.cover, comic.mdCovers)
|
||||
artist = artists.joinToString { it.name.trim() }
|
||||
author = authors.joinToString { it.name.trim() }
|
||||
genre = buildList {
|
||||
comic.origination?.let(::add)
|
||||
demographic?.let { add(Name(it)) }
|
||||
addAll(genres)
|
||||
addAll(comic.mdGenres.mapNotNull { it.name })
|
||||
if (includeMuTags) {
|
||||
comic.muGenres.categories.forEach { category ->
|
||||
category?.category?.title?.let { add(Name(it)) }
|
||||
fun toSManga(includeMuTags: Boolean = false, covers: List<MDcovers>? = null) =
|
||||
SManga.create().apply {
|
||||
// appennding # at end as part of migration from slug to hid
|
||||
url = "/comic/${comic.hid}#"
|
||||
title = comic.title
|
||||
description = buildString {
|
||||
if (!comic.score.isNullOrEmpty()) {
|
||||
val stars = comic.score.toBigDecimal().div(BigDecimal(2))
|
||||
.setScale(0, RoundingMode.HALF_UP).toInt()
|
||||
append("★".repeat(stars))
|
||||
if (stars < 5) append("☆".repeat(5 - stars))
|
||||
append(" ${comic.score} ")
|
||||
}
|
||||
val desc = comic.desc?.beautifyDescription()
|
||||
if (!desc.isNullOrEmpty()) {
|
||||
if (this.isNotEmpty()) append("\n\n")
|
||||
append(desc)
|
||||
}
|
||||
if (comic.altTitles.isNotEmpty()) {
|
||||
if (this.isNotEmpty()) append("\n\n")
|
||||
append("Alternative Titles:\n")
|
||||
append(
|
||||
comic.altTitles.mapNotNull { title ->
|
||||
title.title?.let { "• $it" }
|
||||
}.joinToString("\n"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
status = comic.status.parseStatus(comic.translationComplete)
|
||||
thumbnail_url = parseCover(
|
||||
comic.cover,
|
||||
covers ?: comic.mdCovers,
|
||||
)
|
||||
artist = artists.joinToString { it.name.trim() }
|
||||
author = authors.joinToString { it.name.trim() }
|
||||
genre = buildList {
|
||||
comic.origination?.let(::add)
|
||||
demographic?.let { add(Name(it)) }
|
||||
addAll(genres)
|
||||
addAll(comic.mdGenres.mapNotNull { it.name })
|
||||
if (includeMuTags) {
|
||||
comic.muGenres.categories.forEach { category ->
|
||||
category?.category?.title?.let { add(Name(it)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
.distinctBy { it.name }
|
||||
.filter { it.name.isNotBlank() }
|
||||
.joinToString { it.name.trim() }
|
||||
}
|
||||
.distinctBy { it.name }
|
||||
.filter { it.name.isNotBlank() }
|
||||
.joinToString { it.name.trim() }
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
@ -71,6 +89,7 @@ data class Comic(
|
||||
val hid: String,
|
||||
val title: String,
|
||||
val country: String? = null,
|
||||
val slug: String? = null,
|
||||
@SerialName("md_titles") val altTitles: List<Title> = emptyList(),
|
||||
val desc: String? = null,
|
||||
val status: Int? = 0,
|
||||
@ -79,6 +98,7 @@ data class Comic(
|
||||
@SerialName("cover_url") val cover: String? = null,
|
||||
@SerialName("md_comic_md_genres") val mdGenres: List<MdGenres>,
|
||||
@SerialName("mu_comics") val muGenres: MuComicCategories = MuComicCategories(emptyList()),
|
||||
@SerialName("bayesian_rating") val score: String? = null,
|
||||
) {
|
||||
val origination = when (country) {
|
||||
"jp" -> Name("Manga")
|
||||
@ -103,6 +123,11 @@ data class MuCategories(
|
||||
@SerialName("mu_categories") val category: Title? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Covers(
|
||||
val md_covers: List<MDcovers> = emptyList(),
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class MDcovers(
|
||||
val b2key: String?,
|
||||
|
@ -38,7 +38,7 @@ internal fun parseCover(thumbnailUrl: String?, mdCovers: List<MDcovers>): String
|
||||
val b2key = mdCovers.firstOrNull()?.b2key
|
||||
?: return thumbnailUrl
|
||||
|
||||
return thumbnailUrl?.let { "$it#$b2key" }
|
||||
return thumbnailUrl?.replaceAfterLast("/", "$b2key#")
|
||||
}
|
||||
|
||||
internal fun thumbnailIntercept(chain: Interceptor.Chain): Response {
|
||||
|
Loading…
x
Reference in New Issue
Block a user