From 33f4d5f8c0511184cf65870f91a8a0670c5a4ea4 Mon Sep 17 00:00:00 2001 From: marioplus Date: Sat, 27 Sep 2025 20:22:34 +0800 Subject: [PATCH] fix(YellowNote): adapt to web page structure changes (#10235) * fix(YellowNote): adapt to web page structure changes * feat(YellowNote): make adjustments according to the reviewer's suggestions - use stable value to pase date string - inline selector - combine two operations into one using mapIndexed() * fix(YellowNote): correct image selector * fix(YellowNote): correct data parse * fix(YellowNote): correct data parse * fix(YellowNote): properly adapt to new languages - Implement correct language adaptation - Add settings for language selection, defaulting to system language if unset - Use English for unsupported languages - Fix incorrect formatMediaCount extraction * fix(YellowNote): update date parsing logic from version info * chore(YellowNote): remove log * chore(YellowNote): remove unused multilingual content * fix(YellowNote): optimize Chinese language tag logic - Simplify Chinese language tag conditions - Add support for Simplified Chinese in Singapore (SG) region - Fix potential incorrect default language tagging * fix(YellowNote): override id * feat(YellowNote): add language switch notification and optimize config - Add success notification for language switching - Remove redundant getStringOrDefault implementation * fix(YellowNote): use tryParse --- .../assets/i18n/messages_en.properties | 4 + .../assets/i18n/messages_es.properties | 5 +- .../assets/i18n/messages_ko.properties | 5 +- .../assets/i18n/messages_zh_hans.properties | 3 + .../assets/i18n/messages_zh_hant.properties | 3 + src/all/yellownote/build.gradle | 4 +- .../extension/all/yellownote/LanguageUtils.kt | 57 +++++++ .../extension/all/yellownote/YellowNote.kt | 139 ++++++++++++------ .../all/yellownote/YellowNotePreferences.kt | 95 ++++++++---- .../all/yellownote/YellowNoteSourceFactory.kt | 25 ---- 10 files changed, 235 insertions(+), 105 deletions(-) create mode 100644 src/all/yellownote/src/eu/kanade/tachiyomi/extension/all/yellownote/LanguageUtils.kt delete mode 100644 src/all/yellownote/src/eu/kanade/tachiyomi/extension/all/yellownote/YellowNoteSourceFactory.kt diff --git a/src/all/yellownote/assets/i18n/messages_en.properties b/src/all/yellownote/assets/i18n/messages_en.properties index 60a2ff325..4c35f8c23 100644 --- a/src/all/yellownote/assets/i18n/messages_en.properties +++ b/src/all/yellownote/assets/i18n/messages_en.properties @@ -78,3 +78,7 @@ config.domain.dialog.message=Default domain: config.domain.toast.changed-success=Domain changed successfully. It will take effect after restarting the app. config.domain.toast.changed-failed=Invalid domain! +config.language.title=Language +config.language.summary=Set extension language. Effective after restart. +config.language.changed-success=Language changed successfully. It will take effect after restarting the app. +config.language.changed-success=Language changed successfully. It will take effect after restarting the app. diff --git a/src/all/yellownote/assets/i18n/messages_es.properties b/src/all/yellownote/assets/i18n/messages_es.properties index 6ce66738a..87eedba79 100644 --- a/src/all/yellownote/assets/i18n/messages_es.properties +++ b/src/all/yellownote/assets/i18n/messages_es.properties @@ -76,7 +76,10 @@ filter.category.option.others-ai-photos=Otras: AI Photos config.domain.title=Configuración de dominio config.domain.summary=Si el dominio actual está bloqueado, puedes cambiarlo manualmente aquí. Se aplicará después de reiniciar la aplicación. config.domain.dialog.title=Configuración de dominio -config.domain.dialog.message=Dominio predeterminado: +config.domain.dialog.message=Dominio predeterminado: config.domain.toast.changed-success=Dominio cambiado correctamente. Se aplicará tras reiniciar la aplicación. config.domain.toast.changed-failed=¡Dominio no válido! +config.language.title=Idioma +config.language.summary=Configurar idioma de la extensión. Efectivo tras reiniciar. +config.language.changed-success=Idioma cambiado correctamente. Se aplicará al reiniciar la aplicación. diff --git a/src/all/yellownote/assets/i18n/messages_ko.properties b/src/all/yellownote/assets/i18n/messages_ko.properties index 18641b970..3d4081159 100644 --- a/src/all/yellownote/assets/i18n/messages_ko.properties +++ b/src/all/yellownote/assets/i18n/messages_ko.properties @@ -76,7 +76,10 @@ filter.category.option.others-ai-photos=기타: AI 사진 config.domain.title=도메인 설정 config.domain.summary=현재 도메인이 차단된 경우, 여기에서 수동으로 변경할 수 있습니다. 앱을 재시작하면 적용됩니다. config.domain.dialog.title=도메인 설정 -config.domain.dialog.message=기본 도메인: +config.domain.dialog.message=기본 도메인: config.domain.toast.changed-success=도메인이 변경되었습니다. 앱을 재시작하면 적용됩니다. config.domain.toast.changed-failed=유효하지 않은 도메인입니다! +config.language.title=언어 +config.language.summary=확장 프로그램 사용 언어 설정. 재실행 후 적용됩니다. +config.language.changed-success=언어 변경 성공. 앱 재시작 후 적용됩니다. diff --git a/src/all/yellownote/assets/i18n/messages_zh_hans.properties b/src/all/yellownote/assets/i18n/messages_zh_hans.properties index 0aab0502e..abf131754 100644 --- a/src/all/yellownote/assets/i18n/messages_zh_hans.properties +++ b/src/all/yellownote/assets/i18n/messages_zh_hans.properties @@ -80,3 +80,6 @@ config.domain.dialog.message=默认域名: config.domain.toast.changed-success=已更换域名,重启应用后生效。 config.domain.toast.changed-failed=无效域名! +config.language.title=语言 +config.language.summary=设置拓展使用的语言。重启应用后生效。 +config.language.changed-success=语言修改成功。重启应用后生效。 diff --git a/src/all/yellownote/assets/i18n/messages_zh_hant.properties b/src/all/yellownote/assets/i18n/messages_zh_hant.properties index c58ebbc48..d83a4b9e8 100644 --- a/src/all/yellownote/assets/i18n/messages_zh_hant.properties +++ b/src/all/yellownote/assets/i18n/messages_zh_hant.properties @@ -78,3 +78,6 @@ config.domain.dialog.message=預設網域: config.domain.toast.changed-success=網域已更換,重新啟動應用後生效。 config.domain.toast.changed-failed=無效的網域! +config.language.title= 語言 +config.language.summary= 設定擴充功能使用的語言。重啓應用後生效。 +config.language.changed-success=語言修改成功。重啓應用後生效。 diff --git a/src/all/yellownote/build.gradle b/src/all/yellownote/build.gradle index a09ed699b..de5b33270 100644 --- a/src/all/yellownote/build.gradle +++ b/src/all/yellownote/build.gradle @@ -1,7 +1,7 @@ ext { extName = 'YellowNote' - extClass = '.YellowNoteSourceFactory' - extVersionCode = 1 + extClass = '.YellowNote' + extVersionCode = 2 isNsfw = true } diff --git a/src/all/yellownote/src/eu/kanade/tachiyomi/extension/all/yellownote/LanguageUtils.kt b/src/all/yellownote/src/eu/kanade/tachiyomi/extension/all/yellownote/LanguageUtils.kt new file mode 100644 index 000000000..791f59dde --- /dev/null +++ b/src/all/yellownote/src/eu/kanade/tachiyomi/extension/all/yellownote/LanguageUtils.kt @@ -0,0 +1,57 @@ +package eu.kanade.tachiyomi.extension.all.yellownote + +import android.os.Build +import android.os.LocaleList +import java.util.Locale + +object LanguageUtils { + + val baseLocale = Locale.ENGLISH + + private val languageToSubdomainMap = mapOf( + "en" to "en", + "es" to "es", + "ko" to "kr", + "zh-Hans" to null, + "zh-Hant" to "tw", + ) + + private val languageToDisplayNameMap = mapOf( + "en" to "English", + "es" to "Español", + "ko" to "한국어", + "zh-Hans" to "简体中文", + "zh-Hant" to "繁體中文", + ) + + val supportedLocaleTags = languageToSubdomainMap.keys.toTypedArray() + + fun getDefaultLanguage(): String { + val defaultLocale = + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + LocaleList.getDefault().getFirstMatch(supportedLocaleTags) ?: baseLocale + } else { + Locale.getDefault() + } + + return when { + defaultLocale.script == "Hant" -> "zh-Hant" + defaultLocale.script == "Hans" -> "zh-Hans" + defaultLocale.country in listOf("TW", "HK", "MO") -> "zh-Hant" + defaultLocale.country in listOf("CN", "SG") -> "zh-Hans" + else -> baseLocale.language + } + } + + fun getSubdomainByLanguage(lang: String): String? { + return languageToSubdomainMap[lang] + } + + fun getSupportedLanguageKeys(): Array { + return languageToDisplayNameMap.keys.toTypedArray() + } + + fun getSupportedLanguageDisplayNames(): Array { + return languageToDisplayNameMap.values.toTypedArray() + } +} diff --git a/src/all/yellownote/src/eu/kanade/tachiyomi/extension/all/yellownote/YellowNote.kt b/src/all/yellownote/src/eu/kanade/tachiyomi/extension/all/yellownote/YellowNote.kt index 3b6b906ae..4ce56b665 100644 --- a/src/all/yellownote/src/eu/kanade/tachiyomi/extension/all/yellownote/YellowNote.kt +++ b/src/all/yellownote/src/eu/kanade/tachiyomi/extension/all/yellownote/YellowNote.kt @@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.extension.all.yellownote import androidx.preference.PreferenceScreen import eu.kanade.tachiyomi.extension.all.yellownote.YellowNoteFilters.SortSelector import eu.kanade.tachiyomi.extension.all.yellownote.YellowNotePreferences.baseUrl +import eu.kanade.tachiyomi.extension.all.yellownote.YellowNotePreferences.language import eu.kanade.tachiyomi.extension.all.yellownote.YellowNotePreferences.preferenceMigration import eu.kanade.tachiyomi.lib.i18n.Intl import eu.kanade.tachiyomi.network.GET @@ -25,12 +26,12 @@ import org.jsoup.nodes.Element import java.text.SimpleDateFormat import java.util.Locale -class YellowNote( - override val lang: String, - private val subdomain: String? = null, -) : SimpleParsedHttpSource(), ConfigurableSource { +class YellowNote : SimpleParsedHttpSource(), ConfigurableSource { - override val baseUrl by lazy { preferences.baseUrl(subdomain) } + override val id get() = 170542391855030753 + + override val lang = "all" + override val baseUrl by lazy { preferences.baseUrl() } override val name = "小黄书" @@ -44,77 +45,109 @@ class YellowNote( .add("Referer", "$baseUrl/") private val intl = Intl( - language = lang, - baseLanguage = YellowNoteSourceFactory.BASE_LANGUAGE, - availableLanguages = YellowNoteSourceFactory.SUPPORT_LANGUAGES, + language = preferences.language(), + baseLanguage = LanguageUtils.baseLocale.language, + availableLanguages = LanguageUtils.supportedLocaleTags.toSet(), classLoader = this::class.java.classLoader!!, ) - private val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.US) + private val dateFormat = SimpleDateFormat("yyyy.MM.dd", Locale.US) - private val styleUrlRegex = """url\(['"]?([^'"]+)['"]?\)""".toRegex() + // yyyy.MM.dd + private val dateRegex = """\d{4}\.\d{2}\.\d{2}""".toRegex() + + // + private val styleUrlRegex = """background-image\s*:\s*url\('([^']+)'\)""".toRegex() + + // 100P + 2V + private val mediaCountRegex = """\d+P( \+ \d+V)?""".toRegex() override fun setupPreferenceScreen(screen: PreferenceScreen) { YellowNotePreferences.buildPreferences(screen.context, intl) .forEach(screen::addPreference) } - override fun simpleMangaSelector() = "div.article > div.list > div.item:not([class*=item exoclick_300x500])" + override fun simpleMangaSelector() = + "div.list.photo-list > div.item.photo, div.list.amateur-list > div.item.amateur" - override fun simpleMangaFromElement(element: Element): SManga { - if (element.hasClass("amateur")) { - return simpleMangaFromElementByAmateur(element) - } + override fun simpleMangaFromElement(element: Element) = SManga.create().apply { + val mangaEl = element.selectFirst("a")!! + setUrlWithoutDomain(mangaEl.absUrl("href")) - return SManga.create().apply { - val imgEl = element.selectFirst("img")!! - val titleAppend = element.selectFirst("div.tag > div")?.text()?.let { "($it)" }.orEmpty() - title = "${imgEl.attr("alt")}$titleAppend" + val formatMediaCount = element.select("div.tags > div") + .map { it.text() } + .firstOrNull { mediaCountRegex.matches(it) } + ?.let { "($it)" } + .orEmpty() + title = "${mangaEl.attr("title")}$formatMediaCount" - thumbnail_url = imgEl.absUrl("src") - update_strategy = UpdateStrategy.ONLY_FETCH_ONCE - setUrlWithoutDomain(element.selectFirst("a")!!.absUrl("href")) - } + thumbnail_url = parseUrlFormStyle(mangaEl.selectFirst("div.img")) + + update_strategy = UpdateStrategy.ONLY_FETCH_ONCE } - // /amateurs - private fun simpleMangaFromElementByAmateur(element: Element) = SManga.create().apply { - val titleAppend = element.selectFirst("div.tag > div")?.text()?.let { "($it)" }.orEmpty() - title = "${element.selectFirst("div:nth-child(3)")!!.text()}$titleAppend" - - thumbnail_url = element.selectFirst(".img")?.attr("style") + fun parseUrlFormStyle(element: Element?): String? { + return element + ?.attr("style") ?.let { styleUrlRegex.find(it) } ?.groupValues ?.get(1) - - update_strategy = UpdateStrategy.ONLY_FETCH_ONCE - setUrlWithoutDomain(element.selectFirst("a[href]")!!.absUrl("href")) } - override fun simpleNextPageSelector() = "div.pager:first-of-type a[current] + a[href]" + override fun simpleNextPageSelector() = + "div.pager:first-of-type > span.pager-num.current + a.pager-num" - override fun popularMangaRequest(page: Int) = GET("$baseUrl/photos/sort-hot/$page.html", headers) + override fun popularMangaRequest(page: Int) = + GET("$baseUrl/photos/sort-hot/$page.html", headers) override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/photos/$page.html", headers) override fun mangaDetailsParse(document: Document) = SManga.create().apply { - val tabEl = document.selectFirst("div#tab_1")!! - val titleAppend = tabEl.selectFirst("i.fa.fa-picture-o")?.parentText()?.let { "($it)" }.orEmpty() - title = "${tabEl.selectFirst("i.fa.fa-address-card-o")!!.parentText()!!}$titleAppend" + val infoCardElement = document.selectFirst("div.info-card.photo-detail")!! + val name = parseInfoByIcon(infoCardElement, "i.fa-address-card")!! + val mediaCount = parseInfoByIcon(infoCardElement, "i.fa-image")!! + val no = parseInfoByIcon(infoCardElement, "i.fa-file")?.let { " $it" }.orEmpty() + val categories = + parseInfosByIcon(infoCardElement, "i.fa-video-camera")?.filter { it != "-" } + val filters = parseInfosByIcon(infoCardElement, "i.fa-filter") + val tags = parseInfosByIcon(infoCardElement, "i.fa-tags") - author = tabEl.select("div.models > a").joinToString { it.text() } - genre = tabEl.select("div.contentTag").joinToString { it.text() } + title = "$name$no($mediaCount)" + author = infoCardElement.selectFirst("div.item.floating") + ?.text() + ?: parseInfoByIcon(infoCardElement, "i.fa-circle-user") + genre = listOfNotNull(categories, filters, tags) + .flatten() + .takeIf { it.isNotEmpty() } + ?.joinToString(", ") status = SManga.COMPLETED - description = tabEl.selectFirst("i.fa.fa-calendar")?.text() update_strategy = UpdateStrategy.ONLY_FETCH_ONCE } + private fun parseInfosByIcon(infoCardElement: Element, iconClass: String): List? { + return infoCardElement + .selectFirst("div.item:has(.icon > $iconClass)") + ?.selectFirst("div.text") + ?.children() + ?.map { it.text() } + } + + private fun parseInfoByIcon(infoCardElement: Element, iconClass: String): String? { + return infoCardElement + .selectFirst("div.item:has(.icon > $iconClass)") + ?.selectFirst("div.text") + ?.text() + } + override fun chapterFromElement(element: Element) = throw UnsupportedOperationException() override fun chapterListParse(response: Response): List { val doc = response.asJsoup() - val dateUploadStr = doc.selectFirst("i.fa.fa-calendar")?.text() - val dateUpload = dateFormat.tryParse(dateUploadStr) - val maxPage = doc.select("div.pager:first-of-type a:not([class])").last()?.text()?.toInt() ?: 1 + val infoCardElement = doc.selectFirst("div.info-card.photo-detail")!! + val uploadAt = parseInfoByIcon(infoCardElement, "i.fa-calendar-days") + ?.let { dateFormat.tryParse(it) } + ?: parseUploadDateFromVersionInfo(doc) + ?: 0L + val maxPage = doc.select("div.pager:first-of-type a.pager-num").last()?.text()?.toInt() ?: 1 val basePageUrl = response.request.url.toString() .removeSuffix(".html") return (maxPage downTo 1).map { page -> @@ -122,14 +155,28 @@ class YellowNote( chapter_number = 0F setUrlWithoutDomain("$basePageUrl/$page.html") name = "Page $page" - date_upload = dateUpload + date_upload = uploadAt } } } + private fun parseUploadDateFromVersionInfo(doc: Document): Long? { + for (info in doc.select("div.tab-content > div.info-card div.text")) { + val date = dateRegex.find(info.text()) ?: continue + return dateFormat.tryParse(date.value) + } + return null + } + + private val imageSelector = + "div.list.photo-items > div.item.photo-image, div.list.amateur-items > div.item.amateur-image" + override fun pageListParse(document: Document): List { - return document.select("div.article.mask .photos img.cr_only") - .mapIndexed { i, imgEl -> Page(i, imageUrl = imgEl!!.absUrl("src")) } + return document.select(imageSelector) + .mapIndexed { i, imageElement -> + val url = parseUrlFormStyle(imageElement.selectFirst("div.img"))!! + Page(i, imageUrl = url) + } } override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { diff --git a/src/all/yellownote/src/eu/kanade/tachiyomi/extension/all/yellownote/YellowNotePreferences.kt b/src/all/yellownote/src/eu/kanade/tachiyomi/extension/all/yellownote/YellowNotePreferences.kt index 14ae63886..398b933c4 100644 --- a/src/all/yellownote/src/eu/kanade/tachiyomi/extension/all/yellownote/YellowNotePreferences.kt +++ b/src/all/yellownote/src/eu/kanade/tachiyomi/extension/all/yellownote/YellowNotePreferences.kt @@ -4,6 +4,8 @@ import android.content.Context import android.content.SharedPreferences import android.widget.Toast import androidx.preference.EditTextPreference +import androidx.preference.ListPreference +import androidx.preference.Preference import eu.kanade.tachiyomi.lib.i18n.Intl import okhttp3.HttpUrl.Companion.toHttpUrl @@ -13,17 +15,13 @@ object YellowNotePreferences { private const val PS_KEY_DOMAIN = "$PS_KEY_ROOT::DOMAIN" private const val PS_KEY_DOMAIN_DEFAULT = "$PS_KEY_DOMAIN::DEFAULT" private const val PS_KEY_DOMAIN_OVERRIDE = "$PS_KEY_DOMAIN::OVERRIDE" + private const val PS_KEY_LANGUAGE = "$PS_KEY_ROOT::LANGUAGE" private const val DEFAULT_DOMAIN = "https://xchina.co" - private fun SharedPreferences.getStringOrDefaultIfBlank(key: String, defValue: String): String { - val value = getString(key, defValue)!! - return value.ifBlank { defValue } - } - internal fun SharedPreferences.preferenceMigration() { // refresh when DEFAULT_DOMAIN update - val defaultDomain = getStringOrDefaultIfBlank(PS_KEY_DOMAIN_DEFAULT, DEFAULT_DOMAIN) + val defaultDomain = getString(PS_KEY_DOMAIN_DEFAULT, DEFAULT_DOMAIN)!! if (DEFAULT_DOMAIN != defaultDomain) { edit() .putString(PS_KEY_DOMAIN_DEFAULT, DEFAULT_DOMAIN) @@ -32,9 +30,10 @@ object YellowNotePreferences { } } - internal fun SharedPreferences.baseUrl(subdomain: String?): String { - val httpUrl = getStringOrDefaultIfBlank(PS_KEY_DOMAIN_OVERRIDE, DEFAULT_DOMAIN).toHttpUrl() - + internal fun SharedPreferences.baseUrl(): String { + val lang = language() + val subdomain = LanguageUtils.getSubdomainByLanguage(lang) + val httpUrl = getString(PS_KEY_DOMAIN_OVERRIDE, DEFAULT_DOMAIN)!!.toHttpUrl() val newHost = when { httpUrl.host.split('.').size > 2 || subdomain == null -> httpUrl.host else -> "$subdomain.${httpUrl.host}" @@ -48,28 +47,64 @@ object YellowNotePreferences { .removeSuffix("/") } - internal fun buildPreferences(context: Context, intl: Intl): List { + internal fun SharedPreferences.language(): String { + return getString(PS_KEY_LANGUAGE, "")!!.ifBlank { LanguageUtils.getDefaultLanguage() } + } + + internal fun buildPreferences(context: Context, intl: Intl): List { return listOf( - EditTextPreference(context).apply { - key = PS_KEY_DOMAIN_OVERRIDE - title = intl["config.domain.title"] - summary = intl["config.domain.summary"] - dialogTitle = intl["config.domain.dialog.title"] - dialogMessage = "${intl["config.domain.dialog.message"]}$DEFAULT_DOMAIN" - - setDefaultValue(DEFAULT_DOMAIN) - setOnPreferenceChangeListener { _, newValue -> - try { - (newValue as String).toHttpUrl() - } catch (e: IllegalArgumentException) { - Toast.makeText(context, intl["config.domain.toast.changed-failed"], Toast.LENGTH_LONG).show() - return@setOnPreferenceChangeListener false - } - - Toast.makeText(context, intl["config.domain.toast.changed-success"], Toast.LENGTH_LONG).show() - true - } - }, + buildDomainPreference(context, intl), + buildLanguagePreference(context, intl), ) } + + internal fun buildDomainPreference(context: Context, intl: Intl): Preference { + return EditTextPreference(context).apply { + key = PS_KEY_DOMAIN_OVERRIDE + title = intl["config.domain.title"] + summary = intl["config.domain.summary"] + dialogTitle = intl["config.domain.dialog.title"] + dialogMessage = "${intl["config.domain.dialog.message"]}$DEFAULT_DOMAIN" + + setDefaultValue(DEFAULT_DOMAIN) + setOnPreferenceChangeListener { _, newValue -> + try { + (newValue as String).toHttpUrl() + } catch (_: IllegalArgumentException) { + Toast.makeText( + context, + intl["config.domain.toast.changed-failed"], + Toast.LENGTH_LONG, + ).show() + return@setOnPreferenceChangeListener false + } + + Toast.makeText( + context, + intl["config.domain.toast.changed-success"], + Toast.LENGTH_LONG, + ).show() + true + } + } + } + + internal fun buildLanguagePreference(context: Context, intl: Intl): Preference { + return ListPreference(context).apply { + key = PS_KEY_LANGUAGE + title = intl["config.language.title"] + summary = intl["config.language.summary"] + entries = LanguageUtils.getSupportedLanguageDisplayNames() + entryValues = LanguageUtils.getSupportedLanguageKeys() + setDefaultValue("") + setOnPreferenceChangeListener { _, newValue -> + Toast.makeText( + context, + intl["config.language.changed-success"], + Toast.LENGTH_LONG, + ).show() + true + } + } + } } diff --git a/src/all/yellownote/src/eu/kanade/tachiyomi/extension/all/yellownote/YellowNoteSourceFactory.kt b/src/all/yellownote/src/eu/kanade/tachiyomi/extension/all/yellownote/YellowNoteSourceFactory.kt deleted file mode 100644 index f458324ed..000000000 --- a/src/all/yellownote/src/eu/kanade/tachiyomi/extension/all/yellownote/YellowNoteSourceFactory.kt +++ /dev/null @@ -1,25 +0,0 @@ -package eu.kanade.tachiyomi.extension.all.yellownote - -import eu.kanade.tachiyomi.source.SourceFactory - -class YellowNoteSourceFactory : SourceFactory { - - companion object { - const val BASE_LANGUAGE = "en" - val SUPPORT_LANGUAGES = setOf( - "en", - "es", - "ko", - "zh-Hans", - "zh-Hant", - ) - } - - override fun createSources() = listOf( - YellowNote("en", "en"), - YellowNote("es", "es"), - YellowNote("ko", "kr"), - YellowNote("zh-Hans"), - YellowNote("zh-Hant", "tw"), - ) -}