From 4bc138aa39b5c4a6a77307e50e843adead237506 Mon Sep 17 00:00:00 2001 From: Cuong-Tran Date: Wed, 8 Jan 2025 19:50:03 +0700 Subject: [PATCH] Manga District: add tag browse (#7035) * Manga District: add tag browse * Apply suggestions from code review Co-authored-by: AwkwardPeak7 <48650614+AwkwardPeak7@users.noreply.github.com> * correction * Separate method to load tags from preferences & always initialize with at least 1 tag to avoid excessively reading preferences * remove unnecessary getter * Fix: actually update backing field; also improve load tags from preferences --------- Co-authored-by: AwkwardPeak7 <48650614+AwkwardPeak7@users.noreply.github.com> --- src/en/mangadistrict/build.gradle | 2 +- .../en/mangadistrict/MangaDistrict.kt | 83 +++++++++++++++---- 2 files changed, 68 insertions(+), 17 deletions(-) diff --git a/src/en/mangadistrict/build.gradle b/src/en/mangadistrict/build.gradle index a02ac03d3..e2dce16d6 100644 --- a/src/en/mangadistrict/build.gradle +++ b/src/en/mangadistrict/build.gradle @@ -3,7 +3,7 @@ ext { extClass = '.MangaDistrict' themePkg = 'madara' baseUrl = 'https://mangadistrict.com' - overrideVersionCode = 7 + overrideVersionCode = 8 isNsfw = true } diff --git a/src/en/mangadistrict/src/eu/kanade/tachiyomi/extension/en/mangadistrict/MangaDistrict.kt b/src/en/mangadistrict/src/eu/kanade/tachiyomi/extension/en/mangadistrict/MangaDistrict.kt index 9c372bdb6..3339dea7d 100644 --- a/src/en/mangadistrict/src/eu/kanade/tachiyomi/extension/en/mangadistrict/MangaDistrict.kt +++ b/src/en/mangadistrict/src/eu/kanade/tachiyomi/extension/en/mangadistrict/MangaDistrict.kt @@ -7,7 +7,12 @@ import androidx.preference.ListPreference import androidx.preference.PreferenceScreen import androidx.preference.SwitchPreferenceCompat import eu.kanade.tachiyomi.multisrc.madara.Madara +import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.source.ConfigurableSource +import eu.kanade.tachiyomi.source.model.Filter +import eu.kanade.tachiyomi.source.model.FilterList +import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SManga @@ -17,6 +22,7 @@ import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.Response import org.jsoup.nodes.Document import org.jsoup.nodes.Element +import rx.Observable import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get import java.text.SimpleDateFormat @@ -41,23 +47,13 @@ class MangaDistrict : private val titleVersion = Regex("\\(.*\\)") - override fun popularMangaFromElement(element: Element): SManga { - return super.popularMangaFromElement(element).apply { - if (isRemoveTitleVersion()) { - title = this.title.replace(titleVersion, "").trim() - } - } - } - - override fun searchMangaFromElement(element: Element): SManga { - return super.searchMangaFromElement(element).apply { - if (isRemoveTitleVersion()) { - title = this.title.replace(titleVersion, "").trim() - } - } - } - override fun mangaDetailsParse(document: Document): SManga { + val tags = document.select(mangaDetailsSelectorTag).mapNotNull { element -> + element.ownText() to element.attr("href") + .removeSuffix("/").substringAfterLast('/') + } + tagList = tagList.plus(tags) + return super.mangaDetailsParse(document).apply { if (isRemoveTitleVersion()) { title = this.title.replace(titleVersion, "").trim() @@ -103,6 +99,60 @@ class MangaDistrict : return super.pageListParse(document) } + override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable { + val tagFilter = filters.filterIsInstance().firstOrNull() + if (tagFilter != null && tagFilter.state > 0) { + val urlBuilder = baseUrl.toHttpUrl().newBuilder() + urlBuilder.addPathSegment("publication-tag") + urlBuilder.addPathSegment(tagFilter.toUriPart()) + urlBuilder.addPathSegments("page/$page") + return client.newCall(GET(urlBuilder.build(), headers)) + .asObservableSuccess().map { response -> + popularMangaParse(response) + } + } else { + return super.fetchSearchManga(page, query, filters) + } + } + + private fun loadTagListFromPreferences(): Set> = + preferences.getStringSet(TAG_LIST_PREF, emptySet()) + ?.mapNotNull { + it.split('|') + .let { splits -> + if (splits.size == 2) { + splits[0] to splits[1] + } else { + null + } + } + } + ?.toSet() + // Create at least 1 tag to avoid excessively reading preferences + .let { if (it.isNullOrEmpty()) setOf("Manhwa" to "manhwa") else it } + + private var tagList: Set> = loadTagListFromPreferences() + set(value) { + preferences.edit().putStringSet( + TAG_LIST_PREF, + value.map { "${it.first}|${it.second}" }.toSet(), + ).apply() + field = value + } + + override fun getFilterList(): FilterList { + val filters = super.getFilterList().list.toMutableList() + if (tagList.isNotEmpty()) { + filters += Filter.Separator() + filters += Filter.Header("Tag browse will ignore other filters") + filters += TagList("Tag browse", listOf(Pair("", "")) + tagList.toList()) + } + return FilterList(filters) + } + + private class TagList(title: String, options: List>, state: Int = 0) : + UriPartFilter(title, options.toTypedArray(), state) + private fun String.urlKey(): String { return toHttpUrl().pathSegments.let { path -> "${path[1]}/${path[2]}" @@ -154,6 +204,7 @@ class MangaDistrict : companion object { private const val REMOVE_TITLE_VERSION_PREF = "REMOVE_TITLE_VERSION" + private const val TAG_LIST_PREF = "TAG_LIST" private const val IMG_RES_PREF = "IMG_RES" private const val IMG_RES_ALL = "all"