Compare commits

...

1 Commits

Author SHA1 Message Date
lm41
6aed8e1d17 Use the native android locale picker on android 13+ 2024-11-27 17:46:23 +01:00
7 changed files with 118 additions and 70 deletions

View File

@@ -55,6 +55,10 @@ android {
)
}
androidResources {
generateLocaleConfig = true
}
defaultConfig {
applicationId = "dev.patrickgold.florisboard"
minSdk = projectMinSdk.toInt()
@@ -189,6 +193,7 @@ dependencies {
implementation(libs.androidx.material.icons)
implementation(libs.androidx.navigation.compose)
implementation(libs.androidx.profileinstaller)
implementation(libs.androidx.appcompat)
ksp(libs.androidx.room.compiler)
implementation(libs.androidx.room.runtime)
implementation(libs.cache4k)

View File

@@ -76,6 +76,16 @@
<meta-data android:name="android.view.textservice.scs" android:resource="@xml/spellchecker"/>
</service>
<!-- Service for Locale handling -->
<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
android:enabled="false"
android:exported="false">
<meta-data
android:name="autoStoreLocales"
android:value="true" />
</service>
<!-- Main App Activity -->
<activity
android:name="dev.patrickgold.florisboard.app.FlorisAppActivity"

View File

@@ -20,8 +20,9 @@ import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.displayCutoutPadding
import androidx.compose.foundation.layout.imePadding
@@ -37,6 +38,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.core.os.LocaleListCompat
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.view.WindowCompat
import androidx.navigation.NavController
@@ -72,7 +74,7 @@ val LocalNavController = staticCompositionLocalOf<NavController> {
error("LocalNavController not initialized")
}
class FlorisAppActivity : ComponentActivity() {
class FlorisAppActivity : AppCompatActivity() {
private val prefs by florisPreferenceModel()
private val cacheManager by cacheManager()
private var appTheme by mutableStateOf(AppTheme.AUTO)
@@ -92,10 +94,12 @@ class FlorisAppActivity : ComponentActivity() {
appTheme = it
}
prefs.advanced.settingsLanguage.observe(this) {
val config = Configuration(resources.configuration)
val locale = if (it == "auto") FlorisLocale.default() else FlorisLocale.fromTag(it)
config.setLocale(locale.base)
resourcesContext = createConfigurationContext(config)
val appLocale: LocaleListCompat = if (it == "auto") {
LocaleListCompat.getEmptyLocaleList()
} else {
LocaleListCompat.forLanguageTags(FlorisLocale.fromTag(it).languageTag())
}
AppCompatDelegate.setApplicationLocales(appLocale)
}
if (AndroidVersion.ATMOST_API28_P) {
prefs.advanced.showAppIcon.observe(this) {

View File

@@ -16,6 +16,11 @@
package dev.patrickgold.florisboard.app.settings.advanced
import android.content.Intent
import android.net.Uri
import android.provider.Settings
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Adb
import androidx.compose.material.icons.filled.Archive
@@ -26,6 +31,7 @@ import androidx.compose.material.icons.filled.Preview
import androidx.compose.material.icons.filled.SettingsBackupRestore
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalContext
import dev.patrickgold.florisboard.R
import dev.patrickgold.florisboard.app.AppTheme
import dev.patrickgold.florisboard.app.LocalNavController
@@ -34,7 +40,6 @@ import dev.patrickgold.florisboard.app.enumDisplayEntriesOf
import dev.patrickgold.florisboard.ime.core.DisplayLanguageNamesIn
import dev.patrickgold.florisboard.ime.keyboard.IncognitoMode
import dev.patrickgold.florisboard.lib.FlorisLocale
import org.florisboard.lib.android.AndroidVersion
import dev.patrickgold.florisboard.lib.compose.FlorisScreen
import dev.patrickgold.florisboard.lib.compose.stringRes
import dev.patrickgold.jetpref.datastore.model.observeAsState
@@ -44,6 +49,7 @@ import dev.patrickgold.jetpref.datastore.ui.PreferenceGroup
import dev.patrickgold.jetpref.datastore.ui.SwitchPreference
import dev.patrickgold.jetpref.datastore.ui.listPrefEntries
import dev.patrickgold.jetpref.datastore.ui.vectorResource
import org.florisboard.lib.android.AndroidVersion
@Composable
fun AdvancedScreen() = FlorisScreen {
@@ -51,6 +57,10 @@ fun AdvancedScreen() = FlorisScreen {
previewFieldVisible = false
val navController = LocalNavController.current
val context = LocalContext.current
val languageSettingsLauncher =
rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) {}
content {
ListPreference(
@@ -67,70 +77,86 @@ fun AdvancedScreen() = FlorisScreen {
AndroidVersion.ATLEAST_API31_S
},
)
ListPreference(
prefs.advanced.settingsLanguage,
icon = Icons.Default.Language,
title = stringRes(R.string.pref__advanced__settings_language__label),
entries = listPrefEntries {
listOf(
"auto",
"ar",
"bg",
"bs",
"ca",
"ckb",
"cs",
"da",
"de",
"el",
"en",
"eo",
"es",
"fa",
"fi",
"fr",
"hr",
"hu",
"in",
"it",
"iw",
"ja",
"ko-KR",
"ku",
"lv-LV",
"mk",
"nds-DE",
"nl",
"no",
"pl",
"pt",
"pt-BR",
"ru",
"sk",
"sl",
"sr",
"sv",
"tr",
"uk",
"zgh",
"zh-CN",
).map { languageTag ->
if (languageTag == "auto") {
entry(
key = "auto",
label = stringRes(R.string.settings__system_default),
if (AndroidVersion.ATLEAST_API33_T) {
Preference(
title = stringRes(R.string.pref__advanced__settings_language__label),
icon = Icons.Default.Language,
onClick = {
languageSettingsLauncher.launch(
Intent(
Settings.ACTION_APP_LOCALE_SETTINGS,
Uri.parse("package:${context.packageName}")
)
} else {
val displayLanguageNamesIn by prefs.localization.displayLanguageNamesIn.observeAsState()
val locale = FlorisLocale.fromTag(languageTag)
entry(locale.languageTag(), when (displayLanguageNamesIn) {
DisplayLanguageNamesIn.SYSTEM_LOCALE -> locale.displayName()
DisplayLanguageNamesIn.NATIVE_LOCALE -> locale.displayName(locale)
})
)
}
)
} else {
ListPreference(
prefs.advanced.settingsLanguage,
icon = Icons.Default.Language,
title = stringRes(R.string.pref__advanced__settings_language__label),
entries = listPrefEntries {
listOf(
"auto",
"ar",
"bg",
"bs",
"ca",
"ckb",
"cs",
"da",
"de",
"el",
"en",
"eo",
"es",
"fa",
"fi",
"fr",
"hr",
"hu",
"in",
"it",
"iw",
"ja",
"ko-KR",
"ku",
"lv-LV",
"mk",
"nds-DE",
"nl",
"no",
"pl",
"pt",
"pt-BR",
"ru",
"sk",
"sl",
"sr",
"sv",
"tr",
"uk",
"zgh",
"zh-CN",
).map { languageTag ->
if (languageTag == "auto") {
entry(
key = "auto",
label = stringRes(R.string.settings__system_default),
)
} else {
val displayLanguageNamesIn by prefs.localization.displayLanguageNamesIn.observeAsState()
val locale = FlorisLocale.fromTag(languageTag)
entry(locale.languageTag(), when (displayLanguageNamesIn) {
DisplayLanguageNamesIn.SYSTEM_LOCALE -> locale.displayName()
DisplayLanguageNamesIn.NATIVE_LOCALE -> locale.displayName(locale)
})
}
}
}
}
)
)
}
SwitchPreference(
prefs.advanced.showAppIcon,
icon = Icons.Default.Preview,

View File

@@ -0,0 +1 @@
unqualifiedResLocale=en-US

View File

@@ -10,7 +10,7 @@
<item name="android:forceDarkAllowed" tools:targetApi="q">false</item>
</style>
<style name="FlorisAppTheme" parent="android:style/Theme.Material.NoActionBar">
<style name="FlorisAppTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:colorPrimary">@color/colorPrimary</item>
<item name="android:colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="android:colorAccent">@color/colorAccent</item>
@@ -31,7 +31,7 @@
<item name="android:forceDarkAllowed" tools:targetApi="q">false</item>
</style>
<style name="FlorisAppTheme.Transparent" parent="android:style/Theme.Material.NoActionBar">
<style name="FlorisAppTheme.Transparent" parent="Theme.AppCompat.NoActionBar">
<item name="android:colorPrimary">@android:color/transparent</item>
<item name="android:colorPrimaryDark">@android:color/transparent</item>
<item name="android:colorAccent">@android:color/transparent</item>

View File

@@ -14,6 +14,7 @@ androidx-material-icons = "1.7.3"
androidx-navigation = "2.8.1"
androidx-profileinstaller = "1.4.0"
androidx-room = "2.6.1"
appcompat = "1.7.0"
cache4k = "0.7.0"
kotlin = "2.0.20"
kotlinx-coroutines = "1.8.1"
@@ -53,6 +54,7 @@ androidx-navigation-compose = { module = "androidx.navigation:navigation-compose
androidx-profileinstaller = { module = "androidx.profileinstaller:profileinstaller", version.ref = "androidx-profileinstaller" }
androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "androidx-room" }
androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "androidx-room" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
cache4k = { module = "io.github.reactivecircus.cache4k:cache4k", version.ref = "cache4k" }
kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinx-coroutines" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization-json" }