From 8a14edfd481dafa30042c59b06d4df43e7b37ef2 Mon Sep 17 00:00:00 2001
From: BrutuZ <BrutuZ@users.noreply.github.com>
Date: Mon, 17 Mar 2025 11:47:21 -0300
Subject: [PATCH] Comick: Localized title setting (#8111)

* Localized title preference

* lint
---
 .../assets/i18n/messages_en.properties        |  3 ++
 .../assets/i18n/messages_pt_br.properties     |  3 ++
 src/all/comickfun/build.gradle                |  2 +-
 .../extension/all/comickfun/Comick.kt         | 29 +++++++++++++++++++
 .../tachiyomi/extension/all/comickfun/Dto.kt  | 21 ++++++++++----
 5 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/src/all/comickfun/assets/i18n/messages_en.properties b/src/all/comickfun/assets/i18n/messages_en.properties
index 730dec604..03a42c222 100644
--- a/src/all/comickfun/assets/i18n/messages_en.properties
+++ b/src/all/comickfun/assets/i18n/messages_en.properties
@@ -12,6 +12,9 @@ group_tags_off=List all tags together
 update_cover_title=Update Covers
 update_cover_on=Keep cover updated
 update_cover_off=Prefer first cover
+local_title_title=Translated Title
+local_title_on=if available
+local_title_off=Use the default title from the site
 score_position_title=Score Position in the Description
 score_position_top=Top
 score_position_middle=Middle
diff --git a/src/all/comickfun/assets/i18n/messages_pt_br.properties b/src/all/comickfun/assets/i18n/messages_pt_br.properties
index d6bfc870d..5315e3d29 100644
--- a/src/all/comickfun/assets/i18n/messages_pt_br.properties
+++ b/src/all/comickfun/assets/i18n/messages_pt_br.properties
@@ -12,6 +12,9 @@ group_tags_off=Listar todas as tags juntas
 update_cover_title=Atualizar Capas
 update_cover_on=Manter capas atualizadas
 update_cover_off=Usar apenas a primeira capa
+local_title_title=Título Traduzido
+local_title_on=se disponível
+local_title_off=Usar o título padrão do site
 score_position_title=Posição da Nota na Descrição
 score_position_top=Topo
 score_position_middle=Meio
diff --git a/src/all/comickfun/build.gradle b/src/all/comickfun/build.gradle
index 70e4b1ea8..be0b916f0 100644
--- a/src/all/comickfun/build.gradle
+++ b/src/all/comickfun/build.gradle
@@ -1,7 +1,7 @@
 ext {
     extName = 'Comick'
     extClass = '.ComickFactory'
-    extVersionCode = 54
+    extVersionCode = 55
     isNsfw = true
 }
 
diff --git a/src/all/comickfun/src/eu/kanade/tachiyomi/extension/all/comickfun/Comick.kt b/src/all/comickfun/src/eu/kanade/tachiyomi/extension/all/comickfun/Comick.kt
index 796fdb8c0..94e00520a 100644
--- a/src/all/comickfun/src/eu/kanade/tachiyomi/extension/all/comickfun/Comick.kt
+++ b/src/all/comickfun/src/eu/kanade/tachiyomi/extension/all/comickfun/Comick.kt
@@ -135,6 +135,20 @@ abstract class Comick(
             }
         }.also(screen::addPreference)
 
+        SwitchPreferenceCompat(screen.context).apply {
+            key = LOCAL_TITLE_PREF
+            title = intl["local_title_title"]
+            summaryOff = intl["local_title_off"]
+            summaryOn = intl["local_title_on"]
+            setDefaultValue(LOCAL_TITLE_DEFAULT)
+
+            setOnPreferenceChangeListener { _, newValue ->
+                preferences.edit()
+                    .putBoolean(LOCAL_TITLE_PREF, newValue as Boolean)
+                    .commit()
+            }
+        }.also(screen::addPreference)
+
         ListPreference(screen.context).apply {
             key = SCORE_POSITION_PREF
             title = intl["score_position_title"]
@@ -182,6 +196,17 @@ abstract class Comick(
     private val SharedPreferences.updateCover: Boolean
         get() = getBoolean(FIRST_COVER_PREF, FIRST_COVER_DEFAULT)
 
+    private val SharedPreferences.localTitle: String
+        get() = if (getBoolean(
+                LOCAL_TITLE_PREF,
+                LOCAL_TITLE_DEFAULT,
+            )
+        ) {
+            comickLang.lowercase()
+        } else {
+            "all"
+        }
+
     private val SharedPreferences.scorePosition: String
         get() = getString(SCORE_POSITION_PREF, SCORE_POSITION_DEFAULT) ?: SCORE_POSITION_DEFAULT
 
@@ -437,6 +462,7 @@ abstract class Comick(
                 showAlternativeTitles = preferences.showAlternativeTitles,
                 covers = localCovers.ifEmpty { originalCovers }.ifEmpty { firstVol },
                 groupTags = preferences.groupTags,
+                titleLang = preferences.localTitle,
             )
         }
         return mangaData.toSManga(
@@ -444,6 +470,7 @@ abstract class Comick(
             scorePosition = preferences.scorePosition,
             showAlternativeTitles = preferences.showAlternativeTitles,
             groupTags = preferences.groupTags,
+            titleLang = preferences.localTitle,
         )
     }
 
@@ -571,6 +598,8 @@ abstract class Comick(
         private const val FIRST_COVER_DEFAULT = true
         private const val SCORE_POSITION_PREF = "ScorePosition"
         const val SCORE_POSITION_DEFAULT = "top"
+        private const val LOCAL_TITLE_PREF = "LocalTitle"
+        private const val LOCAL_TITLE_DEFAULT = false
         private const val LIMIT = 20
         private const val CHAPTERS_LIMIT = 99999
     }
diff --git a/src/all/comickfun/src/eu/kanade/tachiyomi/extension/all/comickfun/Dto.kt b/src/all/comickfun/src/eu/kanade/tachiyomi/extension/all/comickfun/Dto.kt
index 8e987c8d3..8bed4379d 100644
--- a/src/all/comickfun/src/eu/kanade/tachiyomi/extension/all/comickfun/Dto.kt
+++ b/src/all/comickfun/src/eu/kanade/tachiyomi/extension/all/comickfun/Dto.kt
@@ -40,11 +40,17 @@ class Manga(
         showAlternativeTitles: Boolean = SHOW_ALTERNATIVE_TITLES_DEFAULT,
         covers: List<MDcovers>? = null,
         groupTags: Boolean = GROUP_TAGS_DEFAULT,
-    ) =
-        SManga.create().apply {
+        titleLang: String,
+    ): SManga {
+        val entryTitle = comic.altTitles.firstOrNull {
+            titleLang != "all" && !it.lang.isNullOrBlank() && titleLang.startsWith(it.lang)
+        }?.title ?: comic.title
+        val titles = listOf(Title(title = comic.title)) + comic.altTitles
+
+        return SManga.create().apply {
             // appennding # at end as part of migration from slug to hid
             url = "/comic/${comic.hid}#"
-            title = comic.title
+            title = entryTitle
             description = buildString {
                 if (scorePosition == "top") append(comic.fancyScore)
                 val desc = comic.desc?.beautifyDescription()
@@ -60,9 +66,10 @@ class Manga(
                     if (this.isNotEmpty()) append("\n\n")
                     append("Alternative Titles:\n")
                     append(
-                        comic.altTitles.mapNotNull { title ->
-                            title.title?.let { "• $it" }
-                        }.joinToString("\n"),
+                        titles.distinctBy { it.title }.filter { it.title != entryTitle }
+                            .mapNotNull { title ->
+                                title.title?.let { "• $it" }
+                            }.joinToString("\n"),
                     )
                 }
                 if (scorePosition == "bottom") {
@@ -97,6 +104,7 @@ class Manga(
                 .filterNot { it.name.isNullOrBlank() || it.group.isNullOrBlank() }
                 .joinToString { if (groupTags) "${it.group}:${it.name?.trim()}" else "${it.name?.trim()}" }
         }
+    }
 }
 
 @Serializable
@@ -171,6 +179,7 @@ class MDcovers(
 @Serializable
 class Title(
     val title: String?,
+    val lang: String? = null,
 )
 
 @Serializable