Fixed missing languages and wrong display (bitfireAT/davx5#214)

* Displaying language with `displayName` instead of `displayLanguage`

Signed-off-by: Arnau Mora <arnyminer.z@gmail.com>

* Added languages from `davdroid`

Signed-off-by: Arnau Mora <arnyminer.z@gmail.com>

* Fixed wrong locale tags

Signed-off-by: Arnau Mora <arnyminer.z@gmail.com>

* Using Map instead of list for language loading

Signed-off-by: Arnau Mora <arnyminer.z@gmail.com>

* Typo

Signed-off-by: Arnau Mora <arnyminer.z@gmail.com>

* Changed language loading logic

Signed-off-by: Arnau Mora <arnyminer.z@gmail.com>

* Improved docs

Signed-off-by: Arnau Mora <arnyminer.z@gmail.com>

* Moved method from `LangUtils`

Signed-off-by: Arnau Mora <arnyminer.z@gmail.com>

* Using regex

Signed-off-by: Arnau Mora <arnyminer.z@gmail.com>

* Added test for `resourceQualifierToLanguageTag`

Signed-off-by: Arnau Mora <arnyminer.z@gmail.com>

---------

Signed-off-by: Arnau Mora <arnyminer.z@gmail.com>
This commit is contained in:
Arnau Mora 2023-02-21 11:03:22 +01:00 committed by Ricki Hirner
parent b83d116f40
commit fffb029362
No known key found for this signature in database
GPG key ID: 79A019FCAAEDD3AA
3 changed files with 60 additions and 7 deletions

View file

@ -60,6 +60,11 @@ Set<String> getLocales(String flavor) {
logger.trace("Getting main locales ($mainDir)...")
def mainLocales = getLocalesForFlavor(mainDir)
// Get a list of locales for the davdroid directory
def davdroidDir = new File(dir, 'davdroid')
logger.trace("Getting davdroid locales ($davdroidDir)...")
def davdroidLocales = getLocalesForFlavor(davdroidDir)
// Get the current flavor
def flavorDir = new File(dir, flavor)
logger.trace("Getting locales for flavor $flavor ($flavorDir)...")
@ -69,6 +74,7 @@ Set<String> getLocales(String flavor) {
// We use Set for avoiding duplicates
Set<String> locales = new LinkedHashSet()
locales.addAll(mainLocales)
locales.addAll(davdroidLocales)
locales.addAll(flavorLocales)
// Log the available locales

View file

@ -0,0 +1,13 @@
package at.bitfire.davdroid.ui
import org.junit.Assert.assertEquals
import org.junit.Test
class AppSettingsActivityTest {
@Test
fun testResourceQualifierToLanguageTag() {
assertEquals("en", AppSettingsActivity.resourceQualifierToLanguageTag("en"))
assertEquals("en-GB", AppSettingsActivity.resourceQualifierToLanguageTag("en-GB"))
assertEquals("en-GB", AppSettingsActivity.resourceQualifierToLanguageTag("en-rGB"))
}
}

View file

@ -42,6 +42,27 @@ class AppSettingsActivity: AppCompatActivity() {
companion object {
const val EXTRA_SCROLL_TO = "scrollTo"
/**
* Matches all language qualifiers with a region of three characters, which is not supported
* by Java's Locale.
* @see resourceQualifierToLanguageTag
*/
private val langRegex = Regex(".*-.{3}")
/**
* Converts the language qualifier given from Android to Java Locale language tag.
* @param lang The qualifier to convert. Example: `en`, `zh-rTW`...
* @return A correct language code to be introduced into [java.util.Locale.forLanguageTag].
*/
fun resourceQualifierToLanguageTag(lang: String): String {
// If the language qualifier is correct, return it
if (!lang.matches(langRegex)) return lang
// Otherwise, fix it
val hyphenIndex = lang.indexOf('-')
// Remove the first character of the 3 (rGB -> GB, rTW -> TW)
return lang.substring(0, hyphenIndex) + "-" + lang.substring(hyphenIndex + 2)
}
}
@ -230,19 +251,32 @@ class AppSettingsActivity: AppCompatActivity() {
}
}
findPreference<ListPreference>(Settings.LANGUAGE)!!.apply {
val languageOptions = mutableListOf<Locale?>(null)
for (language in BuildConfig.TRANSLATION_ARRAY) {
languageOptions.add(Locale.forLanguageTag(language))
}
this.entries = languageOptions.map { language -> language?.displayLanguage ?: context.getText(R.string.app_settings_language_system_default) }.toTypedArray()
this.entryValues = languageOptions.map { language -> language?.language ?: Settings.LANGUAGE_SYSTEM }.toTypedArray()
val languageOptions = mutableMapOf(
// Start with the "System default" option on top
Settings.LANGUAGE_SYSTEM to context.getString(R.string.app_settings_language_system_default)
)
// Create another map with the languages available from TRANSLATION_ARRAY
val availableLanguages = BuildConfig.TRANSLATION_ARRAY
.map { lang ->
// Fix the language code in case there are 3-character languages
val fixedLang = resourceQualifierToLanguageTag(lang)
val locale = Locale.forLanguageTag(fixedLang)
locale.language to locale.displayName
}
// Sort alphabetically by the name displayed
.sortedBy { it.second }
// Add all the available languages to the original list
languageOptions.putAll(availableLanguages)
this.entries = languageOptions.values.toTypedArray()
this.entryValues = languageOptions.keys.toTypedArray()
val appCompatLocales = AppCompatDelegate.getApplicationLocales()
var currentLocale: Locale? = null
if(!appCompatLocales.isEmpty) {
for (i in 0 until appCompatLocales.size()) {
val locale = appCompatLocales[i] ?: continue
if (languageOptions.contains(appCompatLocales[i]!!)) {
if (languageOptions.containsKey(appCompatLocales[i]!!.language)) {
currentLocale = locale
break
}