Comick: Comick: Added Exclude Tags Filter, Fixed Demographic Type, Added "None" / "Others" Filter, Added Content Rating Filter (#8049)
* Added Exclude Tags Filter * Added None Demographic & Other Type. Switched DemographicFilter from TriFilter -> CheckBoxFilter (API Doesn't support it) & switched it.isIncluded() -> it.state * Added Content Rating Filter * Added extension setting to hide/show alternative titles. * Extracted duplicate tags code into a function.
This commit is contained in:
parent
7154880810
commit
ddf63bf592
@ -1,5 +1,8 @@
|
|||||||
ignored_groups_title=Ignored Groups
|
ignored_groups_title=Ignored Groups
|
||||||
ignored_groups_summary=Chapters from these groups won't be shown.\nOne group name per line (case-insensitive)
|
ignored_groups_summary=Chapters from these groups won't be shown.\nOne group name per line (case-insensitive)
|
||||||
|
show_alternative_titles_title=Show Alternative Titles
|
||||||
|
show_alternative_titles_on=Adds alternative titles to the description
|
||||||
|
show_alternative_titles_off=Does not show alternative titles to the description
|
||||||
include_tags_title=Include Tags
|
include_tags_title=Include Tags
|
||||||
include_tags_on=More specific, but might contain spoilers!
|
include_tags_on=More specific, but might contain spoilers!
|
||||||
include_tags_off=Only the broader genres
|
include_tags_off=Only the broader genres
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
ignored_groups_title=Grupos Ignorados
|
ignored_groups_title=Grupos Ignorados
|
||||||
ignored_groups_summary=Capítulos desses grupos não aparecerão.\nUm grupo por linha
|
ignored_groups_summary=Capítulos desses grupos não aparecerão.\nUm grupo por linha
|
||||||
|
show_alternative_titles_title=Mostrar Títulos Alternativos
|
||||||
|
show_alternative_titles_on=Adiciona títulos alternativos à descrição
|
||||||
|
show_alternative_titles_off=Não mostra títulos alternativos na descrição
|
||||||
include_tags_title=Incluir Tags
|
include_tags_title=Incluir Tags
|
||||||
include_tags_on=Mais detalhadas, mas podem conter spoilers
|
include_tags_on=Mais detalhadas, mas podem conter spoilers
|
||||||
include_tags_off=Apenas os gêneros básicos
|
include_tags_off=Apenas os gêneros básicos
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
ext {
|
ext {
|
||||||
extName = 'Comick'
|
extName = 'Comick'
|
||||||
extClass = '.ComickFactory'
|
extClass = '.ComickFactory'
|
||||||
extVersionCode = 53
|
extVersionCode = 54
|
||||||
isNsfw = true
|
isNsfw = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ import keiyoushi.utils.getPreferencesLazy
|
|||||||
import kotlinx.serialization.decodeFromString
|
import kotlinx.serialization.decodeFromString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
|
import okhttp3.HttpUrl.Builder
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
@ -78,6 +79,20 @@ abstract class Comick(
|
|||||||
}
|
}
|
||||||
}.also(screen::addPreference)
|
}.also(screen::addPreference)
|
||||||
|
|
||||||
|
SwitchPreferenceCompat(screen.context).apply {
|
||||||
|
key = SHOW_ALTERNATIVE_TITLES_PREF
|
||||||
|
title = intl["show_alternative_titles_title"]
|
||||||
|
summaryOn = intl["show_alternative_titles_on"]
|
||||||
|
summaryOff = intl["show_alternative_titles_off"]
|
||||||
|
setDefaultValue(SHOW_ALTERNATIVE_TITLES_DEFAULT)
|
||||||
|
|
||||||
|
setOnPreferenceChangeListener { _, newValue ->
|
||||||
|
preferences.edit()
|
||||||
|
.putBoolean(SHOW_ALTERNATIVE_TITLES_PREF, newValue as Boolean)
|
||||||
|
.commit()
|
||||||
|
}
|
||||||
|
}.also(screen::addPreference)
|
||||||
|
|
||||||
SwitchPreferenceCompat(screen.context).apply {
|
SwitchPreferenceCompat(screen.context).apply {
|
||||||
key = INCLUDE_MU_TAGS_PREF
|
key = INCLUDE_MU_TAGS_PREF
|
||||||
title = intl["include_tags_title"]
|
title = intl["include_tags_title"]
|
||||||
@ -155,6 +170,9 @@ abstract class Comick(
|
|||||||
.orEmpty()
|
.orEmpty()
|
||||||
.toSet()
|
.toSet()
|
||||||
|
|
||||||
|
private val SharedPreferences.showAlternativeTitles: Boolean
|
||||||
|
get() = getBoolean(SHOW_ALTERNATIVE_TITLES_PREF, SHOW_ALTERNATIVE_TITLES_DEFAULT)
|
||||||
|
|
||||||
private val SharedPreferences.includeMuTags: Boolean
|
private val SharedPreferences.includeMuTags: Boolean
|
||||||
get() = getBoolean(INCLUDE_MU_TAGS_PREF, INCLUDE_MU_TAGS_DEFAULT)
|
get() = getBoolean(INCLUDE_MU_TAGS_PREF, INCLUDE_MU_TAGS_DEFAULT)
|
||||||
|
|
||||||
@ -272,6 +290,16 @@ abstract class Comick(
|
|||||||
return MangasPage(entries, end < searchResponse.size)
|
return MangasPage(entries, end < searchResponse.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun addTagQueryParameters(builder: Builder, tags: String, parameterName: String) {
|
||||||
|
tags.split(",").forEach {
|
||||||
|
builder.addQueryParameter(
|
||||||
|
parameterName,
|
||||||
|
it.trim().lowercase().replace(SPACE_AND_SLASH_REGEX, "-")
|
||||||
|
.replace("'-", "-and-039-").replace("'", "-and-039-"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
val url = "$apiUrl/v1.0/search".toHttpUrl().newBuilder().apply {
|
val url = "$apiUrl/v1.0/search".toHttpUrl().newBuilder().apply {
|
||||||
filters.forEach { it ->
|
filters.forEach { it ->
|
||||||
@ -293,7 +321,7 @@ abstract class Comick(
|
|||||||
}
|
}
|
||||||
|
|
||||||
is DemographicFilter -> {
|
is DemographicFilter -> {
|
||||||
it.state.filter { it.isIncluded() }.forEach {
|
it.state.filter { it.state }.forEach {
|
||||||
addQueryParameter("demographic", it.value)
|
addQueryParameter("demographic", it.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -314,6 +342,12 @@ abstract class Comick(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is ContentRatingFilter -> {
|
||||||
|
if (it.state > 0) {
|
||||||
|
addQueryParameter("content_rating", it.getValue())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
is CreatedAtFilter -> {
|
is CreatedAtFilter -> {
|
||||||
if (it.state > 0) {
|
if (it.state > 0) {
|
||||||
addQueryParameter("time", it.getValue())
|
addQueryParameter("time", it.getValue())
|
||||||
@ -340,14 +374,14 @@ abstract class Comick(
|
|||||||
|
|
||||||
is TagFilter -> {
|
is TagFilter -> {
|
||||||
if (it.state.isNotEmpty()) {
|
if (it.state.isNotEmpty()) {
|
||||||
it.state.split(",").forEach {
|
addTagQueryParameters(this, it.state, "tags")
|
||||||
addQueryParameter(
|
|
||||||
"tags",
|
|
||||||
it.trim().lowercase().replace(SPACE_AND_SLASH_REGEX, "-")
|
|
||||||
.replace("'-", "-and-039-").replace("'", "-and-039-"),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is ExcludedTagFilter -> {
|
||||||
|
if (it.state.isNotEmpty()) {
|
||||||
|
addTagQueryParameters(this, it.state, "excluded-tags")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {}
|
else -> {}
|
||||||
@ -400,6 +434,7 @@ abstract class Comick(
|
|||||||
return mangaData.toSManga(
|
return mangaData.toSManga(
|
||||||
includeMuTags = preferences.includeMuTags,
|
includeMuTags = preferences.includeMuTags,
|
||||||
scorePosition = preferences.scorePosition,
|
scorePosition = preferences.scorePosition,
|
||||||
|
showAlternativeTitles = preferences.showAlternativeTitles,
|
||||||
covers = localCovers.ifEmpty { originalCovers }.ifEmpty { firstVol },
|
covers = localCovers.ifEmpty { originalCovers }.ifEmpty { firstVol },
|
||||||
groupTags = preferences.groupTags,
|
groupTags = preferences.groupTags,
|
||||||
)
|
)
|
||||||
@ -407,6 +442,7 @@ abstract class Comick(
|
|||||||
return mangaData.toSManga(
|
return mangaData.toSManga(
|
||||||
includeMuTags = preferences.includeMuTags,
|
includeMuTags = preferences.includeMuTags,
|
||||||
scorePosition = preferences.scorePosition,
|
scorePosition = preferences.scorePosition,
|
||||||
|
showAlternativeTitles = preferences.showAlternativeTitles,
|
||||||
groupTags = preferences.groupTags,
|
groupTags = preferences.groupTags,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -524,6 +560,8 @@ abstract class Comick(
|
|||||||
const val SLUG_SEARCH_PREFIX = "id:"
|
const val SLUG_SEARCH_PREFIX = "id:"
|
||||||
private val SPACE_AND_SLASH_REGEX = Regex("[ /]")
|
private val SPACE_AND_SLASH_REGEX = Regex("[ /]")
|
||||||
private const val IGNORED_GROUPS_PREF = "IgnoredGroups"
|
private const val IGNORED_GROUPS_PREF = "IgnoredGroups"
|
||||||
|
private const val SHOW_ALTERNATIVE_TITLES_PREF = "ShowAlternativeTitles"
|
||||||
|
const val SHOW_ALTERNATIVE_TITLES_DEFAULT = false
|
||||||
private const val INCLUDE_MU_TAGS_PREF = "IncludeMangaUpdatesTags"
|
private const val INCLUDE_MU_TAGS_PREF = "IncludeMangaUpdatesTags"
|
||||||
const val INCLUDE_MU_TAGS_DEFAULT = false
|
const val INCLUDE_MU_TAGS_DEFAULT = false
|
||||||
private const val GROUP_TAGS_PREF = "GroupTags"
|
private const val GROUP_TAGS_PREF = "GroupTags"
|
||||||
|
@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.extension.all.comickfun
|
|||||||
import eu.kanade.tachiyomi.extension.all.comickfun.Comick.Companion.GROUP_TAGS_DEFAULT
|
import eu.kanade.tachiyomi.extension.all.comickfun.Comick.Companion.GROUP_TAGS_DEFAULT
|
||||||
import eu.kanade.tachiyomi.extension.all.comickfun.Comick.Companion.INCLUDE_MU_TAGS_DEFAULT
|
import eu.kanade.tachiyomi.extension.all.comickfun.Comick.Companion.INCLUDE_MU_TAGS_DEFAULT
|
||||||
import eu.kanade.tachiyomi.extension.all.comickfun.Comick.Companion.SCORE_POSITION_DEFAULT
|
import eu.kanade.tachiyomi.extension.all.comickfun.Comick.Companion.SCORE_POSITION_DEFAULT
|
||||||
|
import eu.kanade.tachiyomi.extension.all.comickfun.Comick.Companion.SHOW_ALTERNATIVE_TITLES_DEFAULT
|
||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
@ -36,6 +37,7 @@ class Manga(
|
|||||||
fun toSManga(
|
fun toSManga(
|
||||||
includeMuTags: Boolean = INCLUDE_MU_TAGS_DEFAULT,
|
includeMuTags: Boolean = INCLUDE_MU_TAGS_DEFAULT,
|
||||||
scorePosition: String = SCORE_POSITION_DEFAULT,
|
scorePosition: String = SCORE_POSITION_DEFAULT,
|
||||||
|
showAlternativeTitles: Boolean = SHOW_ALTERNATIVE_TITLES_DEFAULT,
|
||||||
covers: List<MDcovers>? = null,
|
covers: List<MDcovers>? = null,
|
||||||
groupTags: Boolean = GROUP_TAGS_DEFAULT,
|
groupTags: Boolean = GROUP_TAGS_DEFAULT,
|
||||||
) =
|
) =
|
||||||
@ -54,7 +56,7 @@ class Manga(
|
|||||||
if (this.isNotEmpty()) append("\n\n")
|
if (this.isNotEmpty()) append("\n\n")
|
||||||
append(comic.fancyScore)
|
append(comic.fancyScore)
|
||||||
}
|
}
|
||||||
if (comic.altTitles.isNotEmpty()) {
|
if (showAlternativeTitles && comic.altTitles.isNotEmpty()) {
|
||||||
if (this.isNotEmpty()) append("\n\n")
|
if (this.isNotEmpty()) append("\n\n")
|
||||||
append("Alternative Titles:\n")
|
append("Alternative Titles:\n")
|
||||||
append(
|
append(
|
||||||
|
@ -11,6 +11,7 @@ fun getFilters(): FilterList {
|
|||||||
TypeFilter("Type", getTypeList),
|
TypeFilter("Type", getTypeList),
|
||||||
SortFilter("Sort", getSortsList),
|
SortFilter("Sort", getSortsList),
|
||||||
StatusFilter("Status", getStatusList),
|
StatusFilter("Status", getStatusList),
|
||||||
|
ContentRatingFilter("Content Rating", getContentRatingList),
|
||||||
CompletedFilter("Completely Scanlated?"),
|
CompletedFilter("Completely Scanlated?"),
|
||||||
CreatedAtFilter("Created at", getCreatedAtList),
|
CreatedAtFilter("Created at", getCreatedAtList),
|
||||||
MinimumFilter("Minimum Chapters"),
|
MinimumFilter("Minimum Chapters"),
|
||||||
@ -20,6 +21,7 @@ fun getFilters(): FilterList {
|
|||||||
ToYearFilter("To"),
|
ToYearFilter("To"),
|
||||||
Filter.Header("Separate tags with commas"),
|
Filter.Header("Separate tags with commas"),
|
||||||
TagFilter("Tags"),
|
TagFilter("Tags"),
|
||||||
|
ExcludedTagFilter("Excluded Tags"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,8 +31,10 @@ internal class GenreFilter(name: String, genreList: List<Pair<String, String>>)
|
|||||||
|
|
||||||
internal class TagFilter(name: String) : TextFilter(name)
|
internal class TagFilter(name: String) : TextFilter(name)
|
||||||
|
|
||||||
|
internal class ExcludedTagFilter(name: String) : TextFilter(name)
|
||||||
|
|
||||||
internal class DemographicFilter(name: String, demographicList: List<Pair<String, String>>) :
|
internal class DemographicFilter(name: String, demographicList: List<Pair<String, String>>) :
|
||||||
Filter.Group<TriFilter>(name, demographicList.map { TriFilter(it.first, it.second) })
|
Filter.Group<CheckBoxFilter>(name, demographicList.map { CheckBoxFilter(it.first, it.second) })
|
||||||
|
|
||||||
internal class TypeFilter(name: String, typeList: List<Pair<String, String>>) :
|
internal class TypeFilter(name: String, typeList: List<Pair<String, String>>) :
|
||||||
Filter.Group<CheckBoxFilter>(name, typeList.map { CheckBoxFilter(it.first, it.second) })
|
Filter.Group<CheckBoxFilter>(name, typeList.map { CheckBoxFilter(it.first, it.second) })
|
||||||
@ -52,6 +56,9 @@ internal class SortFilter(name: String, sortList: List<Pair<String, String>>, st
|
|||||||
internal class StatusFilter(name: String, statusList: List<Pair<String, String>>, state: Int = 0) :
|
internal class StatusFilter(name: String, statusList: List<Pair<String, String>>, state: Int = 0) :
|
||||||
SelectFilter(name, statusList, state)
|
SelectFilter(name, statusList, state)
|
||||||
|
|
||||||
|
internal class ContentRatingFilter(name: String, statusList: List<Pair<String, String>>, state: Int = 0) :
|
||||||
|
SelectFilter(name, statusList, state)
|
||||||
|
|
||||||
/** Generics **/
|
/** Generics **/
|
||||||
internal open class TriFilter(name: String, val value: String) : Filter.TriState(name)
|
internal open class TriFilter(name: String, val value: String) : Filter.TriState(name)
|
||||||
|
|
||||||
@ -156,12 +163,14 @@ private val getDemographicList: List<Pair<String, String>> = listOf(
|
|||||||
Pair("Shoujo", "2"),
|
Pair("Shoujo", "2"),
|
||||||
Pair("Seinen", "3"),
|
Pair("Seinen", "3"),
|
||||||
Pair("Josei", "4"),
|
Pair("Josei", "4"),
|
||||||
|
Pair("None", "5"),
|
||||||
)
|
)
|
||||||
|
|
||||||
private val getTypeList: List<Pair<String, String>> = listOf(
|
private val getTypeList: List<Pair<String, String>> = listOf(
|
||||||
Pair("Manga", "jp"),
|
Pair("Manga", "jp"),
|
||||||
Pair("Manhwa", "kr"),
|
Pair("Manhwa", "kr"),
|
||||||
Pair("Manhua", "cn"),
|
Pair("Manhua", "cn"),
|
||||||
|
Pair("Others", "others"),
|
||||||
)
|
)
|
||||||
|
|
||||||
private val getCreatedAtList: List<Pair<String, String>> = listOf(
|
private val getCreatedAtList: List<Pair<String, String>> = listOf(
|
||||||
@ -190,3 +199,10 @@ private val getStatusList: List<Pair<String, String>> = listOf(
|
|||||||
Pair("Cancelled", "3"),
|
Pair("Cancelled", "3"),
|
||||||
Pair("Hiatus", "4"),
|
Pair("Hiatus", "4"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val getContentRatingList: List<Pair<String, String>> = listOf(
|
||||||
|
Pair("All", ""),
|
||||||
|
Pair("Safe", "safe"),
|
||||||
|
Pair("Suggestive", "suggestive"),
|
||||||
|
Pair("Erotica", "erotica"),
|
||||||
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user