MangaGeko: Fix Filters (#4221)
* Fix Filters * Apply suggestion1 Co-authored-by: AwkwardPeak7 <48650614+AwkwardPeak7@users.noreply.github.com> * Apply suggestion2 * Apply Suggetions - Apply AwkwardPeak7's suggestions --------- Co-authored-by: AwkwardPeak7 <48650614+AwkwardPeak7@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									ac57f5e3dd
								
							
						
					
					
						commit
						2f9ebadb08
					
				| @ -1,7 +1,7 @@ | |||||||
| ext { | ext { | ||||||
|     extName = 'MangaGeko' |     extName = 'MangaGeko' | ||||||
|     extClass = '.MangaRawClub' |     extClass = '.MangaRawClub' | ||||||
|     extVersionCode = 24 |     extVersionCode = 25 | ||||||
|     isNsfw = true |     isNsfw = true | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,13 +1,11 @@ | |||||||
| package eu.kanade.tachiyomi.extension.en.mangarawclub | package eu.kanade.tachiyomi.extension.en.mangarawclub | ||||||
| 
 | 
 | ||||||
| import eu.kanade.tachiyomi.network.GET | import eu.kanade.tachiyomi.network.GET | ||||||
| import eu.kanade.tachiyomi.source.model.Filter |  | ||||||
| import eu.kanade.tachiyomi.source.model.FilterList | import eu.kanade.tachiyomi.source.model.FilterList | ||||||
| import eu.kanade.tachiyomi.source.model.Page | import eu.kanade.tachiyomi.source.model.Page | ||||||
| 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 eu.kanade.tachiyomi.source.online.ParsedHttpSource | import eu.kanade.tachiyomi.source.online.ParsedHttpSource | ||||||
| import okhttp3.FormBody |  | ||||||
| import okhttp3.HttpUrl.Companion.toHttpUrl | import okhttp3.HttpUrl.Companion.toHttpUrl | ||||||
| import okhttp3.OkHttpClient | import okhttp3.OkHttpClient | ||||||
| import okhttp3.Request | import okhttp3.Request | ||||||
| @ -36,74 +34,121 @@ class MangaRawClub : ParsedHttpSource() { | |||||||
|         private val DATE_FORMATTER_2 by lazy { SimpleDateFormat("MMMMM dd, yyyy, h a", Locale.ENGLISH) } |         private val DATE_FORMATTER_2 by lazy { SimpleDateFormat("MMMMM dd, yyyy, h a", Locale.ENGLISH) } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     // Popular | ||||||
|     override fun popularMangaRequest(page: Int): Request { |     override fun popularMangaRequest(page: Int): Request { | ||||||
|         return GET("$baseUrl/browse-comics/?results=$page&filter=views", headers) |         return GET("$baseUrl/browse-comics/?results=$page&filter=views", headers) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     // Latest | ||||||
|     override fun latestUpdatesRequest(page: Int): Request { |     override fun latestUpdatesRequest(page: Int): Request { | ||||||
|         return GET("$baseUrl/jumbo/manga/?results=$page", headers) |         return GET("$baseUrl/jumbo/manga/?results=$page", headers) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     // Search | ||||||
|  |     override fun getFilterList(): FilterList = getFilters() | ||||||
|  |     override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { | ||||||
|  |         if (query.isNotEmpty()) { | ||||||
|  |             // Query search | ||||||
|  |             val url = "$baseUrl/search/".toHttpUrl().newBuilder() | ||||||
|  |                 .addQueryParameter("search", query) | ||||||
|  |                 .build() | ||||||
|  |             return GET(url, headers) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Filter search | ||||||
|  |         val url = "$baseUrl/browse-comics/".toHttpUrl().newBuilder().apply { | ||||||
|  |             val tagsIncl: MutableList<String> = mutableListOf() | ||||||
|  |             val tagsExcl: MutableList<String> = mutableListOf() | ||||||
|  |             val genreIncl: MutableList<String> = mutableListOf() | ||||||
|  |             val genreExcl: MutableList<String> = mutableListOf() | ||||||
|  |             filters.forEach { filter -> | ||||||
|  |                 when (filter) { | ||||||
|  |                     is SelectFilter -> addQueryParameter("filter", filter.vals[filter.state]) | ||||||
|  |                     is GenreFilter -> { | ||||||
|  |                         filter.state.forEach { | ||||||
|  |                             when { | ||||||
|  |                                 it.isIncluded() -> genreIncl.add(it.name) | ||||||
|  |                                 it.isExcluded() -> genreExcl.add(it.name) | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     is ChapterFilter -> addQueryParameter("minchap", filter.state) | ||||||
|  |                     is TextFilter -> { | ||||||
|  |                         if (filter.state.isNotEmpty()) { | ||||||
|  |                             filter.state.split(",").filter(String::isNotBlank).map { tag -> | ||||||
|  |                                 val trimmed = tag.trim() | ||||||
|  |                                 when { | ||||||
|  |                                     trimmed.startsWith('-') -> tagsExcl.add(trimmed.removePrefix("-")) | ||||||
|  |                                     else -> tagsIncl.add(trimmed) | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     else -> {} | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             addQueryParameter("results", page.toString()) | ||||||
|  |             addQueryParameter("genre_included", genreIncl.joinToString(",")) | ||||||
|  |             addQueryParameter("genre_excluded", genreExcl.joinToString(",")) | ||||||
|  |             addQueryParameter("tags_include", tagsIncl.joinToString(",")) | ||||||
|  |             addQueryParameter("tags_exclude", tagsExcl.joinToString(",")) | ||||||
|  |         }.build() | ||||||
|  | 
 | ||||||
|  |         return GET(url, headers) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Selectors | ||||||
|     override fun searchMangaSelector() = "ul.novel-list > li.novel-item" |     override fun searchMangaSelector() = "ul.novel-list > li.novel-item" | ||||||
|     override fun popularMangaSelector() = searchMangaSelector() |     override fun popularMangaSelector() = searchMangaSelector() | ||||||
|     override fun latestUpdatesSelector() = "ul.novel-list.chapters > li.novel-item" |     override fun latestUpdatesSelector() = "ul.novel-list.chapters > li.novel-item" | ||||||
| 
 | 
 | ||||||
|     override fun searchMangaFromElement(element: Element): SManga { |  | ||||||
|         val manga = SManga.create() |  | ||||||
|         manga.title = element.select(".novel-title").first()?.text() ?: "" |  | ||||||
|         manga.thumbnail_url = element.select(".novel-cover img").attr("abs:data-src") |  | ||||||
|         manga.setUrlWithoutDomain(element.select("a").first()!!.attr("href")) |  | ||||||
|         return manga |  | ||||||
|     } |  | ||||||
|     override fun popularMangaFromElement(element: Element): SManga = searchMangaFromElement(element) |  | ||||||
|     override fun latestUpdatesFromElement(element: Element): SManga = searchMangaFromElement(element) |  | ||||||
| 
 |  | ||||||
|     override fun searchMangaNextPageSelector() = ".paging .mg-pagination-chev:last-child:not(.chev-disabled)" |     override fun searchMangaNextPageSelector() = ".paging .mg-pagination-chev:last-child:not(.chev-disabled)" | ||||||
|     override fun popularMangaNextPageSelector() = searchMangaNextPageSelector() |     override fun popularMangaNextPageSelector() = searchMangaNextPageSelector() | ||||||
|     override fun latestUpdatesNextPageSelector() = searchMangaNextPageSelector() |     override fun latestUpdatesNextPageSelector() = searchMangaNextPageSelector() | ||||||
| 
 | 
 | ||||||
|     override fun mangaDetailsParse(document: Document): SManga { |     // Manga from Element | ||||||
|         if (document.select(".novel-header").first() == null) { |     override fun searchMangaFromElement(element: Element): SManga = SManga.create().apply { | ||||||
|             throw Exception("Page not found") |         title = element.selectFirst(".novel-title")!!.ownText() | ||||||
|  |         thumbnail_url = element.select(".novel-cover img").attr("abs:data-src") | ||||||
|  |         setUrlWithoutDomain(element.selectFirst("a")!!.attr("href")) | ||||||
|     } |     } | ||||||
|  |     override fun popularMangaFromElement(element: Element): SManga = searchMangaFromElement(element) | ||||||
|  |     override fun latestUpdatesFromElement(element: Element): SManga = searchMangaFromElement(element) | ||||||
| 
 | 
 | ||||||
|         val manga = SManga.create() |     // Details | ||||||
|         val author = document.select(".author a").first()?.attr("title")?.trim() ?: "" |     override fun mangaDetailsParse(document: Document): SManga = SManga.create().apply { | ||||||
|         if (author.lowercase(Locale.ROOT) != "updating") { |         document.selectFirst(".novel-header") ?: throw Exception("Page not found") | ||||||
|             manga.author = author | 
 | ||||||
|  |         author = document.selectFirst(".author a")?.attr("title")?.trim()?.takeIf { it.lowercase() != "updating" } | ||||||
|  | 
 | ||||||
|  |         description = buildString { | ||||||
|  |             document.selectFirst(".description")?.ownText()?.substringAfter("Summary is")?.trim()?.let { | ||||||
|  |                 append(it) | ||||||
|             } |             } | ||||||
| 
 |             document.selectFirst(".alternative-title")?.ownText()?.trim()?.takeIf { it.isNotEmpty() && it.lowercase() != "updating" }?.let { | ||||||
|         var description = document.select(".description").first()?.text() ?: "" |                 append("\n\n$altName ${it.trim()}") | ||||||
|         description = description.substringAfter("Summary is").trim() |  | ||||||
| 
 |  | ||||||
|         val otherTitle = document.select(".alternative-title").first()?.text()?.trim() ?: "" |  | ||||||
|         if (otherTitle.isNotEmpty() && otherTitle.lowercase(Locale.ROOT) != "updating") { |  | ||||||
|             description += "\n\n$altName $otherTitle" |  | ||||||
|         } |  | ||||||
|         manga.description = description.trim() |  | ||||||
| 
 |  | ||||||
|         manga.genre = document.select(".categories a[href*=genre]").joinToString(", ") { |  | ||||||
|             it.attr("title").removeSuffix("Genre").trim() |  | ||||||
|                 .split(" ").joinToString(" ") { char -> |  | ||||||
|                     char.lowercase().replaceFirstChar { c -> c.uppercase() } |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         val statusElement = document.select("div.header-stats") |         genre = document.select(".categories a[href*=genre]").joinToString(", ") { | ||||||
|         manga.status = when { |             it.ownText().trim() | ||||||
|             statusElement.select("strong.completed").isNotEmpty() -> SManga.COMPLETED |                 .split(" ").joinToString(" ") { word -> | ||||||
|             statusElement.select("strong.ongoing").isNotEmpty() -> SManga.ONGOING |                     word.lowercase().replaceFirstChar { c -> c.uppercase() } | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         status = when { | ||||||
|  |             document.select("div.header-stats strong.completed").isNotEmpty() -> SManga.COMPLETED | ||||||
|  |             document.select("div.header-stats strong.ongoing").isNotEmpty() -> SManga.ONGOING | ||||||
|             else -> SManga.UNKNOWN |             else -> SManga.UNKNOWN | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         val coverElement = document.select(".cover img") |         thumbnail_url = document.selectFirst(".cover img")?.let { img -> | ||||||
|         manga.thumbnail_url = when { |             img.attr("data-src").takeIf { it.isNotEmpty() } ?: img.attr("src") | ||||||
|             coverElement.attr("data-src").isNotEmpty() -> coverElement.attr("data-src") |         } ?: thumbnail_url | ||||||
|             else -> coverElement.attr("src") |  | ||||||
|         } |  | ||||||
|         return manga |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     // Chapters | ||||||
|     override fun chapterListSelector() = "ul.chapter-list > li" |     override fun chapterListSelector() = "ul.chapter-list > li" | ||||||
| 
 | 
 | ||||||
|     override fun chapterListRequest(manga: SManga): Request { |     override fun chapterListRequest(manga: SManga): Request { | ||||||
| @ -111,19 +156,13 @@ class MangaRawClub : ParsedHttpSource() { | |||||||
|         return GET(url, headers) |         return GET(url, headers) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun chapterFromElement(element: Element): SChapter { |     override fun chapterFromElement(element: Element): SChapter = SChapter.create().apply { | ||||||
|         val chapter = SChapter.create() |         setUrlWithoutDomain(element.select("a").attr("href")) | ||||||
|         chapter.setUrlWithoutDomain(element.select("a").attr("href")) |  | ||||||
| 
 | 
 | ||||||
|         val name = element.select(".chapter-title").text().removeSuffix("-eng-li") |         val name = element.select(".chapter-title").text().removeSuffix("-eng-li") | ||||||
|         chapter.name = "Chapter $name" |         this.name = "Chapter $name" | ||||||
|         val number = parseChapterNumber(name) | 
 | ||||||
|         if (number != null) { |         date_upload = parseChapterDate(element.select(".chapter-update").attr("datetime")) | ||||||
|             chapter.chapter_number = number |  | ||||||
|         } |  | ||||||
|         val date = parseChapterDate(element.select(".chapter-update").attr("datetime")) |  | ||||||
|         chapter.date_upload = date |  | ||||||
|         return chapter |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private fun parseChapterDate(string: String): Long { |     private fun parseChapterDate(string: String): Long { | ||||||
| @ -133,140 +172,12 @@ class MangaRawClub : ParsedHttpSource() { | |||||||
|             ?: runCatching { DATE_FORMATTER_2.parse(date)?.time }.getOrNull() ?: 0L |             ?: runCatching { DATE_FORMATTER_2.parse(date)?.time }.getOrNull() ?: 0L | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private fun parseChapterNumber(string: String): Float? { |     // Pages | ||||||
|         if (string.isEmpty()) { |  | ||||||
|             return null |  | ||||||
|         } |  | ||||||
|         return string.split("-")[0].toFloatOrNull() |  | ||||||
|             ?: string.split(".")[0].toFloatOrNull() |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     override fun pageListParse(document: Document): List<Page> { |     override fun pageListParse(document: Document): List<Page> { | ||||||
|         val pages = mutableListOf<Page>() |         return document.select(".page-in img[onerror]").mapIndexed { i, it -> | ||||||
|         document.select(".page-in img[onerror]").forEachIndexed { i, it -> |             Page(i, imageUrl = it.attr("src")) | ||||||
|             pages.add(Page(i, imageUrl = it.attr("src"))) |  | ||||||
|         } |         } | ||||||
|         return pages |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun imageUrlParse(document: Document) = throw UnsupportedOperationException() |     override fun imageUrlParse(document: Document) = throw UnsupportedOperationException() | ||||||
| 
 |  | ||||||
|     override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { |  | ||||||
|         if (query.isNotEmpty()) { |  | ||||||
|             // Query search |  | ||||||
|             return GET("$baseUrl/search/?search=$query", headers) |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // Filter search |  | ||||||
|         val url = "$baseUrl/browse-comics/".toHttpUrl().newBuilder() |  | ||||||
|         val requestBody = FormBody.Builder() |  | ||||||
|         url.addQueryParameter("results", page.toString()) |  | ||||||
| 
 |  | ||||||
|         filters.forEach { filter -> |  | ||||||
|             when (filter) { |  | ||||||
|                 is GenrePairList -> url.addQueryParameter("genre", filter.toUriPart()) // GET |  | ||||||
|                 is Order -> url.addQueryParameter("filter", filter.toUriPart()) // GET |  | ||||||
|                 is Status -> requestBody.add("status", filter.toUriPart()) // POST |  | ||||||
|                 is Action -> requestBody.add("action", filter.toUriPart()) // POST |  | ||||||
|                 is GenreList -> { // POST |  | ||||||
|                     filter.state.filter { it.state == 1 }.forEach { |  | ||||||
|                         requestBody.add("options[]", it.name) |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 else -> {} |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return GET(url.build(), headers) |  | ||||||
|         // return POST("$baseUrl/search", headers, requestBody.build()) // csrfmiddlewaretoken required |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     override fun getFilterList() = FilterList( |  | ||||||
|         Filter.Header("NOTE: Ignored if using text search!"), |  | ||||||
|         Filter.Separator(), |  | ||||||
|         Order(), |  | ||||||
|         GenrePairList(), |  | ||||||
|         // Action(), |  | ||||||
|         // Status(), |  | ||||||
|         // GenreList(getGenreList()) |  | ||||||
|     ) |  | ||||||
| 
 |  | ||||||
|     private class Action : UriPartFilter( |  | ||||||
|         "Action", |  | ||||||
|         arrayOf( |  | ||||||
|             Pair("All", ""), |  | ||||||
|             Pair("Include", "include"), |  | ||||||
|             Pair("Exclude", "exclude"), |  | ||||||
|         ), |  | ||||||
|     ) |  | ||||||
| 
 |  | ||||||
|     private class Order : UriPartFilter( |  | ||||||
|         "Order", |  | ||||||
|         arrayOf( |  | ||||||
|             Pair("Random", "Random"), |  | ||||||
|             Pair("Updated", "Updated"), |  | ||||||
|             Pair("New", "New"), |  | ||||||
|             Pair("Views", "views"), |  | ||||||
|         ), |  | ||||||
|     ) |  | ||||||
| 
 |  | ||||||
|     private class Status : UriPartFilter( |  | ||||||
|         "Status", |  | ||||||
|         arrayOf( |  | ||||||
|             Pair("All", ""), |  | ||||||
|             Pair("Completed", "Completed"), |  | ||||||
|             Pair("Ongoing", "Ongoing"), |  | ||||||
|         ), |  | ||||||
|     ) |  | ||||||
| 
 |  | ||||||
|     private class GenrePairList : UriPartFilter( |  | ||||||
|         "Genres", |  | ||||||
|         arrayOf( |  | ||||||
|             Pair("All", ""), |  | ||||||
|             Pair("R-18", "R-18"), |  | ||||||
|             Pair("Action", "Action"), |  | ||||||
|             Pair("Adult", "Adult"), |  | ||||||
|             Pair("Adventure", "Adventure"), |  | ||||||
|             Pair("Comedy", "Comedy"), |  | ||||||
|             Pair("Cooking", "Cooking"), |  | ||||||
|             Pair("Doujinshi", "Doujinshi"), |  | ||||||
|             Pair("Drama", "Drama"), |  | ||||||
|             Pair("Ecchi", "Ecchi"), |  | ||||||
|             Pair("Fantasy", "Fantasy"), |  | ||||||
|             Pair("Gender bender", "Gender bender"), |  | ||||||
|             Pair("Harem", "Harem"), |  | ||||||
|             Pair("Historical", "Historical"), |  | ||||||
|             Pair("Horror", "Horror"), |  | ||||||
|             Pair("Isekai", "Isekai"), |  | ||||||
|             Pair("Josei", "Josei"), |  | ||||||
|             Pair("Ladies", "ladies"), |  | ||||||
|             Pair("Manhua", "Manhua"), |  | ||||||
|             Pair("Manhwa", "Manhwa"), |  | ||||||
|             Pair("Martial arts", "Martial arts"), |  | ||||||
|             Pair("Mature", "Mature"), |  | ||||||
|             Pair("Mecha", "Mecha"), |  | ||||||
|             Pair("Medical", "Medical"), |  | ||||||
|             Pair("Mystery", "Mystery"), |  | ||||||
|             Pair("One shot", "One shot"), |  | ||||||
|             Pair("Psychological", "Psychological"), |  | ||||||
|             Pair("Romance", "Romance"), |  | ||||||
|             Pair("School life", "School life"), |  | ||||||
|             Pair("Sci fi", "Sci fi"), |  | ||||||
|             Pair("Seinen", "Seinen"), |  | ||||||
|             Pair("Shoujo", "Shoujo"), |  | ||||||
|             Pair("Shounen", "Shounen"), |  | ||||||
|             Pair("Slice of life", "Slice of life"), |  | ||||||
|             Pair("Sports", "Sports"), |  | ||||||
|             Pair("Supernatural", "Supernatural"), |  | ||||||
|             Pair("Tragedy", "Tragedy"), |  | ||||||
|             Pair("Webtoons", "Webtoons"), |  | ||||||
|         ), |  | ||||||
|     ) |  | ||||||
| 
 |  | ||||||
|     private class Genre(name: String) : Filter.TriState(name) |  | ||||||
|     private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Genres+", genres) |  | ||||||
| 
 |  | ||||||
|     private open class UriPartFilter(displayName: String, val vals: Array<Pair<String, String>>) : |  | ||||||
|         Filter.Select<String>(displayName, vals.map { it.first }.toTypedArray()) { |  | ||||||
|         fun toUriPart() = vals[state].second |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -0,0 +1,78 @@ | |||||||
|  | package eu.kanade.tachiyomi.extension.en.mangarawclub | ||||||
|  | 
 | ||||||
|  | import eu.kanade.tachiyomi.source.model.Filter | ||||||
|  | import eu.kanade.tachiyomi.source.model.FilterList | ||||||
|  | 
 | ||||||
|  | fun getFilters(): FilterList { | ||||||
|  |     return FilterList( | ||||||
|  |         Filter.Header("NOTE: Ignored if using text search!"), | ||||||
|  |         Filter.Separator(), | ||||||
|  |         SelectFilter("Sort by", getSortsList), | ||||||
|  |         GenreFilter("Genre", getGenres), | ||||||
|  |         Filter.Separator(), | ||||||
|  |         Filter.Header("Separate tags with commas (,)"), | ||||||
|  |         Filter.Header("Prepend with dash (-) to exclude"), | ||||||
|  |         TextFilter("Tags"), | ||||||
|  |         Filter.Separator(), | ||||||
|  |         ChapterFilter("Minimum Chapter"), | ||||||
|  |     ) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | internal class GenreFilter(name: String, genreList: List<String>) : | ||||||
|  |     Filter.Group<TriFilter>(name, genreList.map { TriFilter(it) }) | ||||||
|  | 
 | ||||||
|  | internal open class TriFilter(name: String) : Filter.TriState(name) | ||||||
|  | 
 | ||||||
|  | internal open class ChapterFilter(name: String) : Filter.Text(name) | ||||||
|  | 
 | ||||||
|  | internal open class TextFilter(name: String) : Filter.Text(name) | ||||||
|  | 
 | ||||||
|  | internal open class SelectFilter(name: String, val vals: List<String>, state: Int = 0) : | ||||||
|  |     Filter.Select<String>(name, vals.map { it }.toTypedArray(), state) | ||||||
|  | 
 | ||||||
|  | private val getGenres = listOf( | ||||||
|  |     "R-18", | ||||||
|  |     "Action", | ||||||
|  |     "Adult", | ||||||
|  |     "Adventure", | ||||||
|  |     "Comedy", | ||||||
|  |     "Cooking", | ||||||
|  |     "Doujinshi", | ||||||
|  |     "Drama", | ||||||
|  |     "Ecchi", | ||||||
|  |     "Fantasy", | ||||||
|  |     "Gender bender", | ||||||
|  |     "Harem", | ||||||
|  |     "Historical", | ||||||
|  |     "Horror", | ||||||
|  |     "Isekai", | ||||||
|  |     "Josei", | ||||||
|  |     "Ladies", | ||||||
|  |     "Manhua", | ||||||
|  |     "Manhwa", | ||||||
|  |     "Martial arts", | ||||||
|  |     "Mature", | ||||||
|  |     "Mecha", | ||||||
|  |     "Medical", | ||||||
|  |     "Mystery", | ||||||
|  |     "One shot", | ||||||
|  |     "Psychological", | ||||||
|  |     "Romance", | ||||||
|  |     "School life", | ||||||
|  |     "Sci fi", | ||||||
|  |     "Seinen", | ||||||
|  |     "Shoujo", | ||||||
|  |     "Shounen", | ||||||
|  |     "Slice of life", | ||||||
|  |     "Sports", | ||||||
|  |     "Supernatural", | ||||||
|  |     "Tragedy", | ||||||
|  |     "Webtoons", | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | private val getSortsList = listOf( | ||||||
|  |     "Random", | ||||||
|  |     "New", | ||||||
|  |     "Updated", | ||||||
|  |     "Views", | ||||||
|  | ) | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 KenjieDec
						KenjieDec