mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 22:37:56 +01:00 
			
		
		
		
	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