Update Manhwa18/Manhwa18.net, Manhwaraw.com (#19516)
* Fix ManyToon.me & ManyToon.club Fix issues in which both sources unable to load any mangas. Closes #16612 * Update multisrc MyMangaCMS to support other site’s langugae Also, support a second alternative name and remove generic words like “manhwa”, “engsub” from those names. Also, mark TruyenTranhLH as NSFW * Move Manhwa18 & Manhwa18.net to MyMangaCMS theme. Also fix Manhwa18.net’s searching issue with the previous theme. Also allow Manhwa18’s filter working since it was not with the previous theme. Close #18818 * Remove unused import causing PR build check to fail * MyMangaCms Bump the `versionId` so the ID will change and users will be forced to migrate to update the URLs. * fix locale friendly * Fix Manhwaraw.com won’t show Popular & Latest manhwa * revert bumping TruyenTranhLH’s version
|
@ -1,90 +0,0 @@
|
|||
package eu.kanade.tachiyomi.extension.en.manhwa18
|
||||
|
||||
import eu.kanade.tachiyomi.multisrc.fmreader.FMReader
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import org.jsoup.nodes.Document
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
class Manhwa18 : FMReader("Manhwa18", "https://manhwa18.com", "en") {
|
||||
override val requestPath = "tim-kiem"
|
||||
|
||||
override val popularSort = "sort=top"
|
||||
|
||||
override fun popularMangaParse(response: Response): MangasPage {
|
||||
val document = response.asJsoup()
|
||||
|
||||
val mangas = document.select(popularMangaSelector()).map { popularMangaFromElement(it) }
|
||||
|
||||
return MangasPage(mangas, document.select(".pagination_wrap .disabled").text() != "Bottom")
|
||||
}
|
||||
|
||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||
val url = "$baseUrl/$requestPath?".toHttpUrlOrNull()!!.newBuilder()
|
||||
.addQueryParameter("q", query)
|
||||
.addQueryParameter("page", page.toString())
|
||||
return GET(url.toString(), headers)
|
||||
}
|
||||
override fun latestUpdatesRequest(page: Int): Request =
|
||||
GET("$baseUrl/$requestPath?listType=pagination&page=$page&sort=update&sort_type=DESC", headers)
|
||||
|
||||
override fun mangaDetailsParse(document: Document): SManga {
|
||||
return SManga.create().apply {
|
||||
title = document.select(".series-name").text()
|
||||
thumbnail_url = document.select("meta[property='og:image']").attr("abs:content")
|
||||
|
||||
document.select(".series-information")?.let { info ->
|
||||
author = info.select(".info-name:contains(Author:) + .info-value").text()
|
||||
genre = info.select(".info-name:contains(Genre:) + .info-value > a")
|
||||
.joinToString { it.text().trim() }
|
||||
|
||||
description = document.select(".summary-content").text().trim()
|
||||
info.select(".info-name:contains(Other name:) + .info-value")
|
||||
.firstOrNull()?.text()?.let {
|
||||
val altName = removeGenericWords(it)
|
||||
description = when (title.lowercase(Locale.US)) {
|
||||
altName.lowercase(Locale.US) -> description
|
||||
else -> description + "\n\n$altName"
|
||||
}
|
||||
}
|
||||
status =
|
||||
parseStatus(info.select(".info-name:contains(Status:) + .info-value").text())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeGenericWords(name: String): String {
|
||||
val excludeList = listOf("manhwa", "engsub")
|
||||
return name.split(' ').filterNot { word ->
|
||||
word.lowercase(Locale.US) in excludeList
|
||||
}.joinToString(" ")
|
||||
}
|
||||
|
||||
override fun chapterListParse(response: Response): List<SChapter> {
|
||||
val document = response.asJsoup()
|
||||
|
||||
return document.select(".list-chapters > a").map { element ->
|
||||
SChapter.create().apply {
|
||||
setUrlWithoutDomain(element.attr("abs:href"))
|
||||
name = element.attr("title")
|
||||
date_upload =
|
||||
SimpleDateFormat("dd/MM/yyyy", Locale.US).parse(
|
||||
element.select(".chapter-time").text().substringAfter(" - "),
|
||||
)?.time ?: 0L
|
||||
chapter_number = element.attr("time").substringAfterLast(' ').toFloatOrNull() ?: -1f
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override val pageListImageSelector = "#chapter-content > img"
|
||||
|
||||
override fun getFilterList() = FilterList()
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
package eu.kanade.tachiyomi.extension.all.manhwa18net
|
||||
|
||||
import eu.kanade.tachiyomi.multisrc.fmreader.FMReader
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceFactory
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import okhttp3.Request
|
||||
import org.jsoup.nodes.Element
|
||||
|
||||
class Manhwa18NetFactory : SourceFactory {
|
||||
override fun createSources(): List<Source> = listOf(
|
||||
Manhwa18Net(),
|
||||
Manhwa18NetRaw(),
|
||||
)
|
||||
}
|
||||
|
||||
class Manhwa18Net : FMReader("Manhwa18.net", "https://manhwa18.net", "en") {
|
||||
override val requestPath = "genre/manhwa"
|
||||
override val popularSort = "sort=top"
|
||||
override val pageListImageSelector = "div#chapter-content > img"
|
||||
|
||||
override fun latestUpdatesRequest(page: Int): Request =
|
||||
GET(
|
||||
"$baseUrl/$requestPath?listType=pagination&page=$page&sort=update&sort_type=DESC",
|
||||
headers,
|
||||
)
|
||||
|
||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||
val noRawsUrl = super.searchMangaRequest(page, query, filters).url.newBuilder().toString()
|
||||
return GET(noRawsUrl, headers)
|
||||
}
|
||||
|
||||
override fun getGenreList() = getAdultGenreList()
|
||||
|
||||
override fun chapterFromElement(element: Element, mangaTitle: String): SChapter {
|
||||
return SChapter.create().apply {
|
||||
setUrlWithoutDomain(element.attr("abs:href"))
|
||||
name = element.attr("title")
|
||||
date_upload = parseAbsoluteDate(
|
||||
element.select(chapterTimeSelector).text().substringAfter(" - "),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Manhwa18NetRaw : FMReader("Manhwa18.net", "https://manhwa18.net", "ko") {
|
||||
override val requestPath = "genre/raw"
|
||||
override val popularSort = "sort=top"
|
||||
override val pageListImageSelector = "div#chapter-content > img"
|
||||
|
||||
override fun latestUpdatesRequest(page: Int): Request =
|
||||
GET(
|
||||
"$baseUrl/$requestPath?listType=pagination&page=$page&sort=update&sort_type=DESC",
|
||||
headers,
|
||||
)
|
||||
|
||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||
val onlyRawsUrl = super.searchMangaRequest(page, query, filters).url.newBuilder().toString()
|
||||
return GET(onlyRawsUrl, headers)
|
||||
}
|
||||
|
||||
override fun getFilterList() = FilterList(
|
||||
super.getFilterList().filterNot { it == GenreList(getGenreList()) },
|
||||
)
|
||||
|
||||
override fun chapterFromElement(element: Element, mangaTitle: String): SChapter {
|
||||
return SChapter.create().apply {
|
||||
setUrlWithoutDomain(element.attr("abs:href"))
|
||||
name = element.attr("title")
|
||||
date_upload = parseAbsoluteDate(
|
||||
element.select(chapterTimeSelector).text().substringAfter(" - "),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package eu.kanade.tachiyomi.extension.ko.manhwaraw
|
||||
|
||||
import eu.kanade.tachiyomi.multisrc.madara.Madara
|
||||
|
||||
class ManhwaRaw : Madara("ManhwaRaw", "https://manhwaraw.com", "ko") {
|
||||
|
||||
override val mangaSubString = "manhwa-raw"
|
||||
|
||||
// The website does not flag the content.
|
||||
override val filterNonMangaItems = false
|
||||
}
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 212 KiB After Width: | Height: | Size: 212 KiB |
|
@ -0,0 +1,62 @@
|
|||
package eu.kanade.tachiyomi.extension.en.manhwa18
|
||||
|
||||
import eu.kanade.tachiyomi.multisrc.mymangacms.MyMangaCMS
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
|
||||
class Manhwa18 : MyMangaCMS("Manhwa18", "https://manhwa18.com", "en") {
|
||||
|
||||
// Migrated from FMReader to MyMangaCMS.
|
||||
override val versionId = 2
|
||||
|
||||
override val parseAuthorString = "Author"
|
||||
override val parseAlternativeNameString = "Other name"
|
||||
override val parseAlternative2ndNameString = "Doujinshi"
|
||||
override val parseStatusString = "Status"
|
||||
override val parseStatusOngoingStringLowerCase = "on going"
|
||||
override val parseStatusOnHoldStringLowerCase = "on hold"
|
||||
override val parseStatusCompletedStringLowerCase = "completed"
|
||||
|
||||
override fun getFilterList(): FilterList = FilterList(
|
||||
Author("Author"),
|
||||
Status(
|
||||
"Status",
|
||||
"All",
|
||||
"Ongoing",
|
||||
"On hold",
|
||||
"Completed",
|
||||
),
|
||||
Sort(
|
||||
"Order",
|
||||
"A-Z",
|
||||
"Z-A",
|
||||
"Latest update",
|
||||
"New manhwa",
|
||||
"Most view",
|
||||
"Most like",
|
||||
),
|
||||
GenreList(getGenreList(), "Genre"),
|
||||
)
|
||||
|
||||
// To populate this list:
|
||||
// console.log([...document.querySelectorAll("div.search-gerne_item")].map(elem => `Genre("${elem.textContent.trim()}", ${elem.querySelector("label").getAttribute("data-genre-id")}),`).join("\n"))
|
||||
override fun getGenreList() = listOf(
|
||||
Genre("Adult", 4),
|
||||
Genre("Doujinshi", 9),
|
||||
Genre("Harem", 17),
|
||||
Genre("Manga", 24),
|
||||
Genre("Manhwa", 26),
|
||||
Genre("Mature", 28),
|
||||
Genre("NTR", 33),
|
||||
Genre("Romance", 36),
|
||||
Genre("Webtoon", 57),
|
||||
Genre("Action", 59),
|
||||
Genre("Comedy", 60),
|
||||
Genre("BL", 61),
|
||||
Genre("Horror", 62),
|
||||
Genre("Raw", 63),
|
||||
Genre("Uncensore", 64),
|
||||
)
|
||||
|
||||
override fun dateUpdatedParser(date: String): Long =
|
||||
runCatching { dateFormatter.parse(date.substringAfter(" - "))?.time }.getOrNull() ?: 0L
|
||||
}
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 212 KiB After Width: | Height: | Size: 212 KiB |
|
@ -0,0 +1,62 @@
|
|||
package eu.kanade.tachiyomi.extension.all.manhwa18net
|
||||
|
||||
import eu.kanade.tachiyomi.multisrc.mymangacms.MyMangaCMS
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
|
||||
class Manhwa18Net : MyMangaCMS("Manhwa18.net", "https://manhwa18.net", "en") {
|
||||
|
||||
// Migrated from FMReader to MyMangaCms.
|
||||
override val versionId = 2
|
||||
|
||||
override val parseAuthorString = "Author"
|
||||
override val parseAlternativeNameString = "Other name"
|
||||
override val parseAlternative2ndNameString = "Doujinshi"
|
||||
override val parseStatusString = "Status"
|
||||
override val parseStatusOngoingStringLowerCase = "on going"
|
||||
override val parseStatusOnHoldStringLowerCase = "on hold"
|
||||
override val parseStatusCompletedStringLowerCase = "completed"
|
||||
|
||||
override fun getFilterList(): FilterList = FilterList(
|
||||
Author("Author"),
|
||||
Status(
|
||||
"Status",
|
||||
"All",
|
||||
"Ongoing",
|
||||
"On hold",
|
||||
"Completed",
|
||||
),
|
||||
Sort(
|
||||
"Order",
|
||||
"A-Z",
|
||||
"Z-A",
|
||||
"Latest update",
|
||||
"New manhwa",
|
||||
"Most view",
|
||||
"Most like",
|
||||
),
|
||||
GenreList(getGenreList(), "Genre"),
|
||||
)
|
||||
|
||||
// To populate this list:
|
||||
// console.log([...document.querySelectorAll("div.search-gerne_item")].map(elem => `Genre("${elem.textContent.trim()}", ${elem.querySelector("label").getAttribute("data-genre-id")}),`).join("\n"))
|
||||
override fun getGenreList() = listOf(
|
||||
Genre("Adult", 4),
|
||||
Genre("Doujinshi", 9),
|
||||
Genre("Harem", 17),
|
||||
Genre("Manga", 24),
|
||||
Genre("Manhwa", 26),
|
||||
Genre("Mature", 28),
|
||||
Genre("NTR", 33),
|
||||
Genre("Romance", 36),
|
||||
Genre("Webtoon", 57),
|
||||
Genre("Action", 59),
|
||||
Genre("Comedy", 60),
|
||||
Genre("BL", 61),
|
||||
Genre("Horror", 62),
|
||||
Genre("Raw", 63),
|
||||
Genre("Uncensore", 64),
|
||||
)
|
||||
|
||||
override fun dateUpdatedParser(date: String): Long =
|
||||
runCatching { dateFormatter.parse(date.substringAfter(" - "))?.time }.getOrNull() ?: 0L
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package eu.kanade.tachiyomi.multisrc.fmreader
|
||||
|
||||
import generator.ThemeSourceData.MultiLang
|
||||
import generator.ThemeSourceData.SingleLang
|
||||
import generator.ThemeSourceGenerator
|
||||
|
||||
|
@ -13,12 +12,10 @@ class FMReaderGenerator : ThemeSourceGenerator {
|
|||
override val baseVersionCode: Int = 8
|
||||
|
||||
override val sources = listOf(
|
||||
MultiLang("Manhwa18.net", "https://manhwa18.net", listOf("en", "ko"), className = "Manhwa18NetFactory", isNsfw = true, overrideVersionCode = 1),
|
||||
SingleLang("Epik Manga", "https://www.epikmanga.com", "tr"),
|
||||
SingleLang("KissLove", "https://klz9.com", "ja", isNsfw = true, overrideVersionCode = 4),
|
||||
SingleLang("Manga-TR", "https://manga-tr.com", "tr", className = "MangaTR", overrideVersionCode = 2),
|
||||
SingleLang("ManhuaRock", "https://manhuarock.net", "vi", overrideVersionCode = 1),
|
||||
SingleLang("Manhwa18", "https://manhwa18.com", "en", isNsfw = true, overrideVersionCode = 2),
|
||||
SingleLang("Say Truyen", "https://saytruyenvip.com", "vi", overrideVersionCode = 3),
|
||||
SingleLang("WeLoveManga", "https://weloma.art", "ja", pkgName = "rawlh", isNsfw = true, overrideVersionCode = 5),
|
||||
SingleLang("Manga1000", "https://manga1000.top", "ja"),
|
||||
|
|
|
@ -329,7 +329,7 @@ class MadaraGenerator : ThemeSourceGenerator {
|
|||
SingleLang("ManhuaScan.info (unoriginal)", "https://manhuascan.info", "en", isNsfw = true, className = "ManhuaScanInfo"),
|
||||
SingleLang("ManhuaUS", "https://manhuaus.com", "en", overrideVersionCode = 5),
|
||||
SingleLang("ManhuaZone", "https://manhuazone.org", "en", overrideVersionCode = 1),
|
||||
SingleLang("Manhwa Raw", "https://manhwaraw.com", "ko", isNsfw = true, overrideVersionCode = 1),
|
||||
SingleLang("Manhwa Raw", "https://manhwaraw.com", "ko", isNsfw = true, overrideVersionCode = 2),
|
||||
SingleLang("Manhwa-Latino", "https://manhwa-latino.com", "es", isNsfw = true, className = "ManhwaLatino", overrideVersionCode = 7),
|
||||
SingleLang("Manhwa-raw", "https://manhwa-raw.com", "all", isNsfw = true, className = "ManhwaDashRaw", overrideVersionCode = 1),
|
||||
SingleLang("Manhwa18.app", "https://manhwa18.app", "en", isNsfw = true, className = "Manhwa18app"),
|
||||
|
|
|
@ -29,6 +29,19 @@ abstract class MyMangaCMS(
|
|||
override val lang: String,
|
||||
) : ParsedHttpSource() {
|
||||
|
||||
protected open val parseAuthorString = "Tác giả"
|
||||
protected open val parseAlternativeNameString = "Tên khác"
|
||||
protected open val parseAlternative2ndNameString = "Tên gốc"
|
||||
protected open val parseStatusString = "Tình trạng"
|
||||
protected open val parseStatusOngoingStringLowerCase = "đang tiến hành"
|
||||
protected open val parseStatusOnHoldStringLowerCase = "tạm ngưng"
|
||||
protected open val parseStatusCompletedStringLowerCase = "đã hoàn thành"
|
||||
|
||||
/**
|
||||
* List of words to be removed when parsing alternative names
|
||||
*/
|
||||
protected open val removeGenericWords = listOf("manhwa", "engsub")
|
||||
|
||||
override val supportsLatest = true
|
||||
|
||||
override val client = network.cloudflareClient.newBuilder().apply {
|
||||
|
@ -184,20 +197,23 @@ abstract class MyMangaCMS(
|
|||
)
|
||||
title = document.select(".series-name").first()!!.text().trim()
|
||||
|
||||
var alternativeNames: String? = null
|
||||
var alternativeNames: String = ""
|
||||
document.select(".info-item").forEach {
|
||||
val value = it.select(".info-value")
|
||||
when (it.select(".info-name").text().trim()) {
|
||||
"Tên khác:" -> alternativeNames = value.joinToString(", ") { name ->
|
||||
name.text().trim()
|
||||
"$parseAlternativeNameString:" -> alternativeNames += value.joinToString(", ") { name ->
|
||||
removeGenericWords(name.text()).trim() + ", "
|
||||
}
|
||||
"Tác giả:" -> author = value.joinToString(", ") { auth ->
|
||||
"$parseAlternative2ndNameString:" -> alternativeNames += value.joinToString(", ") { name ->
|
||||
removeGenericWords(name.text()).trim() + ", "
|
||||
}
|
||||
"$parseAuthorString:" -> author = value.joinToString(", ") { auth ->
|
||||
auth.text().trim()
|
||||
}
|
||||
"Tình trạng:" -> status = when (value.first()!!.text().lowercase().trim()) {
|
||||
"đang tiến hành" -> SManga.ONGOING
|
||||
"tạm ngưng" -> SManga.ON_HIATUS
|
||||
"đã hoàn thành" -> SManga.COMPLETED
|
||||
"$parseStatusString:" -> status = when (value.first()!!.text().lowercase().trim()) {
|
||||
parseStatusOngoingStringLowerCase -> SManga.ONGOING
|
||||
parseStatusOnHoldStringLowerCase -> SManga.ON_HIATUS
|
||||
parseStatusCompletedStringLowerCase -> SManga.COMPLETED
|
||||
else -> SManga.UNKNOWN
|
||||
}
|
||||
}
|
||||
|
@ -217,8 +233,8 @@ abstract class MyMangaCMS(
|
|||
descElem.text().trim()
|
||||
}
|
||||
|
||||
if (!alternativeNames.isNullOrEmpty()) {
|
||||
description = "Tên khác: ${alternativeNames}\n\n" + description
|
||||
if (alternativeNames.isNotEmpty()) {
|
||||
description = "$parseAlternativeNameString: ${alternativeNames}\n\n" + description
|
||||
}
|
||||
|
||||
genre = document.select("a[href*=the-loai] span.badge")
|
||||
|
@ -230,6 +246,14 @@ abstract class MyMangaCMS(
|
|||
.attr("style")
|
||||
.let { backgroundImageRegex.find(it)?.groups?.get(1)?.value }
|
||||
}
|
||||
|
||||
private fun removeGenericWords(name: String): String {
|
||||
val locale = Locale.forLanguageTag(lang)
|
||||
|
||||
return name.split(' ')
|
||||
.filterNot { word -> word.lowercase(locale) in removeGenericWords }
|
||||
.joinToString(" ")
|
||||
}
|
||||
//endregion
|
||||
|
||||
//region Chapter list
|
||||
|
@ -294,30 +318,44 @@ abstract class MyMangaCMS(
|
|||
) : Filter.Select<String>(displayName, vals.map { it.first }.toTypedArray(), state) {
|
||||
fun toUriPart() = vals[state].second
|
||||
}
|
||||
private class Status : Filter.Select<String>(
|
||||
"Tình trạng",
|
||||
protected class Status(
|
||||
displayName: String = "Tình trạng",
|
||||
statusAll: String = "Tất cả",
|
||||
statusOngoing: String = "Đang tiến hành",
|
||||
statusOnHold: String = "Tạm ngưng",
|
||||
statusCompleted: String = "Hoàn thành",
|
||||
) : Filter.Select<String>(
|
||||
displayName,
|
||||
arrayOf(
|
||||
"Tất cả",
|
||||
"Đang tiến hành",
|
||||
"Tạm ngưng",
|
||||
"Hoàn thành",
|
||||
statusAll,
|
||||
statusOngoing,
|
||||
statusOnHold,
|
||||
statusCompleted,
|
||||
),
|
||||
)
|
||||
private class Sort : UriPartFilter(
|
||||
"Sắp xếp",
|
||||
protected class Sort(
|
||||
displayName: String = "Sắp xếp",
|
||||
sortAZ: String = "A-Z",
|
||||
sortZA: String = "Z-A",
|
||||
sortUpdate: String = "Mới cập nhật",
|
||||
sortNew: String = "Truyện mới",
|
||||
sortPopular: String = "Xem nhiều",
|
||||
sortLike: String = "Được thích nhiều",
|
||||
) : UriPartFilter(
|
||||
displayName,
|
||||
arrayOf(
|
||||
Pair("A-Z", "az"),
|
||||
Pair("Z-A", "za"),
|
||||
Pair("Mới cập nhật", "update"),
|
||||
Pair("Truyện mới", "new"),
|
||||
Pair("Xem nhiều", "top"),
|
||||
Pair("Được thích nhiều", "like"),
|
||||
Pair(sortAZ, "az"),
|
||||
Pair(sortZA, "za"),
|
||||
Pair(sortUpdate, "update"),
|
||||
Pair(sortNew, "new"),
|
||||
Pair(sortPopular, "top"),
|
||||
Pair(sortLike, "like"),
|
||||
),
|
||||
4,
|
||||
)
|
||||
open class Genre(name: String, val id: Int) : Filter.TriState(name)
|
||||
private class Author : Filter.Text("Tác giả")
|
||||
private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Thể loại", genres)
|
||||
protected class Author(displayName: String = "Tác giả") : Filter.Text(displayName)
|
||||
protected class GenreList(genres: List<Genre>, displayName: String = "Thể loại") : Filter.Group<Genre>(displayName, genres)
|
||||
|
||||
override fun getFilterList(): FilterList = FilterList(
|
||||
Author(),
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package eu.kanade.tachiyomi.multisrc.mymangacms
|
||||
|
||||
import generator.ThemeSourceData.MultiLang
|
||||
import generator.ThemeSourceData.SingleLang
|
||||
import generator.ThemeSourceGenerator
|
||||
|
||||
|
@ -9,15 +10,31 @@ class MyMangaCMSGenerator : ThemeSourceGenerator {
|
|||
|
||||
override val themeClass = "MyMangaCMS"
|
||||
|
||||
override val baseVersionCode: Int = 1
|
||||
override val baseVersionCode: Int = 2
|
||||
|
||||
override val sources = listOf(
|
||||
SingleLang(
|
||||
"TruyenTranhLH",
|
||||
"https://truyentranhlh.net",
|
||||
"vi",
|
||||
isNsfw = true,
|
||||
overrideVersionCode = 9,
|
||||
),
|
||||
SingleLang(
|
||||
"Manhwa18",
|
||||
"https://manhwa18.com",
|
||||
"en",
|
||||
isNsfw = true,
|
||||
overrideVersionCode = 9,
|
||||
),
|
||||
MultiLang(
|
||||
"Manhwa18.net",
|
||||
"https://manhwa18.net",
|
||||
listOf("en"),
|
||||
className = "Manhwa18Net",
|
||||
isNsfw = true,
|
||||
overrideVersionCode = 8,
|
||||
),
|
||||
)
|
||||
|
||||
companion object {
|
||||
|
|