add language picker

This commit is contained in:
greenart7c3
2023-07-05 15:12:24 -03:00
parent 33cc261b62
commit 035ba899ee
7 changed files with 92 additions and 22 deletions

View File

@@ -71,6 +71,7 @@ private object PrefKeys {
const val AUTOMATICALLY_SHOW_IMAGES = "automatically_show_images" const val AUTOMATICALLY_SHOW_IMAGES = "automatically_show_images"
const val AUTOMATICALLY_START_PLAYBACK = "automatically_start_playback" const val AUTOMATICALLY_START_PLAYBACK = "automatically_start_playback"
const val THEME = "theme" const val THEME = "theme"
const val PREFERRED_LANGUAGE = "preferred_Language"
val LAST_READ: (String) -> String = { route -> "last_read_route_$route" } val LAST_READ: (String) -> String = { route -> "last_read_route_$route" }
} }
@@ -254,6 +255,7 @@ object LocalPreferences {
} else { } else {
putBoolean(PrefKeys.AUTOMATICALLY_START_PLAYBACK, account.settings.automaticallyStartPlayback!!) putBoolean(PrefKeys.AUTOMATICALLY_START_PLAYBACK, account.settings.automaticallyStartPlayback!!)
} }
putString(PrefKeys.PREFERRED_LANGUAGE, account.settings.preferredLanguage ?: "")
}.apply() }.apply()
} }
@@ -271,6 +273,14 @@ object LocalPreferences {
return theme return theme
} }
fun getPreferredLanguage(): String {
var language = ""
encryptedPreferences().apply {
language = getString(PrefKeys.PREFERRED_LANGUAGE, "") ?: ""
}
return language
}
fun loadFromEncryptedStorage(): Account? { fun loadFromEncryptedStorage(): Account? {
val acc = loadFromEncryptedStorage(currentAccount()) val acc = loadFromEncryptedStorage(currentAccount())
acc?.registerObservers() acc?.registerObservers()
@@ -373,7 +383,7 @@ object LocalPreferences {
mapOf() mapOf()
} }
val settings = Settings(null, null) val settings = Settings()
encryptedPreferences().apply { encryptedPreferences().apply {
settings.automaticallyShowImages = if (contains(PrefKeys.AUTOMATICALLY_SHOW_IMAGES)) { settings.automaticallyShowImages = if (contains(PrefKeys.AUTOMATICALLY_SHOW_IMAGES)) {
getBoolean(PrefKeys.AUTOMATICALLY_SHOW_IMAGES, false) getBoolean(PrefKeys.AUTOMATICALLY_SHOW_IMAGES, false)
@@ -386,6 +396,8 @@ object LocalPreferences {
} else { } else {
null null
} }
settings.preferredLanguage = getString(PrefKeys.PREFERRED_LANGUAGE, "")
} }
val a = Account( val a = Account(

View File

@@ -4,6 +4,7 @@ import androidx.compose.runtime.Stable
@Stable @Stable
class Settings( class Settings(
var automaticallyShowImages: Boolean?, var automaticallyShowImages: Boolean? = null,
var automaticallyStartPlayback: Boolean? var automaticallyStartPlayback: Boolean? = null,
var preferredLanguage: String? = null
) )

View File

@@ -10,11 +10,13 @@ import android.os.Bundle
import android.util.Log import android.util.Log
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface import androidx.compose.material.Surface
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.fragment.app.FragmentActivity import androidx.core.os.LocaleListCompat
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.amethyst.BuildConfig import com.vitorpamplona.amethyst.BuildConfig
import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.LocalPreferences
@@ -42,7 +44,7 @@ import kotlinx.coroutines.launch
import java.net.URLEncoder import java.net.URLEncoder
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
class MainActivity : FragmentActivity() { class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@@ -53,6 +55,11 @@ class MainActivity : FragmentActivity() {
LocalPreferences.migrateSingleUserPrefs() LocalPreferences.migrateSingleUserPrefs()
val themeViewModel = ThemeViewModel() val themeViewModel = ThemeViewModel()
themeViewModel.onChange(LocalPreferences.getTheme()) themeViewModel.onChange(LocalPreferences.getTheme())
val language = LocalPreferences.getPreferredLanguage()
if (language.isNotBlank()) {
val appLocale: LocaleListCompat = LocaleListCompat.forLanguageTags(language)
AppCompatDelegate.setApplicationLocales(appLocale)
}
setContent { setContent {
AmethystTheme(themeViewModel) { AmethystTheme(themeViewModel) {

View File

@@ -1,10 +1,13 @@
package com.vitorpamplona.amethyst.ui.screen.loggedIn package com.vitorpamplona.amethyst.ui.screen.loggedIn
import android.content.Context
import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Button import androidx.compose.material.Button
import androidx.compose.material.DropdownMenuItem import androidx.compose.material.DropdownMenuItem
import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ExperimentalMaterialApi
@@ -23,13 +26,53 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.core.os.LocaleListCompat
import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.LocalPreferences
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ServiceManager import com.vitorpamplona.amethyst.ServiceManager
import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer
import com.vitorpamplona.amethyst.ui.theme.StdPadding import com.vitorpamplona.amethyst.ui.theme.StdPadding
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import java.io.IOException
fun Context.getLocaleListFromXml(): LocaleListCompat {
val tagsList = mutableListOf<CharSequence>()
try {
val xpp: XmlPullParser = resources.getXml(R.xml.locales_config)
while (xpp.eventType != XmlPullParser.END_DOCUMENT) {
if (xpp.eventType == XmlPullParser.START_TAG) {
if (xpp.name == "locale") {
tagsList.add(xpp.getAttributeValue(0))
}
}
xpp.next()
}
} catch (e: XmlPullParserException) {
e.printStackTrace()
} catch (e: IOException) {
e.printStackTrace()
}
return LocaleListCompat.forLanguageTags(tagsList.joinToString(","))
}
fun Context.getLangPreferenceDropdownEntries(): Map<String, String> {
val localeList = getLocaleListFromXml()
val map = mutableMapOf<String, String>()
for (a in 0 until localeList.size()) {
localeList[a].let {
map.put(it!!.getDisplayName(it).replaceFirstChar { char -> char.uppercase() }, it.toLanguageTag())
}
}
return map
}
@Composable @Composable
fun SettingsScreen( fun SettingsScreen(
@@ -59,6 +102,16 @@ fun SettingsScreen(
} }
val context = LocalContext.current val context = LocalContext.current
val languageEntries = context.getLangPreferenceDropdownEntries()
val languageList = languageEntries.keys.toTypedArray()
var languageIndex = languageEntries.values.toTypedArray().indexOf(Locale.current.toLanguageTag())
if (languageIndex == -1) languageIndex = languageEntries.values.toTypedArray().indexOf(Locale.current.language)
if (languageIndex == -1) languageIndex = languageEntries.values.toTypedArray().indexOf("en")
val selectedLanguage = remember {
mutableStateOf(languageList[languageIndex])
}
Column( Column(
StdPadding, StdPadding,
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
@@ -67,9 +120,10 @@ fun SettingsScreen(
Section("Application preferences") Section("Application preferences")
Text( DropDownSettings(
"Theme", selectedItem = selectedLanguage,
fontWeight = FontWeight.Bold listItems = languageList,
title = "Language"
) )
DropDownSettings( DropDownSettings(
@@ -78,19 +132,12 @@ fun SettingsScreen(
title = "Theme" title = "Theme"
) )
Text(
"Media",
fontWeight = FontWeight.Bold
)
DropDownSettings( DropDownSettings(
selectedItem = selectedItem, selectedItem = selectedItem,
listItems = selectedItens, listItems = selectedItens,
title = "Automatically load images/gifs" title = "Automatically load images/gifs"
) )
Spacer(modifier = DoubleVertSpacer)
DropDownSettings( DropDownSettings(
selectedItem = selectedVideoItem, selectedItem = selectedVideoItem,
listItems = selectedItens, listItems = selectedItens,
@@ -114,12 +161,15 @@ fun SettingsScreen(
else -> null else -> null
} }
accountViewModel.changeTheme(selectedTheme.value) accountViewModel.changeTheme(selectedTheme.value)
scope.launch(Dispatchers.IO) { scope.launch(Dispatchers.IO) {
accountViewModel.updateGlobalSettings(automaticallyShowImages, automaticallyStartPlayback) accountViewModel.updateGlobalSettings(automaticallyShowImages, automaticallyStartPlayback)
LocalPreferences.saveToEncryptedStorage(accountViewModel.account) LocalPreferences.saveToEncryptedStorage(accountViewModel.account)
LocalPreferences.updateTheme(selectedTheme.value) LocalPreferences.updateTheme(selectedTheme.value)
ServiceManager.pause() ServiceManager.pause()
ServiceManager.start(context) ServiceManager.start(context)
val appLocale: LocaleListCompat = LocaleListCompat.forLanguageTags(languageEntries[selectedLanguage.value])
AppCompatDelegate.setApplicationLocales(appLocale)
} }
} }
) { ) {
@@ -140,6 +190,7 @@ fun DropDownSettings(
mutableStateOf(false) mutableStateOf(false)
} }
ExposedDropdownMenuBox( ExposedDropdownMenuBox(
modifier = Modifier.padding(8.dp),
expanded = expanded, expanded = expanded,
onExpandedChange = { onExpandedChange = {
expanded = !expanded expanded = !expanded

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<style name="Theme.Amethyst" parent="android:Theme.Material.Light.NoActionBar"> <style name="Theme.Amethyst" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:statusBarColor">@color/purple_700</item> <item name="android:statusBarColor">@color/purple_700</item>
<item name="android:windowBackground">@color/black</item> <item name="android:windowBackground">@color/black</item>
<item name="android:windowLayoutInDisplayCutoutMode" tools:ignore="NewApi">shortEdges</item>\ <item name="android:windowLayoutInDisplayCutoutMode" tools:ignore="NewApi">shortEdges</item>\

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<style name="Theme.Amethyst" parent="android:Theme.Material.Light.NoActionBar"> <style name="Theme.Amethyst" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:statusBarColor">@color/purple_700</item> <item name="android:statusBarColor">@color/purple_700</item>
<item name="android:windowLayoutInDisplayCutoutMode" tools:ignore="NewApi">shortEdges</item> <item name="android:windowLayoutInDisplayCutoutMode" tools:ignore="NewApi">shortEdges</item>
</style> </style>

View File

@@ -7,17 +7,16 @@
<locale android:name="fa"/> <locale android:name="fa"/>
<locale android:name="fr"/> <locale android:name="fr"/>
<locale android:name="hu"/> <locale android:name="hu"/>
<locale android:name="night"/>
<locale android:name="nl"/> <locale android:name="nl"/>
<locale android:name="pr-rBR"/> <locale android:name="pt-BR"/>
<locale android:name="ru"/> <locale android:name="ru"/>
<locale android:name="sv-rSE"/> <locale android:name="sv-SE"/>
<locale android:name="ta"/> <locale android:name="ta"/>
<locale android:name="tr"/> <locale android:name="tr"/>
<locale android:name="uk"/> <locale android:name="uk"/>
<locale android:name="zh"/> <locale android:name="zh"/>
<locale android:name="zh-rHK"/> <locale android:name="zh-HK"/>
<locale android:name="zh-rTW"/> <locale android:name="zh-TW"/>
<locale android:name="en"/> <locale android:name="en"/>
<locale android:name="en-GB"/> <locale android:name="en-GB"/>
</locale-config> </locale-config>