From b465745d1af7631bb8ea4d34c6d6161bfba6d469 Mon Sep 17 00:00:00 2001 From: greenart7c3 Date: Fri, 17 Oct 2025 07:07:17 -0300 Subject: [PATCH] Refactor: Move language setting from per-account to global settings This change moves the language preference from being an individual account setting to a global application-wide setting. The `language` property has been removed from the `Account` model and added to the `AmberSettings` model. All related logic for saving, loading, and applying the language preference has been updated to reflect this new global scope. The application now loads and applies the language setting on startup. --- app/src/main/java/com/greenart7c3/nostrsigner/Amber.kt | 7 +++++++ .../com/greenart7c3/nostrsigner/LocalPreferences.kt | 7 +++---- .../java/com/greenart7c3/nostrsigner/models/Account.kt | 1 - .../greenart7c3/nostrsigner/models/AmberSettings.kt | 1 + .../nostrsigner/ui/AccountStateViewModel.kt | 5 ----- .../com/greenart7c3/nostrsigner/ui/LanguageScreen.kt | 10 ++++------ .../java/com/greenart7c3/nostrsigner/ui/MainScreen.kt | 1 - 7 files changed, 15 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/Amber.kt b/app/src/main/java/com/greenart7c3/nostrsigner/Amber.kt index 46d9ee10..e7fe4648 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/Amber.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/Amber.kt @@ -4,7 +4,9 @@ import android.app.Application import android.content.Intent import android.net.NetworkCapabilities import android.util.Log +import androidx.appcompat.app.AppCompatDelegate import androidx.compose.runtime.mutableStateOf +import androidx.core.os.LocaleListCompat import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleObserver import androidx.lifecycle.LifecycleOwner @@ -246,6 +248,11 @@ class Amber : Application(), LifecycleObserver { LocalPreferences.switchToAccount(this@Amber, LocalPreferences.allSavedAccounts(this@Amber).first().npub) } settings = LocalPreferences.loadSettingsFromEncryptedStorage() + settings.language?.let { + AppCompatDelegate.setApplicationLocales( + LocaleListCompat.forLanguageTags(it), + ) + } LocalPreferences.reloadApp() fixRejectedPermissions() fixAcceptedPermissions() diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/LocalPreferences.kt b/app/src/main/java/com/greenart7c3/nostrsigner/LocalPreferences.kt index 0ca31d29..9bb95984 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/LocalPreferences.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/LocalPreferences.kt @@ -32,7 +32,6 @@ private enum class PrefKeys(val key: String) { NOSTR_PRIVKEY("nostr_privkey"), NOSTR_PUBKEY("nostr_pubkey"), ACCOUNT_NAME("account_name"), - LANGUAGE_PREFS("languagePreferences"), SIGN_POLICY("default_sign_policy"), SEED_WORDS("seed_words"), PROFILE_URL("profile_url"), @@ -56,6 +55,7 @@ private enum class SettingsKeys(val key: String) { PROXY_PORT("proxy_port"), BATERRY_OPTIMIZATION("battery_optimization"), KILL_SWITCH("kill_switch"), + LANGUAGE_PREFS("languagePreferences"), } @Immutable @@ -139,6 +139,7 @@ object LocalPreferences { putBoolean(SettingsKeys.USE_PROXY.key, settings.useProxy) putInt(SettingsKeys.PROXY_PORT.key, settings.proxyPort) putBoolean(SettingsKeys.KILL_SWITCH.key, settings.killSwitch.value) + putString(SettingsKeys.LANGUAGE_PREFS.key, settings.language) } } } @@ -220,6 +221,7 @@ object LocalPreferences { useProxy = getBoolean(SettingsKeys.USE_PROXY.key, false), proxyPort = getInt(SettingsKeys.PROXY_PORT.key, 9050), killSwitch = MutableStateFlow(getBoolean(SettingsKeys.KILL_SWITCH.key, false)), + language = getString(SettingsKeys.LANGUAGE_PREFS.key, null), ) } } @@ -406,7 +408,6 @@ object LocalPreferences { account.signer.keyPair.pubKey.let { putString(PrefKeys.NOSTR_PUBKEY.key, it.toHexKey()) } putString(PrefKeys.ACCOUNT_NAME.key, account.name.value) putString(PrefKeys.PROFILE_URL.key, account.picture.value) - putString(PrefKeys.LANGUAGE_PREFS.key, account.language) putInt(PrefKeys.SIGN_POLICY.key, account.signPolicy) putBoolean(PrefKeys.DID_BACKUP.key, account.didBackup) } @@ -498,7 +499,6 @@ object LocalPreferences { val privKey = DataStoreAccess.getEncryptedKey(context, npub, DataStoreAccess.NOSTR_PRIVKEY) val name = getString(PrefKeys.ACCOUNT_NAME.key, "") ?: "" val picture = getString(PrefKeys.PROFILE_URL.key, "") ?: "" - val language = getString(PrefKeys.LANGUAGE_PREFS.key, null) val signPolicy = getInt(PrefKeys.SIGN_POLICY.key, 1) val savedSeedWords = DataStoreAccess.getEncryptedKey(context, npub, DataStoreAccess.SEED_WORDS) val seedWords = savedSeedWords?.split(" ")?.toSet() ?: emptySet() @@ -509,7 +509,6 @@ object LocalPreferences { signer = NostrSignerInternal(KeyPair(privKey = privKey?.hexToByteArray(), pubKey = pubKey.hexToByteArray())), name = MutableStateFlow(name), picture = MutableStateFlow(picture), - language = language, signPolicy = signPolicy, seedWords = seedWords, didBackup = didBackup, diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/models/Account.kt b/app/src/main/java/com/greenart7c3/nostrsigner/models/Account.kt index ff3fab56..3e6aeddb 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/models/Account.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/models/Account.kt @@ -16,7 +16,6 @@ class Account( val signer: NostrSignerInternal, val name: MutableStateFlow, val picture: MutableStateFlow, - var language: String?, var signPolicy: Int, var seedWords: Set, var didBackup: Boolean, diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/models/AmberSettings.kt b/app/src/main/java/com/greenart7c3/nostrsigner/models/AmberSettings.kt index 06ef0787..6cd0150b 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/models/AmberSettings.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/models/AmberSettings.kt @@ -27,4 +27,5 @@ data class AmberSettings( val useProxy: Boolean = false, val proxyPort: Int = 9050, val killSwitch: MutableStateFlow = MutableStateFlow(false), + var language: String? = null, ) diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/AccountStateViewModel.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/AccountStateViewModel.kt index 1b219c73..0ddef117 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/AccountStateViewModel.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/AccountStateViewModel.kt @@ -163,7 +163,6 @@ class AccountStateViewModel(npub: String?) : ViewModel() { signer = NostrSignerInternal(KeyPair(Hex.decode(newKey))), name = MutableStateFlow(""), picture = MutableStateFlow(""), - language = null, signPolicy = signPolicy, seedWords = emptySet(), didBackup = true, @@ -173,7 +172,6 @@ class AccountStateViewModel(npub: String?) : ViewModel() { signer = NostrSignerInternal(KeyPair(privKey = key.bechToBytes())), name = MutableStateFlow(""), picture = MutableStateFlow(""), - language = null, signPolicy = signPolicy, seedWords = emptySet(), didBackup = true, @@ -184,7 +182,6 @@ class AccountStateViewModel(npub: String?) : ViewModel() { signer = NostrSignerInternal(keyPair), name = MutableStateFlow(""), picture = MutableStateFlow(""), - language = null, signPolicy = signPolicy, seedWords = key.split(" ").toSet(), didBackup = true, @@ -194,7 +191,6 @@ class AccountStateViewModel(npub: String?) : ViewModel() { signer = NostrSignerInternal(KeyPair(Hex.decode(key))), name = MutableStateFlow(""), picture = MutableStateFlow(""), - language = null, signPolicy = signPolicy, seedWords = emptySet(), didBackup = true, @@ -226,7 +222,6 @@ class AccountStateViewModel(npub: String?) : ViewModel() { NostrSignerInternal(keyPair), name = MutableStateFlow(name), picture = MutableStateFlow(""), - language = null, signPolicy = signPolicy, seedWords = seedWords, didBackup = false, diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/LanguageScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/LanguageScreen.kt index ef8f4afd..32db6eea 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/LanguageScreen.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/LanguageScreen.kt @@ -14,7 +14,6 @@ import androidx.core.os.LocaleListCompat import com.greenart7c3.nostrsigner.Amber import com.greenart7c3.nostrsigner.LocalPreferences import com.greenart7c3.nostrsigner.R -import com.greenart7c3.nostrsigner.models.Account import com.greenart7c3.nostrsigner.ui.components.TitleExplainer import java.io.IOException import kotlinx.collections.immutable.ImmutableMap @@ -27,12 +26,11 @@ import org.xmlpull.v1.XmlPullParserException @Composable fun LanguageScreen( modifier: Modifier = Modifier, - account: Account, ) { val context = LocalContext.current val languageEntries = remember { context.getLangPreferenceDropdownEntries() } val languageList = remember { languageEntries.keys.map { TitleExplainer(it) }.toImmutableList() } - val languageIndex = getLanguageIndex(languageEntries, account.language) + val languageIndex = getLanguageIndex(languageEntries, Amber.instance.settings.language) Column( modifier = modifier @@ -49,10 +47,10 @@ fun LanguageScreen( languageIndex, ) { Amber.instance.applicationIOScope.launch { - account.language = languageEntries[languageList[it].title] - LocalPreferences.saveToEncryptedStorage(context, account) + Amber.instance.settings.language = languageEntries[languageList[it].title] + LocalPreferences.saveSettingsToEncryptedStorage(Amber.instance.settings) AppCompatDelegate.setApplicationLocales( - LocaleListCompat.forLanguageTags(account.language), + LocaleListCompat.forLanguageTags(Amber.instance.settings.language), ) } } diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/MainScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/MainScreen.kt index 785306b3..6252a685 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/MainScreen.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/MainScreen.kt @@ -501,7 +501,6 @@ fun MainScreen( .padding(padding) .padding(horizontal = verticalPadding) .padding(top = verticalPadding * 1.5f), - account = account, ) }, )