From 0495dc88fc6a030a73306fe0f1d76bb230070531 Mon Sep 17 00:00:00 2001 From: David Kaspar Date: Mon, 16 Jun 2025 15:52:46 +0200 Subject: [PATCH] Add dropdown with auto translate language excludes to app settings Persist changes to settings TODO: Load actually excluded languages Optimise code Improve UI --- .../vitorpamplona/amethyst/model/Settings.kt | 1 + .../ui/screen/SharedPreferencesViewModel.kt | 18 ++++ .../amethyst/ui/screen/SharedSettingsState.kt | 2 +- .../loggedIn/settings/AppSettingsScreen.kt | 89 +++++++++++++++++++ amethyst/src/main/res/values/strings.xml | 4 + 5 files changed, 113 insertions(+), 1 deletion(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Settings.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Settings.kt index 356f79707a..0487326ae8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Settings.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Settings.kt @@ -27,6 +27,7 @@ import com.vitorpamplona.amethyst.R data class Settings( val theme: ThemeType = ThemeType.SYSTEM, val preferredLanguage: String? = null, + val dontTranslateFrom: Set = emptySet(), val automaticallyShowImages: ConnectivityType = ConnectivityType.ALWAYS, val automaticallyStartPlayback: ConnectivityType = ConnectivityType.ALWAYS, val automaticallyShowUrlPreview: ConnectivityType = ConnectivityType.ALWAYS, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/SharedPreferencesViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/SharedPreferencesViewModel.kt index dffe105810..68063f4794 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/SharedPreferencesViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/SharedPreferencesViewModel.kt @@ -52,6 +52,7 @@ class SharedPreferencesViewModel : ViewModel() { sharedPrefs.theme = savedSettings.theme sharedPrefs.language = savedSettings.preferredLanguage + sharedPrefs.dontTranslateFrom = savedSettings.dontTranslateFrom sharedPrefs.automaticallyShowImages = savedSettings.automaticallyShowImages sharedPrefs.automaticallyStartPlayback = savedSettings.automaticallyStartPlayback sharedPrefs.automaticallyShowUrlPreview = savedSettings.automaticallyShowUrlPreview @@ -82,6 +83,22 @@ class SharedPreferencesViewModel : ViewModel() { } } + fun addDontTranslateFrom(languageCode: String) { + val newSet = sharedPrefs.dontTranslateFrom.plus(languageCode) + if (newSet != sharedPrefs.dontTranslateFrom) { + sharedPrefs.dontTranslateFrom = newSet + saveSharedSettings() + } + } + + fun removeDontTranslateFrom(languageCode: String) { + val newSet = sharedPrefs.dontTranslateFrom.minus(languageCode) + if (newSet != sharedPrefs.dontTranslateFrom) { + sharedPrefs.dontTranslateFrom = newSet + saveSharedSettings() + } + } + fun updateLanguageInTheUI() { if (sharedPrefs.language != null) { viewModelScope.launch(Dispatchers.Main) { @@ -188,6 +205,7 @@ class SharedPreferencesViewModel : ViewModel() { Settings( sharedPrefs.theme, sharedPrefs.language, + sharedPrefs.dontTranslateFrom, sharedPrefs.automaticallyShowImages, sharedPrefs.automaticallyStartPlayback, sharedPrefs.automaticallyShowUrlPreview, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/SharedSettingsState.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/SharedSettingsState.kt index cbdd75954c..f70b385b2e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/SharedSettingsState.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/SharedSettingsState.kt @@ -38,7 +38,7 @@ import com.vitorpamplona.amethyst.model.ThemeType class SharedSettingsState { var theme by mutableStateOf(ThemeType.SYSTEM) var language by mutableStateOf(null) - + var dontTranslateFrom by mutableStateOf>(emptySet()) var automaticallyShowImages by mutableStateOf(ConnectivityType.ALWAYS) var automaticallyStartPlayback by mutableStateOf(ConnectivityType.ALWAYS) var automaticallyShowUrlPreview by mutableStateOf(ConnectivityType.ALWAYS) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/AppSettingsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/AppSettingsScreen.kt index 131d971bd1..27293b754d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/AppSettingsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/AppSettingsScreen.kt @@ -32,10 +32,22 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Clear +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ExposedDropdownMenuBox +import androidx.compose.material3.ExposedDropdownMenuDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -77,6 +89,7 @@ import kotlinx.collections.immutable.toImmutableMap import org.xmlpull.v1.XmlPullParser import org.xmlpull.v1.XmlPullParserException import java.io.IOException +import java.util.Locale as JavaLocale fun Context.getLocaleListFromXml(): LocaleListCompat { val tagsList = mutableListOf() @@ -233,6 +246,10 @@ fun SettingsScreen(sharedPreferencesViewModel: SharedPreferencesViewModel) { Spacer(modifier = HalfVertSpacer) + DontTranslateFromSetting(sharedPreferencesViewModel, languageEntries) + + Spacer(modifier = HalfVertSpacer) + SettingsRow( R.string.theme, R.string.theme_description, @@ -322,6 +339,78 @@ fun SettingsScreen(sharedPreferencesViewModel: SharedPreferencesViewModel) { } } +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun DontTranslateFromSetting( + sharedPreferencesViewModel: SharedPreferencesViewModel, + languageEntries: ImmutableMap, +) { + var expanded by remember { mutableStateOf(false) } + val selectedLanguages = sharedPreferencesViewModel.sharedPrefs.dontTranslateFrom + + Column { + SettingsRow( + name = R.string.dont_translate_from, + description = R.string.dont_translate_from_description, + ) { + ExposedDropdownMenuBox( + expanded = expanded, + onExpandedChange = { expanded = !expanded }, + ) { + OutlinedTextField( + value = stringRes(R.string.add_a_language), + onValueChange = {}, + readOnly = true, + trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) }, + modifier = Modifier.menuAnchor(), + ) + + ExposedDropdownMenu( + expanded = expanded, + onDismissRequest = { expanded = false }, + ) { + languageEntries.forEach { (displayName, languageCode) -> + if (!selectedLanguages.contains(languageCode)) { + DropdownMenuItem( + text = { Text(text = displayName) }, + onClick = { + sharedPreferencesViewModel.addDontTranslateFrom(languageCode) + expanded = false + }, + ) + } + } + } + } + } + + selectedLanguages.forEach { languageCode -> + val displayName = + languageEntries.entries.find { it.value == languageCode }?.key + ?: JavaLocale.forLanguageTag(languageCode).displayName + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = + Modifier + .fillMaxWidth() + .padding(vertical = Size10dp), + ) { + Text( + text = displayName, + modifier = Modifier.weight(1f), + ) + IconButton(onClick = { sharedPreferencesViewModel.removeDontTranslateFrom(languageCode) }) { + Icon( + imageVector = Icons.Default.Clear, + contentDescription = stringRes(R.string.remove), + tint = MaterialTheme.colorScheme.onSurface, + ) + } + } + } + } +} + @Composable fun SettingsRow( name: Int, diff --git a/amethyst/src/main/res/values/strings.xml b/amethyst/src/main/res/values/strings.xml index cbcfc0fb42..67ce651afd 100644 --- a/amethyst/src/main/res/values/strings.xml +++ b/amethyst/src/main/res/values/strings.xml @@ -1178,4 +1178,8 @@ Share image… Search hashtag: #%1$s + + Don\'t Translate From + Languages selected here will not be translated + Add a language