Filters with flexible adapter
This commit is contained in:
@@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.data.source.model
|
||||
sealed class Filter<T>(val name: String, var state: T) {
|
||||
open class Header(name: String) : Filter<Any>(name, 0)
|
||||
open class Separator(name: String = "") : Filter<Any>(name, 0)
|
||||
abstract class List<V>(name: String, val values: Array<V>, state: Int = 0) : Filter<Int>(name, state)
|
||||
abstract class Select<V>(name: String, val values: Array<V>, state: Int = 0) : Filter<Int>(name, state)
|
||||
abstract class Text(name: String, state: String = "") : Filter<String>(name, state)
|
||||
abstract class CheckBox(name: String, state: Boolean = false) : Filter<Boolean>(name, state)
|
||||
abstract class TriState(name: String, state: Int = STATE_IGNORE) : Filter<Int>(name, state) {
|
||||
@@ -17,9 +17,24 @@ sealed class Filter<T>(val name: String, var state: T) {
|
||||
const val STATE_EXCLUDE = 2
|
||||
}
|
||||
}
|
||||
abstract class Group<V>(name: String, state: List<V>): Filter<List<V>>(name, state)
|
||||
|
||||
abstract class Sort<V>(name: String, val values: Array<V>, state: Selection? = null)
|
||||
abstract class Sort(name: String, val values: Array<String>, state: Selection? = null)
|
||||
: Filter<Sort.Selection?>(name, state) {
|
||||
data class Selection(val index: Int, val ascending: Boolean)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is Filter<*>) return false
|
||||
|
||||
return name == other.name && state == other.state
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = name.hashCode()
|
||||
result = 31 * result + (state?.hashCode() ?: 0)
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +1,7 @@
|
||||
package eu.kanade.tachiyomi.data.source.model
|
||||
|
||||
class FilterList(list: List<Filter<*>>) : List<Filter<*>> by list {
|
||||
data class FilterList(val list: List<Filter<*>>) : List<Filter<*>> by list {
|
||||
|
||||
constructor(vararg fs: Filter<*>) : this(if (fs.isNotEmpty()) fs.asList() else emptyList())
|
||||
|
||||
fun hasSameState(other: FilterList): Boolean {
|
||||
if (size != other.size) return false
|
||||
|
||||
return (0..lastIndex)
|
||||
.all { get(it).javaClass == other[it].javaClass && get(it).state == other[it].state }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -99,7 +99,7 @@ class Batoto : ParsedOnlineSource(), LoginSource {
|
||||
is TextField -> {
|
||||
if (!filter.state.isEmpty()) url.addQueryParameter(filter.key, filter.state)
|
||||
}
|
||||
is ListField -> {
|
||||
is SelectField -> {
|
||||
val sel = filter.values[filter.state].value
|
||||
if (!sel.isEmpty()) url.addQueryParameter(filter.key, sel)
|
||||
}
|
||||
@@ -290,9 +290,9 @@ class Batoto : ParsedOnlineSource(), LoginSource {
|
||||
private class Status : Filter.TriState("Completed")
|
||||
private class Genre(name: String, val id: Int) : Filter.TriState(name)
|
||||
private class TextField(name: String, val key: String) : Filter.Text(name)
|
||||
private class ListField(name: String, val key: String, values: Array<ListValue>, state: Int = 0) : Filter.List<ListValue>(name, values, state)
|
||||
private class SelectField(name: String, val key: String, values: Array<ListValue>, state: Int = 0) : Filter.Select<ListValue>(name, values, state)
|
||||
private class Flag(name: String, val key: String, val valTrue: String, val valFalse: String) : Filter.CheckBox(name)
|
||||
private class OrderBy() : Filter.Sort<String>("Order by",
|
||||
private class OrderBy() : Filter.Sort("Order by",
|
||||
arrayOf("Title", "Author", "Artist", "Rating", "Views", "Last Update"),
|
||||
Filter.Sort.Selection(4, false))
|
||||
|
||||
@@ -302,14 +302,14 @@ class Batoto : ParsedOnlineSource(), LoginSource {
|
||||
// on https://bato.to/search
|
||||
override fun getFilterList() = FilterList(
|
||||
TextField("Author", "artist_name"),
|
||||
ListField("Type", "type", arrayOf(ListValue("Any", ""), ListValue("Manga (Jp)", "jp"), ListValue("Manhwa (Kr)", "kr"), ListValue("Manhua (Cn)", "cn"), ListValue("Artbook", "ar"), ListValue("Other", "ot"))),
|
||||
SelectField("Type", "type", arrayOf(ListValue("Any", ""), ListValue("Manga (Jp)", "jp"), ListValue("Manhwa (Kr)", "kr"), ListValue("Manhua (Cn)", "cn"), ListValue("Artbook", "ar"), ListValue("Other", "ot"))),
|
||||
Status(),
|
||||
Flag("Exclude mature", "mature", "m", ""),
|
||||
Filter.Separator(),
|
||||
OrderBy(),
|
||||
Filter.Separator(),
|
||||
Filter.Header("Genres"),
|
||||
ListField("Inclusion mode", "genre_cond", arrayOf(ListValue("And (all selected genres)", "and"), ListValue("Or (any selected genres) ", "or"))),
|
||||
SelectField("Inclusion mode", "genre_cond", arrayOf(ListValue("And (all selected genres)", "and"), ListValue("Or (any selected genres) ", "or"))),
|
||||
Genre("4-Koma", 40),
|
||||
Genre("Action", 1),
|
||||
Genre("Adventure", 2),
|
||||
|
||||
@@ -58,7 +58,12 @@ class Mangafox : ParsedOnlineSource() {
|
||||
val url = HttpUrl.parse("$baseUrl/search.php?name_method=cw&author_method=cw&artist_method=cw&advopts=1").newBuilder().addQueryParameter("name", query)
|
||||
(if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
|
||||
when (filter) {
|
||||
is Genre -> url.addQueryParameter(filter.id, filter.state.toString())
|
||||
is Status -> url.addQueryParameter(filter.id, filter.state.toString())
|
||||
is GenreList -> {
|
||||
filter.state.forEach { genre ->
|
||||
url.addQueryParameter(genre.id, genre.state.toString())
|
||||
}
|
||||
}
|
||||
is TextField -> url.addQueryParameter(filter.key, filter.state)
|
||||
is Type -> url.addQueryParameter("type", if(filter.state == 0) "" else filter.state.toString())
|
||||
is OrderBy -> {
|
||||
@@ -161,24 +166,29 @@ class Mangafox : ParsedOnlineSource() {
|
||||
}
|
||||
}
|
||||
|
||||
private class Status(val id: String = "is_completed") : Filter.TriState("Completed")
|
||||
private class Genre(name: String, val id: String = "genres[$name]") : Filter.TriState(name)
|
||||
private class TextField(name: String, val key: String) : Filter.Text(name)
|
||||
private class Type() : Filter.List<String>("Type", arrayOf("Any", "Japanese Manga", "Korean Manhwa", "Chinese Manhua"))
|
||||
private class OrderBy() : Filter.Sort<String>("Order by",
|
||||
private class Type : Filter.Select<String>("Type", arrayOf("Any", "Japanese Manga", "Korean Manhwa", "Chinese Manhua"))
|
||||
private class OrderBy : Filter.Sort("Order by",
|
||||
arrayOf("Series name", "Rating", "Views", "Total chapters", "Last chapter"),
|
||||
Filter.Sort.Selection(2, false))
|
||||
private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Genres", genres)
|
||||
|
||||
// $('select.genres').map((i,el)=>`Genre("${$(el).next().text().trim()}", "${$(el).attr('name')}")`).get().join(',\n')
|
||||
// on http://mangafox.me/search.php
|
||||
override fun getFilterList() = FilterList(
|
||||
TextField("Author", "author"),
|
||||
TextField("Artist", "artist"),
|
||||
Type(),
|
||||
Genre("Completed", "is_completed"),
|
||||
Status(),
|
||||
Filter.Separator(),
|
||||
OrderBy(),
|
||||
Filter.Separator(),
|
||||
Filter.Header("Genres"),
|
||||
GenreList(getGenreList())
|
||||
)
|
||||
|
||||
// $('select.genres').map((i,el)=>`Genre("${$(el).next().text().trim()}", "${$(el).attr('name')}")`).get().join(',\n')
|
||||
// on http://mangafox.me/search.php
|
||||
private fun getGenreList() = listOf(
|
||||
Genre("Action"),
|
||||
Genre("Adult"),
|
||||
Genre("Adventure"),
|
||||
|
||||
@@ -162,15 +162,11 @@ class Mangahere : ParsedOnlineSource() {
|
||||
|
||||
override fun imageUrlParse(document: Document) = document.getElementById("image").attr("src")
|
||||
|
||||
private data class ListValue(val name: String, val value: String) {
|
||||
override fun toString(): String = name
|
||||
}
|
||||
|
||||
private class Status() : Filter.TriState("Completed")
|
||||
private class Status : Filter.TriState("Completed")
|
||||
private class Genre(name: String, val id: String = "genres[$name]") : Filter.TriState(name)
|
||||
private class TextField(name: String, val key: String) : Filter.Text(name)
|
||||
private class Type() : Filter.List<String>("Type", arrayOf("Any", "Japanese Manga (read from right to left)", "Korean Manhwa (read from left to right)"))
|
||||
private class OrderBy() : Filter.Sort<String>("Order by",
|
||||
private class Type : Filter.Select<String>("Type", arrayOf("Any", "Japanese Manga (read from right to left)", "Korean Manhwa (read from left to right)"))
|
||||
private class OrderBy : Filter.Sort("Order by",
|
||||
arrayOf("Series name", "Rating", "Views", "Total chapters", "Last chapter"),
|
||||
Filter.Sort.Selection(2, false))
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ class Mangasee : ParsedOnlineSource() {
|
||||
if (filter.state?.ascending != true)
|
||||
url.addQueryParameter("sortOrder", "descending")
|
||||
}
|
||||
is ListField -> if (filter.state != 0) url.addQueryParameter(filter.key, filter.values[filter.state])
|
||||
is SelectField -> if (filter.state != 0) url.addQueryParameter(filter.key, filter.values[filter.state])
|
||||
is TextField -> if (!filter.state.isEmpty()) url.addQueryParameter(filter.key, filter.state)
|
||||
is Genre -> when (filter.state) {
|
||||
Filter.TriState.STATE_INCLUDE -> genres = if (genres == null) filter.name else genres + "," + filter.name
|
||||
@@ -155,23 +155,19 @@ class Mangasee : ParsedOnlineSource() {
|
||||
|
||||
override fun imageUrlParse(document: Document): String = document.select("img.CurImage").attr("src")
|
||||
|
||||
private data class SortOption(val name: String, val keys: Array<String>, val values: Array<String>) {
|
||||
override fun toString(): String = name
|
||||
}
|
||||
|
||||
private class Sort() : Filter.Sort<String>("Sort", arrayOf("Alphabetically", "Date updated", "Popularity"), Filter.Sort.Selection(2, false))
|
||||
private class Sort : Filter.Sort("Sort", arrayOf("Alphabetically", "Date updated", "Popularity"), Filter.Sort.Selection(2, false))
|
||||
private class Genre(name: String) : Filter.TriState(name)
|
||||
private class TextField(name: String, val key: String) : Filter.Text(name)
|
||||
private class ListField(name: String, val key: String, values: Array<String>, state: Int = 0) : Filter.List<String>(name, values, state)
|
||||
private class SelectField(name: String, val key: String, values: Array<String>, state: Int = 0) : Filter.Select<String>(name, values, state)
|
||||
|
||||
// [...document.querySelectorAll("label.triStateCheckBox input")].map(el => `Filter("${el.getAttribute('name')}", "${el.nextSibling.textContent.trim()}")`).join(',\n')
|
||||
// http://mangasee.co/advanced-search/
|
||||
override fun getFilterList() = FilterList(
|
||||
TextField("Years", "year"),
|
||||
TextField("Author", "author"),
|
||||
ListField("Scan Status", "status", arrayOf("Any", "Complete", "Discontinued", "Hiatus", "Incomplete", "Ongoing")),
|
||||
ListField("Publish Status", "pstatus", arrayOf("Any", "Cancelled", "Complete", "Discontinued", "Hiatus", "Incomplete", "Ongoing", "Unfinished")),
|
||||
ListField("Type", "type", arrayOf("Any", "Doujinshi", "Manga", "Manhua", "Manhwa", "OEL", "One-shot")),
|
||||
SelectField("Scan Status", "status", arrayOf("Any", "Complete", "Discontinued", "Hiatus", "Incomplete", "Ongoing")),
|
||||
SelectField("Publish Status", "pstatus", arrayOf("Any", "Cancelled", "Complete", "Discontinued", "Hiatus", "Incomplete", "Ongoing", "Unfinished")),
|
||||
SelectField("Type", "type", arrayOf("Any", "Doujinshi", "Manga", "Manhua", "Manhwa", "OEL", "One-shot")),
|
||||
Filter.Separator(),
|
||||
Sort(),
|
||||
Filter.Separator(),
|
||||
|
||||
@@ -164,7 +164,7 @@ class Readmangatoday : ParsedOnlineSource() {
|
||||
private class Status() : Filter.TriState("Completed")
|
||||
private class Genre(name: String, val id: Int) : Filter.TriState(name)
|
||||
private class TextField(name: String, val key: String) : Filter.Text(name)
|
||||
private class Type() : Filter.List<String>("Type", arrayOf("All", "Japanese Manga", "Korean Manhwa", "Chinese Manhua"))
|
||||
private class Type() : Filter.Select<String>("Type", arrayOf("All", "Japanese Manga", "Korean Manhwa", "Chinese Manhua"))
|
||||
|
||||
// [...document.querySelectorAll("ul.manga-cat span")].map(el => `Genre("${el.nextSibling.textContent.trim()}", ${el.getAttribute('data-id')})`).join(',\n')
|
||||
// http://www.readmanga.today/advanced-search
|
||||
|
||||
Reference in New Issue
Block a user