From 9203dc0112690675e243ac60bb73c2ab3dd09c7c Mon Sep 17 00:00:00 2001 From: tom5079 Date: Tue, 13 Oct 2020 13:51:53 +0900 Subject: [PATCH] Tag translation --- app/release/output-metadata.json | 4 +- .../xyz/quaver/pupil/types/Suggestions.kt | 7 +- .../java/xyz/quaver/pupil/ui/MainActivity.kt | 6 +- .../pupil/ui/fragment/SettingsFragment.kt | 33 ++++++++-- .../pupil/ui/view/FloatingSearchView.kt | 4 +- .../java/xyz/quaver/pupil/ui/view/TagChip.kt | 3 +- .../main/java/xyz/quaver/pupil/util/misc.kt | 11 +++- .../java/xyz/quaver/pupil/util/translation.kt | 66 +++++++++++++++++++ app/src/main/res/values-ja/strings.xml | 2 + app/src/main/res/values-ko/strings.xml | 2 + app/src/main/res/values/strings.xml | 2 + app/src/main/res/xml/root_preferences.xml | 9 ++- 12 files changed, 133 insertions(+), 16 deletions(-) create mode 100644 app/src/main/java/xyz/quaver/pupil/util/translation.kt diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json index d69aff38..261a5224 100644 --- a/app/release/output-metadata.json +++ b/app/release/output-metadata.json @@ -11,8 +11,8 @@ "type": "SINGLE", "filters": [], "properties": [], - "versionCode": 62, - "versionName": "5.1.3-hotfix1", + "versionCode": 63, + "versionName": "5.1.4", "enabled": true, "outputFile": "app-release.apk" } diff --git a/app/src/main/java/xyz/quaver/pupil/types/Suggestions.kt b/app/src/main/java/xyz/quaver/pupil/types/Suggestions.kt index 54dccdab..f04c35ce 100644 --- a/app/src/main/java/xyz/quaver/pupil/types/Suggestions.kt +++ b/app/src/main/java/xyz/quaver/pupil/types/Suggestions.kt @@ -22,13 +22,18 @@ import kotlinx.android.parcel.IgnoredOnParcel import kotlinx.android.parcel.Parcelize import xyz.quaver.floatingsearchview.suggestions.model.SearchSuggestion import xyz.quaver.hitomi.Suggestion +import xyz.quaver.pupil.util.translations @Parcelize data class TagSuggestion(val s: String, val t: Int, val u: String, val n: String) : SearchSuggestion { constructor(s: Suggestion) : this(s.s, s.t, s.u, s.n) @IgnoredOnParcel - override val body = s + override val body = + if (translations[s] != null) + "${translations[s]} ($s)" + else + s } @Parcelize diff --git a/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt b/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt index 3999d42b..0602cb55 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt @@ -28,11 +28,13 @@ import android.view.KeyEvent import android.view.MenuItem import android.view.MotionEvent import android.view.View -import android.widget.* +import android.widget.EditText +import android.widget.ImageView +import android.widget.LinearLayout +import android.widget.TextView import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatDelegate import androidx.cardview.widget.CardView -import androidx.core.text.util.LinkifyCompat import androidx.core.view.GravityCompat import com.google.android.material.appbar.AppBarLayout import com.google.android.material.navigation.NavigationView diff --git a/app/src/main/java/xyz/quaver/pupil/ui/fragment/SettingsFragment.kt b/app/src/main/java/xyz/quaver/pupil/ui/fragment/SettingsFragment.kt index 8345dc45..b57ec30c 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/fragment/SettingsFragment.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/fragment/SettingsFragment.kt @@ -21,14 +21,16 @@ package xyz.quaver.pupil.ui.fragment import android.app.Activity import android.content.* import android.os.Bundle +import android.os.LocaleList import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatDelegate -import androidx.preference.Preference -import androidx.preference.PreferenceCategory -import androidx.preference.PreferenceFragmentCompat -import androidx.preference.SwitchPreferenceCompat +import androidx.core.os.LocaleListCompat +import androidx.preference.* import com.google.android.gms.oss.licenses.OssLicensesMenuActivity +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import xyz.quaver.io.FileX import xyz.quaver.io.util.getChild import xyz.quaver.pupil.R @@ -37,6 +39,7 @@ import xyz.quaver.pupil.ui.SettingsActivity import xyz.quaver.pupil.ui.dialog.* import xyz.quaver.pupil.util.* import xyz.quaver.pupil.util.downloader.DownloadManager +import java.util.* class SettingsFragment : PreferenceFragmentCompat(), @@ -123,6 +126,9 @@ class SettingsFragment : this ?: return false when (key) { + "tag_language" -> { + updateTranslations() + } "nomedia" -> { val create = (newValue as? Boolean) ?: return false @@ -243,6 +249,25 @@ class SettingsFragment : onPreferenceClickListener = this@SettingsFragment } + "tag_language" -> { + this as ListPreference + + isEnabled = false + + CoroutineScope(Dispatchers.IO).launch { + val languages = getAvailableLanguages().distinct().toTypedArray() + + entries = languages.map { Locale(it).let { loc -> loc.getDisplayLanguage(loc) } }.toTypedArray() + entryValues = languages + + launch(Dispatchers.Main) { + isEnabled = true + } + } + + onPreferenceChangeListener = this@SettingsFragment + + } "mirrors" -> { onPreferenceClickListener = this@SettingsFragment } diff --git a/app/src/main/java/xyz/quaver/pupil/ui/view/FloatingSearchView.kt b/app/src/main/java/xyz/quaver/pupil/ui/view/FloatingSearchView.kt index 79b4b362..d17d3076 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/view/FloatingSearchView.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/view/FloatingSearchView.kt @@ -164,9 +164,7 @@ class FloatingSearchView @JvmOverloads constructor(context: Context, attrs: Attr } } - if (item.t == -1) { - textView?.text = item.s - } else { + if (item.t > 0) { (suggestionView as? LinearLayout)?.let { val count = it.findViewById(R.id.count) if (count == null) diff --git a/app/src/main/java/xyz/quaver/pupil/ui/view/TagChip.kt b/app/src/main/java/xyz/quaver/pupil/ui/view/TagChip.kt index a482d898..917979da 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/view/TagChip.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/view/TagChip.kt @@ -25,6 +25,7 @@ import com.google.android.material.chip.Chip import xyz.quaver.pupil.R import xyz.quaver.pupil.favoriteTags import xyz.quaver.pupil.types.Tag +import xyz.quaver.pupil.util.translations import xyz.quaver.pupil.util.wordCapitalize @SuppressLint("ViewConstructor") @@ -90,7 +91,7 @@ class TagChip(context: Context, _tag: Tag) : Chip(context) { text = when (tag.area) { "language" -> languages[tag.tag] - else -> tag.tag.wordCapitalize() + else -> (translations[tag.tag] ?: tag.tag).wordCapitalize() } setEnsureMinTouchTargetSize(false) diff --git a/app/src/main/java/xyz/quaver/pupil/util/misc.kt b/app/src/main/java/xyz/quaver/pupil/util/misc.kt index df3e820e..94319ee3 100644 --- a/app/src/main/java/xyz/quaver/pupil/util/misc.kt +++ b/app/src/main/java/xyz/quaver/pupil/util/misc.kt @@ -23,6 +23,9 @@ import android.content.Context import android.content.Intent import android.os.Build import androidx.core.content.ContextCompat +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.jsonArray +import kotlinx.serialization.json.jsonObject import okhttp3.OkHttpClient import okhttp3.Request import xyz.quaver.Code @@ -128,4 +131,10 @@ fun String.ellipsize(n: Int): String = if (this.length > n) this.slice(0 until n) + "…" else - this \ No newline at end of file + this + +operator fun JsonElement.get(index: Int) = + this.jsonArray[index] + +operator fun JsonElement.get(tag: String) = + this.jsonObject[tag] \ No newline at end of file diff --git a/app/src/main/java/xyz/quaver/pupil/util/translation.kt b/app/src/main/java/xyz/quaver/pupil/util/translation.kt new file mode 100644 index 00000000..7f68d607 --- /dev/null +++ b/app/src/main/java/xyz/quaver/pupil/util/translation.kt @@ -0,0 +1,66 @@ +/* + * Pupil, Hitomi.la viewer for Android + * Copyright (C) 2020 tom5079 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package xyz.quaver.pupil.util + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.jsonArray +import kotlinx.serialization.json.jsonPrimitive +import okhttp3.Request +import xyz.quaver.pupil.client +import java.io.IOException +import java.util.* + +private val filesURL = "https://api.github.com/repos/tom5079/Pupil/git/trees/tags" +private val contentURL = "https://raw.githubusercontent.com/tom5079/Pupil/tags/" + +var translations: Map = run { + updateTranslations() + emptyMap() +} + private set + +@Suppress("BlockingMethodInNonBlockingContext") +fun updateTranslations() = CoroutineScope(Dispatchers.IO).launch { + translations = emptyMap() + translations = Json.decodeFromString>(client.newCall( + Request.Builder() + .url(contentURL + "${Preferences["tag_language", ""]}.json") + .build() + ).execute().also { if (it.code() != 200) return@launch }.body()?.use { it.string() } ?: return@launch).filterValues { it.isNotEmpty() } +} + +fun getAvailableLanguages(): List { + val languages = Locale.getISOLanguages() + + val json = Json.parseToJsonElement(client.newCall( + Request.Builder() + .url(filesURL) + .build() + ).execute().also { if (it.code() != 200) throw IOException() }.body()?.use { it.string() } ?: return emptyList()) + + return listOf("en") + (json["tree"]?.jsonArray?.mapNotNull { + val name = it["path"]?.jsonPrimitive?.content?.takeWhile { c -> c != '.' } + + languages.firstOrNull { code -> code.equals(name, ignoreCase = true) } + } ?: emptyList()) +} \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index ac6869c1..24635c8e 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -152,4 +152,6 @@ エラー キャッシュサイズ制限 制限なし + タグ言語 + Githubにて翻訳に参加できます \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 58979aec..a2ef5add 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -152,4 +152,6 @@ 오류 캐시 크기 제한 무제한 + 태그 언어 + Github에서 번역에 참여하세요 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 53d185b4..a9fc624a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -175,6 +175,8 @@ Miscellaneous + Tag Language + Participate in translation on Github Load images from mirrors Proxy Turn pages Right-to-Left diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml index ff67535d..93ffa2af 100644 --- a/app/src/main/res/xml/root_preferences.xml +++ b/app/src/main/res/xml/root_preferences.xml @@ -1,6 +1,5 @@ - + + +