From 7fd163d6d43e651a508dad6af0f17eefe6a0931c Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sun, 1 Mar 2026 19:25:13 -0500 Subject: [PATCH] - Adds reactions and zap settings to the settings screen - Creates a better distinction between settings for the user and for the whole app. --- .../amethyst/ui/navigation/AppNavigation.kt | 2 +- .../ui/navigation/drawer/DrawerContent.kt | 26 ++-- .../loggedIn/settings/AllSettingsScreen.kt | 111 ++++++++++++++++-- amethyst/src/main/res/values/strings.xml | 11 +- 4 files changed, 118 insertions(+), 32 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 84fe53131..774452173 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 @@ -163,7 +163,7 @@ fun AppNavigation( composableFromBottomArgs { NewUserMetadataScreen(nav, accountViewModel) } composable { SearchScreen(accountViewModel, nav) } - composableFromEnd { AllSettingsScreen(nav) } + composableFromEnd { AllSettingsScreen(accountViewModel, nav) } composableFromEnd { SecurityFiltersScreen(accountViewModel, nav) } composableFromEnd { PrivacyOptionsScreen(Amethyst.instance.torPrefs.value, nav) } composableFromEnd { BookmarkListScreen(accountViewModel, nav) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt index 4d62d6ca7..72a872606 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt @@ -49,7 +49,6 @@ import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.outlined.CollectionsBookmark 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.Settings import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon @@ -102,7 +101,6 @@ import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.painterRes import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel -import com.vitorpamplona.amethyst.ui.screen.loggedIn.keyBackup.AccountBackupDialog import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer @@ -433,8 +431,6 @@ fun ListContent( accountViewModel: AccountViewModel, nav: INav, ) { - var backupDialogOpen by remember { mutableStateOf(false) } - Column(modifier) { NavigationRow( title = R.string.profile, @@ -477,17 +473,13 @@ fun ListContent( route = Route.Chess, ) - accountViewModel.account.settings.keyPair.privKey?.let { - IconRow( - title = R.string.backup_keys, - icon = Icons.Outlined.Key, - tint = MaterialTheme.colorScheme.onBackground, - onClick = { - nav.closeDrawer() - backupDialogOpen = true - }, - ) - } + IconRowRelays( + accountViewModel = accountViewModel, + onClick = { + nav.closeDrawer() + nav.nav(Route.EditRelays) + }, + ) NavigationRow( title = R.string.settings, @@ -506,10 +498,6 @@ fun ListContent( onClick = openSheet, ) } - - if (backupDialogOpen) { - AccountBackupDialog(accountViewModel, onClose = { backupDialogOpen = false }) - } } @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/AllSettingsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/AllSettingsScreen.kt index 13aad71c1..1b9ee3abd 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/AllSettingsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/AllSettingsScreen.kt @@ -27,7 +27,10 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.Bolt import androidx.compose.material.icons.outlined.CloudUpload +import androidx.compose.material.icons.outlined.FavoriteBorder +import androidx.compose.material.icons.outlined.Key import androidx.compose.material.icons.outlined.Security import androidx.compose.material.icons.outlined.Settings import androidx.compose.material.icons.outlined.Translate @@ -37,29 +40,75 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold 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 import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton +import com.vitorpamplona.amethyst.ui.note.UpdateReactionTypeDialog +import com.vitorpamplona.amethyst.ui.note.UpdateZapAmountDialog import com.vitorpamplona.amethyst.ui.painterRes +import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +import com.vitorpamplona.amethyst.ui.screen.loggedIn.keyBackup.AccountBackupDialog +import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel import com.vitorpamplona.amethyst.ui.stringRes +import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn + +@Preview +@Composable +fun AllSettingsScreenPreview() { + ThemeComparisonColumn { + AllSettingsScreen( + mockAccountViewModel(), + EmptyNav(), + ) + } +} @Composable -fun AllSettingsScreen(nav: INav) { +fun AllSettingsScreen( + accountViewModel: AccountViewModel, + nav: INav, +) { val tint = MaterialTheme.colorScheme.onBackground + var showReactionDialog by remember { mutableStateOf(false) } + var wantsToChangeZapAmount by remember { mutableStateOf(false) } + + if (showReactionDialog) { + UpdateReactionTypeDialog( + onClose = { showReactionDialog = false }, + accountViewModel = accountViewModel, + nav = nav, + ) + } + + if (wantsToChangeZapAmount) { + UpdateZapAmountDialog( + onClose = { wantsToChangeZapAmount = false }, + accountViewModel = accountViewModel, + ) + } + Scaffold( topBar = { TopBarWithBackButton(stringRes(id = R.string.settings), nav::popBack) }, ) { padding -> Column(Modifier.padding(padding)) { + SettingsSectionHeader(R.string.account_settings) SettingsNavigationRow( title = R.string.relay_setup, iconPainter = R.drawable.relays, @@ -75,6 +124,20 @@ fun AllSettingsScreen(nav: INav) { onClick = { nav.nav(Route.EditMediaServers) }, ) HorizontalDivider() + SettingsNavigationRow( + title = R.string.reactions, + icon = Icons.Outlined.FavoriteBorder, + tint = tint, + onClick = { showReactionDialog = true }, + ) + HorizontalDivider() + SettingsNavigationRow( + title = R.string.zaps, + icon = Icons.Outlined.Bolt, + tint = tint, + onClick = { wantsToChangeZapAmount = true }, + ) + HorizontalDivider() SettingsNavigationRow( title = R.string.security_filters, icon = Icons.Outlined.Security, @@ -82,6 +145,32 @@ fun AllSettingsScreen(nav: INav) { onClick = { nav.nav(Route.SecurityFilters) }, ) HorizontalDivider() + SettingsNavigationRow( + title = R.string.translations, + icon = Icons.Outlined.Translate, + tint = tint, + onClick = { nav.nav(Route.UserSettings) }, + ) + accountViewModel.account.settings.keyPair.privKey?.let { + var backupDialogOpen by remember { mutableStateOf(false) } + + HorizontalDivider() + SettingsNavigationRow( + title = R.string.backup_keys, + icon = Icons.Outlined.Key, + tint = tint, + onClick = { + nav.closeDrawer() + backupDialogOpen = true + }, + ) + + if (backupDialogOpen) { + AccountBackupDialog(accountViewModel, onClose = { backupDialogOpen = false }) + } + } + HorizontalDivider(thickness = 4.dp) + SettingsSectionHeader(R.string.app_settings) SettingsNavigationRow( title = R.string.privacy_options, iconPainter = R.drawable.ic_tor, @@ -91,22 +180,26 @@ fun AllSettingsScreen(nav: INav) { ) HorizontalDivider() SettingsNavigationRow( - title = R.string.preferences, + title = R.string.ui_preferences, icon = Icons.Outlined.Settings, tint = tint, onClick = { nav.nav(Route.Settings) }, ) - HorizontalDivider() - SettingsNavigationRow( - title = R.string.user_preferences, - icon = Icons.Outlined.Translate, - tint = tint, - onClick = { nav.nav(Route.UserSettings) }, - ) } } } +@Composable +private fun SettingsSectionHeader(title: Int) { + Text( + text = stringRes(title), + fontSize = 12.sp, + fontWeight = FontWeight.SemiBold, + color = MaterialTheme.colorScheme.primary, + modifier = Modifier.padding(start = 24.dp, end = 24.dp, top = 16.dp, bottom = 4.dp), + ) +} + @Composable private fun SettingsNavigationRow( title: Int, diff --git a/amethyst/src/main/res/values/strings.xml b/amethyst/src/main/res/values/strings.xml index 1d77673d4..b4a9a247d 100644 --- a/amethyst/src/main/res/values/strings.xml +++ b/amethyst/src/main/res/values/strings.xml @@ -123,7 +123,7 @@ Picture Url(Optional) Description Description not found - "About us.. " + "About us… " What\'s on your mind? Write a message… Post @@ -191,7 +191,7 @@ Anonymize Alters your voice pitch. Note: basic pitch changes can potentially be reversed by determined listeners. User does not have a lightning address set up to receive sats - "reply here.. " + "reply here… " Copies the Note ID to the clipboard for sharing in Nostr Copy Channel ID (Note) to the Clipboard Edits the Channel Metadata @@ -281,7 +281,7 @@ Public Chat Metadata Public chats are visible to everyone on Nostr and anyone can participate on them. They are great for open communities around specific topics. - Moderation can be controlled by deleting posts on the its relays + Moderation can be controlled by deleting posts on its relays Relays Insert between 1–3 relays that host this group. @@ -871,10 +871,15 @@ Sensitive Content Adds sensitive content warning before showing this content + UI Preferences App Preferences User Preferences + Translations + Reactions Settings + Account Settings + App Settings Always Wifi-only Unmetered WiFi