From 0495dc88fc6a030a73306fe0f1d76bb230070531 Mon Sep 17 00:00:00 2001 From: David Kaspar Date: Mon, 16 Jun 2025 15:52:46 +0200 Subject: [PATCH 01/13] 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 356f79707..0487326ae 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 dffe10581..68063f479 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 cbdd75954..f70b385b2 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 131d971bd..27293b754 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 cbcfc0fb4..67ce651af 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 From a5c370133c7d53a9bc8cda1c5d354b814ff6dbbf Mon Sep 17 00:00:00 2001 From: David Kaspar Date: Wed, 25 Jun 2025 10:53:28 +0200 Subject: [PATCH 02/13] Change to show excluded languages in dropdown, no rows below TODO: Load actually excluded languages Optimise code Improve UI --- .../ui/screen/SharedPreferencesViewModel.kt | 8 --- .../loggedIn/settings/AppSettingsScreen.kt | 54 ++++--------------- amethyst/src/main/res/values/strings.xml | 4 +- 3 files changed, 12 insertions(+), 54 deletions(-) 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 68063f479..e8c7e8d4f 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 @@ -83,14 +83,6 @@ 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) { 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 27293b754..ef85341a5 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,14 +32,10 @@ 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 @@ -246,7 +242,7 @@ fun SettingsScreen(sharedPreferencesViewModel: SharedPreferencesViewModel) { Spacer(modifier = HalfVertSpacer) - DontTranslateFromSetting(sharedPreferencesViewModel, languageEntries) + DontTranslateFromSetting(sharedPreferencesViewModel) Spacer(modifier = HalfVertSpacer) @@ -341,10 +337,7 @@ fun SettingsScreen(sharedPreferencesViewModel: SharedPreferencesViewModel) { @OptIn(ExperimentalMaterial3Api::class) @Composable -fun DontTranslateFromSetting( - sharedPreferencesViewModel: SharedPreferencesViewModel, - languageEntries: ImmutableMap, -) { +fun DontTranslateFromSetting(sharedPreferencesViewModel: SharedPreferencesViewModel) { var expanded by remember { mutableStateOf(false) } val selectedLanguages = sharedPreferencesViewModel.sharedPrefs.dontTranslateFrom @@ -369,45 +362,18 @@ fun DontTranslateFromSetting( 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 -> + DropdownMenuItem( + text = { Text(text = JavaLocale.forLanguageTag(languageCode).displayName) }, + onClick = { + sharedPreferencesViewModel.removeDontTranslateFrom(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, - ) - } - } - } } } diff --git a/amethyst/src/main/res/values/strings.xml b/amethyst/src/main/res/values/strings.xml index 67ce651af..c1f4d8aad 100644 --- a/amethyst/src/main/res/values/strings.xml +++ b/amethyst/src/main/res/values/strings.xml @@ -1180,6 +1180,6 @@ Search hashtag: #%1$s Don\'t Translate From - Languages selected here will not be translated - Add a language + Languages shown here will not be translated. Select a language to remove it and have it translated again. + Select to remove From 2e2a9bb9177d02daecba0ab5dfd8c1d77403b8eb Mon Sep 17 00:00:00 2001 From: David Kaspar Date: Wed, 25 Jun 2025 18:13:43 +0200 Subject: [PATCH 03/13] Added user preferences screen --- .../amethyst/ui/navigation/AppNavigation.kt | 2 + .../amethyst/ui/navigation/DrawerContent.kt | 8 +++ .../amethyst/ui/navigation/Routes.kt | 2 + .../loggedIn/settings/UserSettingsScreen.kt | 51 +++++++++++++++++++ amethyst/src/main/res/values/strings.xml | 1 + 5 files changed, 64 insertions(+) create mode 100644 amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt index aee8a9f70..f9fcbf096 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt @@ -84,6 +84,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.search.SearchScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.NIP47SetupScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.SecurityFiltersScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.SettingsScreen +import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.UserSettingsScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.ThreadScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.video.VideoScreen import com.vitorpamplona.amethyst.ui.screen.loggedOff.AddAccountDialog @@ -123,6 +124,7 @@ fun AppNavigation( composableFromEnd { BookmarkListScreen(accountViewModel, nav) } composableFromEnd { DraftListScreen(accountViewModel, nav) } composableFromEnd { SettingsScreen(sharedPreferencesViewModel, accountViewModel, nav) } + composableFromEnd { UserSettingsScreen(accountViewModel, nav) } composableFromBottomArgs { NIP47SetupScreen(accountViewModel, nav, it.nip47) } composableFromEndArgs { AllRelayListScreen(it.toAdd, accountViewModel, nav) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt index 687b012bb..2aec48a00 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt @@ -508,6 +508,14 @@ fun ListContent( route = Route.Settings, ) + NavigationRow( + title = R.string.user_preferences, + icon = Icons.Outlined.Settings, + tint = MaterialTheme.colorScheme.onBackground, + nav = nav, + route = Route.UserSettings, + ) + Spacer(modifier = Modifier.weight(1f)) IconRow( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt index eced5ad9c..7be1576e3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/Routes.kt @@ -62,6 +62,8 @@ sealed class Route { @Serializable object Settings : Route() + @Serializable object UserSettings : Route() + @Serializable object EditProfile : Route() @Serializable data class EditRelays( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt new file mode 100644 index 000000000..f9f08427b --- /dev/null +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.amethyst.ui.screen.loggedIn.settings + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold +import com.vitorpamplona.amethyst.ui.navigation.INav +import com.vitorpamplona.amethyst.ui.navigation.TopBarWithBackButton +import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +import com.vitorpamplona.amethyst.ui.stringRes + +@Composable +fun UserSettingsScreen( + accountViewModel: AccountViewModel, + nav: INav, +) { + DisappearingScaffold( + isInvertedLayout = false, + topBar = { + TopBarWithBackButton(stringRes(id = R.string.user_preferences), nav::popBack) + }, + accountViewModel = accountViewModel, + ) { + Column(Modifier.padding(it)) { + Text("Hello World!") + } + } +} diff --git a/amethyst/src/main/res/values/strings.xml b/amethyst/src/main/res/values/strings.xml index c1f4d8aad..b57c94024 100644 --- a/amethyst/src/main/res/values/strings.xml +++ b/amethyst/src/main/res/values/strings.xml @@ -675,6 +675,7 @@ Adds sensitive content warning before showing this content App Preferences + User Preferences Settings Always From 3524f7e412f2d7fa774dcbc021b3bdf7b59a0205 Mon Sep 17 00:00:00 2001 From: David Kaspar Date: Wed, 25 Jun 2025 20:18:11 +0200 Subject: [PATCH 04/13] Added support for multiple icons for a single row (backwards compatible) --- .../amethyst/ui/navigation/DrawerContent.kt | 62 ++++++++++++++----- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt index 2aec48a00..f52aaed5e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/DrawerContent.kt @@ -51,6 +51,7 @@ import androidx.compose.material.icons.outlined.CloudUpload import androidx.compose.material.icons.outlined.Drafts import androidx.compose.material.icons.outlined.GroupAdd import androidx.compose.material.icons.outlined.Key +import androidx.compose.material.icons.outlined.Person import androidx.compose.material.icons.outlined.Security import androidx.compose.material.icons.outlined.Settings import androidx.compose.material3.HorizontalDivider @@ -66,7 +67,6 @@ import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -74,7 +74,6 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.text.LinkAnnotation import androidx.compose.ui.text.SpanStyle @@ -427,8 +426,6 @@ fun ListContent( var backupDialogOpen by remember { mutableStateOf(false) } - val context = LocalContext.current - Column(modifier) { NavigationRow( title = R.string.profile, @@ -510,7 +507,7 @@ fun ListContent( NavigationRow( title = R.string.user_preferences, - icon = Icons.Outlined.Settings, + icons = listOf(Icons.Outlined.Person, Icons.Outlined.Settings), tint = MaterialTheme.colorScheme.onBackground, nav = nav, route = Route.UserSettings, @@ -592,11 +589,28 @@ fun NavigationRow( tint: Color, nav: INav, route: Route, +) { + NavigationRow( + title = title, + icons = listOf(icon), + tint = tint, + nav = nav, + route = route, + ) +} + +@Composable +fun NavigationRow( + title: Int, + icons: List, + tint: Color, + nav: INav, + route: Route, ) { IconRow( - title, - icon, - tint, + title = title, + icons = icons, + tint = tint, onClick = { nav.closeDrawer() nav.nav(route) @@ -644,6 +658,21 @@ fun IconRow( icon: ImageVector, tint: Color, onClick: () -> Unit, +) { + IconRow( + title = title, + icons = listOf(icon), + tint = tint, + onClick = onClick, + ) +} + +@Composable +fun IconRow( + title: Int, + icons: List, + tint: Color, + onClick: () -> Unit, ) { Row( modifier = @@ -658,12 +687,15 @@ fun IconRow( modifier = IconRowModifier, verticalAlignment = Alignment.CenterVertically, ) { - Icon( - imageVector = icon, - contentDescription = stringRes(title), - modifier = Size22Modifier, - tint = tint, - ) + icons.forEach { icon -> + Icon( + imageVector = icon, + contentDescription = stringRes(title), + modifier = Size22Modifier.padding(end = 4.dp), + tint = tint, + ) + } + Text( modifier = IconRowTextModifier, text = stringRes(title), @@ -717,8 +749,6 @@ fun BottomContent( accountViewModel: AccountViewModel, nav: INav, ) { - val coroutineScope = rememberCoroutineScope() - // store the dialog open or close state var dialogOpen by remember { mutableStateOf(false) } From c59086068b664e0379f603cefcddbf9948b88b6c Mon Sep 17 00:00:00 2001 From: David Kaspar Date: Wed, 25 Jun 2025 20:31:21 +0200 Subject: [PATCH 05/13] Move dont translate settings to the dedicated user settings page --- .../amethyst/ui/navigation/AppNavigation.kt | 3 - .../ui/screen/loggedIn/AccountViewModel.kt | 2 + .../loggedIn/settings/AppSettingsScreen.kt | 57 +--------------- .../loggedIn/settings/UserSettingsScreen.kt | 68 +++++++++++++++++++ 4 files changed, 71 insertions(+), 59 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt index f9fcbf096..48276a4c7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt @@ -253,9 +253,6 @@ private fun NavigateIfIntentRequested( } nav.newStack(Route.NewPost(message = message, attachment = media.toString())) - - media = null - message = null } else { var newAccount by remember { mutableStateOf(null) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt index 6fc5e8653..2edbbd430 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt @@ -898,6 +898,8 @@ class AccountViewModel( fun dontTranslateFrom() = account.settings.syncedSettings.languages.dontTranslateFrom + fun toggleDontTranslateFrom(languageCode: String) = account.toggleDontTranslateFrom(languageCode) + fun translateTo() = account.settings.syncedSettings.languages.translateTo fun defaultZapType() = account.settings.syncedSettings.zaps.defaultZapType.value 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 ef85341a5..f89306911 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,18 +32,10 @@ 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.material3.DropdownMenuItem -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.ExposedDropdownMenuBox -import androidx.compose.material3.ExposedDropdownMenuDefaults 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 @@ -85,7 +77,6 @@ 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() @@ -128,7 +119,7 @@ fun getLanguageIndex( sharedPreferencesViewModel: SharedPreferencesViewModel, ): Int { val language = sharedPreferencesViewModel.sharedPrefs.language - var languageIndex = -1 + var languageIndex: Int if (language != null) { languageIndex = languageEntries.values.toTypedArray().indexOf(language) } else { @@ -242,10 +233,6 @@ fun SettingsScreen(sharedPreferencesViewModel: SharedPreferencesViewModel) { Spacer(modifier = HalfVertSpacer) - DontTranslateFromSetting(sharedPreferencesViewModel) - - Spacer(modifier = HalfVertSpacer) - SettingsRow( R.string.theme, R.string.theme_description, @@ -335,48 +322,6 @@ fun SettingsScreen(sharedPreferencesViewModel: SharedPreferencesViewModel) { } } -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun DontTranslateFromSetting(sharedPreferencesViewModel: SharedPreferencesViewModel) { - 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 }, - ) { - selectedLanguages.forEach { languageCode -> - DropdownMenuItem( - text = { Text(text = JavaLocale.forLanguageTag(languageCode).displayName) }, - onClick = { - sharedPreferencesViewModel.removeDontTranslateFrom(languageCode) - expanded = false - }, - ) - } - } - } - } - } -} - @Composable fun SettingsRow( name: Int, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt index f9f08427b..4ae886b4b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt @@ -21,9 +21,22 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.settings import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ExposedDropdownMenuBox +import androidx.compose.material3.ExposedDropdownMenuDefaults +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 com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold @@ -31,6 +44,9 @@ import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.navigation.TopBarWithBackButton import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.stringRes +import com.vitorpamplona.amethyst.ui.theme.Size10dp +import com.vitorpamplona.amethyst.ui.theme.Size20dp +import java.util.Locale as JavaLocale @Composable fun UserSettingsScreen( @@ -46,6 +62,58 @@ fun UserSettingsScreen( ) { Column(Modifier.padding(it)) { Text("Hello World!") + + Column( + Modifier + .fillMaxSize() + .padding(top = Size10dp, start = Size20dp, end = Size20dp) + .verticalScroll(rememberScrollState()), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + DontTranslateFromSetting(accountViewModel) + } + } + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun DontTranslateFromSetting(accountViewModel: AccountViewModel) { + var expanded by remember { mutableStateOf(false) } + val selectedLanguages = accountViewModel.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 }, + ) { + selectedLanguages.forEach { languageCode -> + DropdownMenuItem( + text = { Text(text = JavaLocale.forLanguageTag(languageCode).displayName) }, + onClick = { + accountViewModel.toggleDontTranslateFrom(languageCode) + expanded = false + }, + ) + } + } + } } } } From f0670971ef8239b60406c555f1ca09a8a8bf59c7 Mon Sep 17 00:00:00 2001 From: David Kaspar Date: Wed, 25 Jun 2025 20:51:11 +0200 Subject: [PATCH 06/13] Wrap update call in IO scope TODO: Don't show users own languages Remove language from drop down Add explainer --- .../ui/screen/loggedIn/settings/UserSettingsScreen.kt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt index 4ae886b4b..1d30cfe38 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt @@ -38,6 +38,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.lifecycle.viewModelScope import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold import com.vitorpamplona.amethyst.ui.navigation.INav @@ -46,6 +47,8 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.Size10dp import com.vitorpamplona.amethyst.ui.theme.Size20dp +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import java.util.Locale as JavaLocale @Composable @@ -61,8 +64,6 @@ fun UserSettingsScreen( accountViewModel = accountViewModel, ) { Column(Modifier.padding(it)) { - Text("Hello World!") - Column( Modifier .fillMaxSize() @@ -107,7 +108,11 @@ fun DontTranslateFromSetting(accountViewModel: AccountViewModel) { DropdownMenuItem( text = { Text(text = JavaLocale.forLanguageTag(languageCode).displayName) }, onClick = { - accountViewModel.toggleDontTranslateFrom(languageCode) + accountViewModel.viewModelScope.launch(Dispatchers.IO) { + accountViewModel.toggleDontTranslateFrom( + languageCode, + ) + } expanded = false }, ) From 759ef44440dcd2310889a8934e70005d79d88e4f Mon Sep 17 00:00:00 2001 From: David Kaspar Date: Wed, 25 Jun 2025 20:54:19 +0200 Subject: [PATCH 07/13] Remove previous implementation TODO: Rename Settings to AppSettings (routes, classes) Don't show users own languages Remove language from drop down Add explainer Change to dropdown with Xs --- .../java/com/vitorpamplona/amethyst/model/Settings.kt | 1 - .../amethyst/ui/screen/SharedPreferencesViewModel.kt | 10 ---------- .../amethyst/ui/screen/SharedSettingsState.kt | 2 +- .../ui/screen/loggedIn/settings/AppSettingsScreen.kt | 11 ++++++----- 4 files changed, 7 insertions(+), 17 deletions(-) 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 0487326ae..356f79707 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Settings.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Settings.kt @@ -27,7 +27,6 @@ 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 e8c7e8d4f..dffe10581 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,7 +52,6 @@ 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 @@ -83,14 +82,6 @@ class SharedPreferencesViewModel : ViewModel() { } } - 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) { @@ -197,7 +188,6 @@ 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 f70b385b2..cbdd75954 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 f89306911..ed6911b7a 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 @@ -120,11 +120,12 @@ fun getLanguageIndex( ): Int { val language = sharedPreferencesViewModel.sharedPrefs.language var languageIndex: Int - if (language != null) { - languageIndex = languageEntries.values.toTypedArray().indexOf(language) - } else { - languageIndex = languageEntries.values.toTypedArray().indexOf(Locale.current.toLanguageTag()) - } + languageIndex = + if (language != null) { + languageEntries.values.toTypedArray().indexOf(language) + } else { + languageEntries.values.toTypedArray().indexOf(Locale.current.toLanguageTag()) + } if (languageIndex == -1) { languageIndex = languageEntries.values.toTypedArray().indexOf(Locale.current.language) } From 5620eb023b6d00ff614cec511099fdd0d89a5790 Mon Sep 17 00:00:00 2001 From: David Kaspar Date: Thu, 26 Jun 2025 08:56:23 +0200 Subject: [PATCH 08/13] added preview for UserSettingsScreen.kt TODO: Rename Settings to AppSettings (routes, classes) Don't show users own languages Remove language from drop down Add explainer --- .../loggedIn/settings/UserSettingsScreen.kt | 21 +++++++++++++++++-- amethyst/src/main/res/values/strings.xml | 1 - 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt index 1d30cfe38..dbdd51c58 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt @@ -21,8 +21,10 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.settings import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize 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.material3.DropdownMenuItem @@ -38,19 +40,34 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp import androidx.lifecycle.viewModelScope import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold +import com.vitorpamplona.amethyst.ui.navigation.EmptyNav import com.vitorpamplona.amethyst.ui.navigation.INav import com.vitorpamplona.amethyst.ui.navigation.TopBarWithBackButton import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.Size10dp import com.vitorpamplona.amethyst.ui.theme.Size20dp +import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonRow import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.util.Locale as JavaLocale +@Preview(device = "spec:width=2160px,height=2340px,dpi=440") +@Composable +fun UserSettingsScreenPreview() { + val accountViewModel = mockAccountViewModel() + val nav = EmptyNav + ThemeComparisonRow { + UserSettingsScreen(accountViewModel, nav) + } +} + @Composable fun UserSettingsScreen( accountViewModel: AccountViewModel, @@ -93,11 +110,11 @@ fun DontTranslateFromSetting(accountViewModel: AccountViewModel) { onExpandedChange = { expanded = !expanded }, ) { OutlinedTextField( - value = stringRes(R.string.add_a_language), + value = stringRes(R.string.quick_action_select), onValueChange = {}, readOnly = true, trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) }, - modifier = Modifier.menuAnchor(), + modifier = Modifier.windowInsetsPadding(WindowInsets(0.dp, 0.dp, 0.dp, 0.dp)), ) ExposedDropdownMenu( diff --git a/amethyst/src/main/res/values/strings.xml b/amethyst/src/main/res/values/strings.xml index b57c94024..2d9b6cdb2 100644 --- a/amethyst/src/main/res/values/strings.xml +++ b/amethyst/src/main/res/values/strings.xml @@ -1182,5 +1182,4 @@ Don\'t Translate From Languages shown here will not be translated. Select a language to remove it and have it translated again. - Select to remove From fdf11d3ca39c119a28d891bf7b5a2c3a3282eae3 Mon Sep 17 00:00:00 2001 From: David Kaspar Date: Thu, 26 Jun 2025 09:06:02 +0200 Subject: [PATCH 09/13] revert dropdown TODO: Rename Settings to AppSettings (routes, classes) Don't show users own languages Remove language from drop down Add explainer --- .../ui/screen/loggedIn/settings/UserSettingsScreen.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt index dbdd51c58..ce61a37f8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt @@ -21,16 +21,15 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.settings import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize 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.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExposedDropdownMenuBox import androidx.compose.material3.ExposedDropdownMenuDefaults +import androidx.compose.material3.MenuAnchorType import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -41,7 +40,6 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp import androidx.lifecycle.viewModelScope import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold @@ -114,7 +112,7 @@ fun DontTranslateFromSetting(accountViewModel: AccountViewModel) { onValueChange = {}, readOnly = true, trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) }, - modifier = Modifier.windowInsetsPadding(WindowInsets(0.dp, 0.dp, 0.dp, 0.dp)), + modifier = Modifier.menuAnchor(MenuAnchorType.PrimaryEditable), ) ExposedDropdownMenu( From 6015ea04cefbf70e1c4a7cc4ea15b1d123d0e400 Mon Sep 17 00:00:00 2001 From: David Kaspar Date: Thu, 26 Jun 2025 13:16:51 +0200 Subject: [PATCH 10/13] remove selected language from dropdown TODO: Rename Settings to AppSettings (routes, classes) Don't show users own languages Add explainer --- .../amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt index ce61a37f8..e95ca4664 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt @@ -96,7 +96,7 @@ fun UserSettingsScreen( @Composable fun DontTranslateFromSetting(accountViewModel: AccountViewModel) { var expanded by remember { mutableStateOf(false) } - val selectedLanguages = accountViewModel.dontTranslateFrom() + val selectedLanguages = accountViewModel.dontTranslateFrom().toMutableSet() Column { SettingsRow( @@ -128,6 +128,7 @@ fun DontTranslateFromSetting(accountViewModel: AccountViewModel) { languageCode, ) } + selectedLanguages.remove(languageCode) expanded = false }, ) From 65cca8aa3483bb1fbcbbcf81ecc6ffe913f7092f Mon Sep 17 00:00:00 2001 From: David Kaspar Date: Sun, 29 Jun 2025 17:29:20 +0100 Subject: [PATCH 11/13] Don't show users own languages TODO: Add red x to items Rename Settings to AppSettings (routes, classes) Add explainer --- .../com/vitorpamplona/amethyst/model/AccountSyncedSettings.kt | 4 ++++ .../amethyst/ui/screen/loggedIn/AccountViewModel.kt | 2 ++ .../ui/screen/loggedIn/settings/UserSettingsScreen.kt | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSyncedSettings.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSyncedSettings.kt index c6a6bb951..8ee4e293f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSyncedSettings.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AccountSyncedSettings.kt @@ -113,6 +113,10 @@ class AccountSyncedSettings( security.warnAboutPostsWithReports = syncedSettingsInternal.security.warnAboutPostsWithReports } } + + fun dontTranslateFromFilteredBySpokenLanguages(): Set { + return languages.dontTranslateFrom - getLanguagesSpokenByUser() + } } @Stable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt index 2edbbd430..f4d592aac 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt @@ -898,6 +898,8 @@ class AccountViewModel( fun dontTranslateFrom() = account.settings.syncedSettings.languages.dontTranslateFrom + fun dontTranslateFromFilteredBySpokenLanguages() = account.settings.syncedSettings.dontTranslateFromFilteredBySpokenLanguages() + fun toggleDontTranslateFrom(languageCode: String) = account.toggleDontTranslateFrom(languageCode) fun translateTo() = account.settings.syncedSettings.languages.translateTo diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt index e95ca4664..4c025091e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt @@ -96,7 +96,7 @@ fun UserSettingsScreen( @Composable fun DontTranslateFromSetting(accountViewModel: AccountViewModel) { var expanded by remember { mutableStateOf(false) } - val selectedLanguages = accountViewModel.dontTranslateFrom().toMutableSet() + val selectedLanguages = accountViewModel.dontTranslateFromFilteredBySpokenLanguages().toMutableSet() Column { SettingsRow( From 285603cc0fa095cbe8d3ff2d987397c6ffc87806 Mon Sep 17 00:00:00 2001 From: David Kaspar Date: Sun, 29 Jun 2025 17:37:50 +0100 Subject: [PATCH 12/13] added trailing x icon to menu items to clarify removal --- .../screen/loggedIn/settings/UserSettingsScreen.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt index 4c025091e..9f57b1af5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/UserSettingsScreen.kt @@ -23,12 +23,16 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.settings import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Close 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.MenuAnchorType import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text @@ -39,7 +43,9 @@ 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 import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp import androidx.lifecycle.viewModelScope import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold @@ -131,6 +137,14 @@ fun DontTranslateFromSetting(accountViewModel: AccountViewModel) { selectedLanguages.remove(languageCode) expanded = false }, + trailingIcon = { + Icon( + imageVector = Icons.Default.Close, + contentDescription = "Remove $languageCode", + tint = Color.Red, + modifier = Modifier.size(16.dp), + ) + }, ) } } From fb9c070ee60226ed4c0e5d34629ebeb9523b26eb Mon Sep 17 00:00:00 2001 From: David Kaspar Date: Sun, 29 Jun 2025 18:33:30 +0100 Subject: [PATCH 13/13] One more line for description --- .../amethyst/ui/screen/loggedIn/settings/AppSettingsScreen.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ed6911b7a..5eb38c0aa 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 @@ -366,7 +366,7 @@ fun SettingsRow( text = stringRes(description), style = MaterialTheme.typography.bodySmall, color = Color.Gray, - maxLines = 2, + maxLines = 3, overflow = TextOverflow.Ellipsis, ) }