From 563e179abe2aa0d7c3dc8dbbd0acfd5aa7b26aa7 Mon Sep 17 00:00:00 2001
From: Luqman <riyanluqman@gmail.com>
Date: Sat, 26 Nov 2022 07:18:48 +0700
Subject: [PATCH] Comic Fx: add project page & series type (#14374)

---
 src/id/comicfx/build.gradle                   |  2 +-
 .../tachiyomi/extension/id/comicfx/ComicFx.kt | 56 +++++++++++++------
 2 files changed, 41 insertions(+), 17 deletions(-)

diff --git a/src/id/comicfx/build.gradle b/src/id/comicfx/build.gradle
index fda7adcc4..d5d69b548 100644
--- a/src/id/comicfx/build.gradle
+++ b/src/id/comicfx/build.gradle
@@ -6,7 +6,7 @@ ext {
     extName = 'Comic Fx'
     pkgNameSuffix = 'id.comicfx'
     extClass = '.ComicFx'
-    extVersionCode = 4
+    extVersionCode = 5
 }
 
 apply from: "$rootDir/common.gradle"
diff --git a/src/id/comicfx/src/eu/kanade/tachiyomi/extension/id/comicfx/ComicFx.kt b/src/id/comicfx/src/eu/kanade/tachiyomi/extension/id/comicfx/ComicFx.kt
index 8acb919b9..b0fa51711 100644
--- a/src/id/comicfx/src/eu/kanade/tachiyomi/extension/id/comicfx/ComicFx.kt
+++ b/src/id/comicfx/src/eu/kanade/tachiyomi/extension/id/comicfx/ComicFx.kt
@@ -41,13 +41,14 @@ class ComicFx : ParsedHttpSource() {
         return GET("$baseUrl/filterList?page=$page&sortBy=name&asc=true", headers)
     }
 
-    override fun popularMangaSelector() = "div.media"
+    // combining selector for "popular" and "latest" to be used for "search" selector as it need both selector
+    override fun popularMangaSelector() = "div.media, div.daftar-komik .komika"
 
     override fun popularMangaFromElement(element: Element): SManga {
         val manga = SManga.create()
-        manga.thumbnail_url = element.select(".media-left a img").attr("abs:data-src")
-        manga.title = element.select(".media-body .media-heading a strong").text()
-        val item = element.select(".media-left a")
+        manga.thumbnail_url = element.select(".media-left a img, .komik-img a .batas img").attr("abs:data-src")
+        manga.title = element.select(".media-body .media-heading a strong, .komik-des a h3").text()
+        val item = element.select(".media-left a, div.komik-img a")
         manga.setUrlWithoutDomain(item.attr("href"))
 
         return manga
@@ -60,17 +61,9 @@ class ComicFx : ParsedHttpSource() {
         return GET("$baseUrl/latest-release?page=$page", headers)
     }
 
-    override fun latestUpdatesSelector() = "div.daftar-komik .komika"
+    override fun latestUpdatesSelector() = popularMangaSelector()
 
-    override fun latestUpdatesFromElement(element: Element): SManga {
-        val manga = SManga.create()
-        manga.thumbnail_url = element.select(".komik-img a .batas img").attr("abs:data-src")
-        manga.title = element.select(".komik-des a h3").text()
-        val item = element.select("div.komik-img a")
-        manga.setUrlWithoutDomain(item.attr("href"))
-
-        return manga
-    }
+    override fun latestUpdatesFromElement(element: Element): SManga = popularMangaFromElement(element)
 
     override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
 
@@ -117,6 +110,14 @@ class ComicFx : ParsedHttpSource() {
                 is TypeFilter -> url.addQueryParameter("ctype", filter.toUriPart())
                 is AuthorFilter -> url.addQueryParameter("author", filter.state)
                 is ArtistFilter -> url.addQueryParameter("artist", filter.state)
+
+                // if site has project page, default value "hasProjectPage" = false
+                is ProjectFilter -> {
+                    if (filter.toUriPart() == "project-filter-on") {
+                        url.setPathSegment(0, "/latest-project".substring(1))
+                    }
+                }
+                else -> { /* Do Nothing */ }
             }
         }
 
@@ -137,7 +138,18 @@ class ComicFx : ParsedHttpSource() {
         artist = document.select(".infolengkap span:contains(Artist) a, #artist").text()
         status = parseStatus(document.select(".infolengkap span:contains(status) i").text())
         description = document.select("div.sinopsis p").text()
-        genre = document.select(".genre-komik a").joinToString { it.text() }
+
+        // Add series type (manga/manhwa/manhua/other) to genre
+        val genres = document.select(".genre-komik a").map { it.text() }.toMutableList()
+        document.selectFirst(".infokomik .type")?.ownText().takeIf { it.isNullOrBlank().not() }?.let { genres.add(it) }
+        genre = genres.map { genre ->
+            genre.lowercase(Locale.forLanguageTag(lang)).replaceFirstChar { char ->
+                if (char.isLowerCase()) char.titlecase(Locale.forLanguageTag(lang))
+                else char.toString()
+            }
+        }
+            .joinToString { it.trim() }
+
         thumbnail_url = document.select(".thumb img").attr("abs:src")
     }
 
@@ -209,7 +221,11 @@ class ComicFx : ParsedHttpSource() {
         StatusFilter(),
         TypeFilter(),
         ArtistFilter("Artist"),
-        AuthorFilter("Author")
+        AuthorFilter("Author"),
+        Filter.Separator(),
+        Filter.Header("NOTE: Can't be used with other filter!"),
+        Filter.Header("$name Project List page"),
+        ProjectFilter(),
     )
 
     private class ArtistFilter(name: String) : Filter.Text(name)
@@ -284,6 +300,14 @@ class ComicFx : ParsedHttpSource() {
         )
     )
 
+    private class ProjectFilter : UriPartFilter(
+        "Filter Project",
+        arrayOf(
+            Pair("", "Show all manga"),
+            Pair("project-filter-on", "Show only project manga")
+        )
+    )
+
     private open class UriPartFilter(displayName: String, val vals: Array<Pair<String, String>>) :
         Filter.Select<String>(displayName, vals.map { it.second }.toTypedArray()) {
         fun toUriPart() = vals[state].first