From 285af9adbe305a376eed34154863d5a136747d6d Mon Sep 17 00:00:00 2001 From: Aleksandar Ilic Date: Wed, 24 Jan 2024 15:48:16 +0100 Subject: [PATCH] Update wallet settings --- .../core/compose/PrimalNavigationBar.kt | 2 +- .../settings/wallet/ExternalWalletSettings.kt | 139 +---------- .../settings/wallet/WalletSettingsScreen.kt | 229 +++++++++++++----- .../wallet/dashboard/WalletDashboardScreen.kt | 8 +- app/src/main/res/values/strings.xml | 1 + 5 files changed, 180 insertions(+), 199 deletions(-) diff --git a/app/src/main/kotlin/net/primal/android/core/compose/PrimalNavigationBar.kt b/app/src/main/kotlin/net/primal/android/core/compose/PrimalNavigationBar.kt index d8579fae..701ab529 100644 --- a/app/src/main/kotlin/net/primal/android/core/compose/PrimalNavigationBar.kt +++ b/app/src/main/kotlin/net/primal/android/core/compose/PrimalNavigationBar.kt @@ -54,7 +54,7 @@ import net.primal.android.theme.AppTheme import net.primal.android.theme.PrimalTheme import net.primal.android.user.domain.Badges -private val NavigationBarFullHeightDp = 64.dp +val NavigationBarFullHeightDp = 64.dp private val NavigationBarBoltCircleSizeDp = NavigationBarFullHeightDp private val NavigationBarVisibleHeightDp = 56.dp private val NavigationBarBoltBorderSpaceDp = 6.dp diff --git a/app/src/main/kotlin/net/primal/android/settings/wallet/ExternalWalletSettings.kt b/app/src/main/kotlin/net/primal/android/settings/wallet/ExternalWalletSettings.kt index 7c7ac43d..7e3eb07c 100644 --- a/app/src/main/kotlin/net/primal/android/settings/wallet/ExternalWalletSettings.kt +++ b/app/src/main/kotlin/net/primal/android/settings/wallet/ExternalWalletSettings.kt @@ -12,10 +12,6 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Card -import androidx.compose.material3.CardDefaults -import androidx.compose.material3.ListItem -import androidx.compose.material3.ListItemDefaults import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -29,8 +25,6 @@ import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview @@ -40,82 +34,29 @@ import androidx.compose.ui.unit.sp import net.primal.android.R import net.primal.android.core.compose.IconText import net.primal.android.core.compose.PrimalDivider -import net.primal.android.core.compose.PrimalSwitch import net.primal.android.core.compose.button.PrimalFilledButton import net.primal.android.core.compose.button.PrimalLoadingButton import net.primal.android.theme.AppTheme import net.primal.android.theme.PrimalTheme import net.primal.android.theme.domain.PrimalTheme import net.primal.android.user.domain.NostrWalletConnect -import net.primal.android.user.domain.WalletPreference @Composable -fun ExternalWalletSettings( - nwcWallet: NostrWalletConnect?, - walletPreference: WalletPreference, - profileLightningAddress: String?, - onUsePrimalWalletSwitchChanged: (Boolean) -> Unit, - onExternalWalletDisconnect: () -> Unit, - onEditProfileClick: () -> Unit, -) { +fun ExternalWalletSettings(nwcWallet: NostrWalletConnect?, onExternalWalletDisconnect: () -> Unit) { Column( modifier = Modifier.animateContentSize(), ) { - val primalWalletPreferred = walletPreference != WalletPreference.NostrWalletConnect - ExternalWalletListItem( - preferPrimalWallet = primalWalletPreferred, - onExternalWalletSwitchChanged = onUsePrimalWalletSwitchChanged, - ) - - if (!primalWalletPreferred) { - Spacer(modifier = Modifier.height(24.dp)) - - ExternalWalletSection( - nwcWallet = nwcWallet, - onExternalWalletDisconnect = onExternalWalletDisconnect, - ) + Spacer(modifier = Modifier.height(16.dp)) - Spacer(modifier = Modifier.height(24.dp)) + ExternalWalletSection( + nwcWallet = nwcWallet, + onExternalWalletDisconnect = onExternalWalletDisconnect, + ) - NostrProfileLightingAddressSection( - lightningAddress = profileLightningAddress, - onEditProfileClick = onEditProfileClick, - ) - } + Spacer(modifier = Modifier.height(16.dp)) } } -@Composable -private fun ExternalWalletListItem(preferPrimalWallet: Boolean, onExternalWalletSwitchChanged: (Boolean) -> Unit) { - ListItem( - modifier = Modifier.clickable { - onExternalWalletSwitchChanged(!preferPrimalWallet) - }, - headlineContent = { - Text( - modifier = Modifier.padding(bottom = 4.dp), - text = stringResource(id = R.string.settings_wallet_use_primal_wallet), - style = AppTheme.typography.bodyLarge, - color = AppTheme.colorScheme.onPrimary, - ) - }, - supportingContent = { - Text( - modifier = Modifier.fillMaxWidth(), - text = stringResource(id = R.string.settings_wallet_use_primal_wallet_hint), - style = AppTheme.typography.bodySmall, - color = AppTheme.extraColorScheme.onSurfaceVariantAlt1, - ) - }, - trailingContent = { - PrimalSwitch( - checked = preferPrimalWallet, - onCheckedChange = onExternalWalletSwitchChanged, - ) - }, - ) -} - @Composable private fun ExternalWalletSection(nwcWallet: NostrWalletConnect?, onExternalWalletDisconnect: () -> Unit) { SectionTitle( @@ -292,68 +233,6 @@ fun ConnectMutinyWalletButton(modifier: Modifier = Modifier, onClick: (() -> Uni } } -@Composable -private fun NostrProfileLightingAddressSection(lightningAddress: String?, onEditProfileClick: () -> Unit) { - Column { - SectionTitle( - title = stringResource(id = R.string.settings_wallet_nwc_profile_lightning_address), - ) - - Card( - modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp), - colors = CardDefaults.cardColors( - containerColor = AppTheme.extraColorScheme.surfaceVariantAlt1, - ), - ) { - ListItem( - modifier = Modifier.clickable { onEditProfileClick() }, - colors = ListItemDefaults.colors( - containerColor = AppTheme.extraColorScheme.surfaceVariantAlt1, - ), - headlineContent = { - Text( - text = "Address", - style = AppTheme.typography.bodyMedium.copy(fontSize = 16.sp), - ) - }, - trailingContent = { - Text( - text = lightningAddress ?: "", - style = AppTheme.typography.bodyMedium.copy(fontSize = 16.sp), - ) - }, - ) - } - Text( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(horizontal = 4.dp) - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null, - onClick = onEditProfileClick, - ), - text = buildAnnotatedString { - append(stringResource(id = R.string.settings_wallet_nwc_profile_lightning_address_hint)) - append( - AnnotatedString( - text = " ${ - stringResource(id = R.string.settings_wallet_nwc_profile_lightning_address_hint_suffix) - }", - spanStyle = SpanStyle( - color = AppTheme.colorScheme.secondary, - fontStyle = AppTheme.typography.bodySmall.fontStyle, - ), - ), - ) - append(".") - }, - style = AppTheme.typography.bodySmall, - ) - } -} - @Preview @Composable private fun PreviewExternalWalletSettings( @@ -365,11 +244,7 @@ private fun PreviewExternalWalletSettings( Column { ExternalWalletSettings( nwcWallet = state.wallet, - walletPreference = state.walletPreference, - profileLightningAddress = state.userLightningAddress, - onUsePrimalWalletSwitchChanged = {}, onExternalWalletDisconnect = {}, - onEditProfileClick = {}, ) } } diff --git a/app/src/main/kotlin/net/primal/android/settings/wallet/WalletSettingsScreen.kt b/app/src/main/kotlin/net/primal/android/settings/wallet/WalletSettingsScreen.kt index a56a7854..ce841d3f 100644 --- a/app/src/main/kotlin/net/primal/android/settings/wallet/WalletSettingsScreen.kt +++ b/app/src/main/kotlin/net/primal/android/settings/wallet/WalletSettingsScreen.kt @@ -1,10 +1,12 @@ package net.primal.android.settings.wallet -import androidx.compose.animation.animateContentSize +import androidx.compose.animation.AnimatedContent import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState @@ -12,6 +14,7 @@ import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowForwardIos import androidx.compose.material.icons.outlined.Info import androidx.compose.material3.AlertDialog import androidx.compose.material3.ExperimentalMaterial3Api @@ -34,6 +37,9 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.AnnotatedString +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.tooling.preview.Preview @@ -43,6 +49,7 @@ import androidx.compose.ui.unit.dp import androidx.core.text.isDigitsOnly import java.text.NumberFormat import net.primal.android.R +import net.primal.android.core.compose.PrimalSwitch import net.primal.android.core.compose.PrimalTopAppBar import net.primal.android.core.compose.icons.PrimalIcons import net.primal.android.core.compose.icons.primaliconpack.ArrowBack @@ -81,6 +88,8 @@ fun WalletSettingsScreen( ) { val scrollState = rememberScrollState() val numberFormat = remember { NumberFormat.getNumberInstance() } + val primalWalletPreferred = state.walletPreference != WalletPreference.NostrWalletConnect + Scaffold( modifier = Modifier, topBar = { @@ -94,18 +103,15 @@ fun WalletSettingsScreen( Column( modifier = Modifier .verticalScroll(scrollState) - .padding(paddingValues) - .animateContentSize(), + .padding(paddingValues), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, ) { Spacer(modifier = Modifier.height(16.dp)) - ExternalWalletSettings( - nwcWallet = state.wallet, - walletPreference = state.walletPreference, - profileLightningAddress = state.userLightningAddress, - onUsePrimalWalletSwitchChanged = { enabled -> + ExternalWalletListItem( + preferPrimalWallet = primalWalletPreferred, + onExternalWalletSwitchChanged = { enabled -> eventPublisher( UiEvent.UpdateWalletPreference( walletPreference = if (enabled) { @@ -116,77 +122,129 @@ fun WalletSettingsScreen( ), ) }, - onExternalWalletDisconnect = { - eventPublisher(UiEvent.DisconnectWallet) - }, - onEditProfileClick = onEditProfileClick, ) - if (state.walletPreference != WalletPreference.NostrWalletConnect) { -// Spacer(modifier = Modifier.height(8.dp)) + AnimatedContent(targetState = primalWalletPreferred, label = "WalletSettingsContent") { + when (it) { + true -> { + Column { +// Spacer(modifier = Modifier.height(8.dp)) // -// SettingsItem( -// headlineText = stringResource(id = R.string.settings_wallet_start_in_wallet), -// supportText = stringResource(id = R.string.settings_wallet_start_in_wallet_hint), -// trailingContent = { -// PrimalSwitch( -// checked = false, -// onCheckedChange = { -// }, -// ) -// }, -// onClick = { -// }, -// ) +// SettingsItem( +// headlineText = stringResource(id = R.string.settings_wallet_start_in_wallet), +// supportText = stringResource(id = R.string.settings_wallet_start_in_wallet_hint), +// trailingContent = { +// PrimalSwitch( +// checked = false, +// onCheckedChange = { +// }, +// ) +// }, +// onClick = { +// }, +// ) - Spacer(modifier = Modifier.height(8.dp)) + Spacer(modifier = Modifier.height(8.dp)) - var spamThresholdAmountEditorDialog by remember { mutableStateOf(false) } - val spamThresholdAmountInSats = state.spamThresholdAmountInSats?.let { - numberFormat.format(it) - } ?: "1" - SettingsItem( - headlineText = stringResource(id = R.string.settings_wallet_hide_transactions_below), - supportText = "$spamThresholdAmountInSats sats", - onClick = { spamThresholdAmountEditorDialog = true }, - ) + var spamThresholdAmountEditorDialog by remember { mutableStateOf(false) } + val spamThresholdAmountInSats = state.spamThresholdAmountInSats?.let { + numberFormat.format(it) + } ?: "1" + SettingsItem( + headlineText = stringResource( + id = R.string.settings_wallet_hide_transactions_below, + ), + supportText = "$spamThresholdAmountInSats sats", + onClick = { spamThresholdAmountEditorDialog = true }, + ) - if (spamThresholdAmountEditorDialog) { - SpamThresholdAmountEditorDialog( - onDialogDismiss = { spamThresholdAmountEditorDialog = false }, - onEditAmount = { - eventPublisher(UiEvent.UpdateMinTransactionAmount(amountInSats = it)) - }, - ) - } + if (spamThresholdAmountEditorDialog) { + SpamThresholdAmountEditorDialog( + onDialogDismiss = { spamThresholdAmountEditorDialog = false }, + onEditAmount = { + eventPublisher(UiEvent.UpdateMinTransactionAmount(amountInSats = it)) + }, + ) + } + + Spacer(modifier = Modifier.height(8.dp)) - Spacer(modifier = Modifier.height(8.dp)) + var maxWalletBalanceShown by remember { mutableStateOf(false) } + val maxBalanceInSats = + numberFormat.format((state.maxWalletBalanceInBtc ?: "0.01").toSats().toLong()) + SettingsItem( + headlineText = stringResource(id = R.string.settings_wallet_max_wallet_balance), + supportText = "$maxBalanceInSats sats", + trailingContent = { + IconButton(onClick = { maxWalletBalanceShown = true }) { + Icon(imageVector = Icons.Outlined.Info, contentDescription = null) + } + }, + onClick = { maxWalletBalanceShown = true }, + ) - var maxWalletBalanceShown by remember { mutableStateOf(false) } - val maxBalanceInSats = numberFormat.format((state.maxWalletBalanceInBtc ?: "0.01").toSats().toLong()) - SettingsItem( - headlineText = stringResource(id = R.string.settings_wallet_max_wallet_balance), - supportText = "$maxBalanceInSats sats", - trailingContent = { - IconButton(onClick = { maxWalletBalanceShown = true }) { - Icon(imageVector = Icons.Outlined.Info, contentDescription = null) + if (maxWalletBalanceShown) { + MaxWalletBalanceDialog( + text = stringResource(id = R.string.settings_wallet_max_wallet_balance_hint), + onDialogDismiss = { maxWalletBalanceShown = false }, + ) + } } - }, - onClick = { maxWalletBalanceShown = true }, - ) + } - if (maxWalletBalanceShown) { - MaxWalletBalanceDialog( - text = stringResource(id = R.string.settings_wallet_max_wallet_balance_hint), - onDialogDismiss = { maxWalletBalanceShown = false }, - ) + false -> { + ExternalWalletSettings( + nwcWallet = state.wallet, + onExternalWalletDisconnect = { + eventPublisher(UiEvent.DisconnectWallet) + }, + ) + } } } + + Spacer(modifier = Modifier.height(8.dp)) + + NostrProfileLightingAddressSection( + lightningAddress = state.userLightningAddress, + onEditProfileClick = onEditProfileClick, + ) } }, ) } +@Composable +private fun ExternalWalletListItem(preferPrimalWallet: Boolean, onExternalWalletSwitchChanged: (Boolean) -> Unit) { + ListItem( + modifier = Modifier.clickable { + onExternalWalletSwitchChanged(!preferPrimalWallet) + }, + headlineContent = { + Text( + modifier = Modifier.padding(bottom = 4.dp), + text = stringResource(id = R.string.settings_wallet_use_primal_wallet), + style = AppTheme.typography.bodyLarge, + color = AppTheme.colorScheme.onPrimary, + ) + }, + supportingContent = { + Text( + modifier = Modifier.fillMaxWidth(), + text = stringResource(id = R.string.settings_wallet_use_primal_wallet_hint), + style = AppTheme.typography.bodySmall, + color = AppTheme.extraColorScheme.onSurfaceVariantAlt1, + ) + }, + trailingContent = { + PrimalSwitch( + checked = preferPrimalWallet, + onCheckedChange = onExternalWalletSwitchChanged, + ) + }, + ) +} + @Composable private fun SettingsItem( headlineText: String, @@ -297,6 +355,53 @@ private fun SpamThresholdAmountEditorDialog(onDialogDismiss: () -> Unit, onEditA ) } +@Composable +private fun NostrProfileLightingAddressSection(lightningAddress: String?, onEditProfileClick: () -> Unit) { + Column { + SettingsItem( + headlineText = stringResource(id = R.string.settings_wallet_ln_address), + supportText = lightningAddress, + trailingContent = { + Icon(imageVector = Icons.Default.ArrowForwardIos, contentDescription = null) + }, + onClick = onEditProfileClick, + ) + + Column( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp), + ) { + Text( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 2.dp) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = null, + onClick = onEditProfileClick, + ), + text = buildAnnotatedString { + append(stringResource(id = R.string.settings_wallet_nwc_profile_lightning_address_hint)) + append( + AnnotatedString( + text = " ${ + stringResource(id = R.string.settings_wallet_nwc_profile_lightning_address_hint_suffix) + }", + spanStyle = SpanStyle( + color = AppTheme.colorScheme.secondary, + fontStyle = AppTheme.typography.bodySmall.fontStyle, + ), + ), + ) + append(".") + }, + style = AppTheme.typography.bodySmall, + ) + } + } +} + class WalletUiStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( diff --git a/app/src/main/kotlin/net/primal/android/wallet/dashboard/WalletDashboardScreen.kt b/app/src/main/kotlin/net/primal/android/wallet/dashboard/WalletDashboardScreen.kt index 4427aa70..f5f1fb85 100644 --- a/app/src/main/kotlin/net/primal/android/wallet/dashboard/WalletDashboardScreen.kt +++ b/app/src/main/kotlin/net/primal/android/wallet/dashboard/WalletDashboardScreen.kt @@ -42,6 +42,7 @@ import kotlinx.coroutines.launch import net.primal.android.LocalPrimalTheme import net.primal.android.R import net.primal.android.core.compose.AppBarIcon +import net.primal.android.core.compose.NavigationBarFullHeightDp import net.primal.android.core.compose.PrimalTopAppBar import net.primal.android.core.compose.PrimalTopLevelDestination import net.primal.android.core.compose.SnackbarErrorHandler @@ -321,11 +322,10 @@ fun WalletDashboardScreen( }, footer = { if (shouldAddFooter) { + val systemNavigationBarDp = 48.dp val spacerHeight = with(density) { - (topBarHeight - topBarFooterHeight).toDp() + - dashboardLiteHeightDp + - 64.dp /* PrimalNavigationBar */ + - 48.dp /* SystemNavigationBar */ + (topBarHeight - topBarFooterHeight).toDp() + dashboardLiteHeightDp + + NavigationBarFullHeightDp + systemNavigationBarDp } Spacer(modifier = Modifier.height(spacerHeight)) } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e3b44825..2141fa01 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -243,6 +243,7 @@ Hide transactions below You can choose to hide small transactions to avoid spam in your transaction list Edit amount + Nostr lightning address Start in wallet Open the wallet when Primal starts Save