[#1414] Hide Balances

* [#1414] Hide Balances

- Closes #1414
- Reworked TopAppBar back navigation-related parameters across the app to enable us to inject a different action - hide balances instead of just the back navigation
- Tests updated to reflect the above changes
- A simple new button UI test was added, too
- Changelog update
This commit is contained in:
Honza Rychnovský 2024-07-03 15:29:49 +02:00 committed by GitHub
parent 42deed3391
commit bbf730d8f5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
57 changed files with 632 additions and 203 deletions

View File

@ -9,11 +9,12 @@ directly impact users rather than highlighting other key architectural updates.*
## [Unreleased] ## [Unreleased]
### Fixed
- The app navigation has been improved to always behave the same for system, gesture, or top app bar back navigation actions.
### Added ### Added
- Proper ZEC amount abbreviation has been added across the entire app as described by the design document - Proper ZEC amount abbreviation has been added across the entire app as described by the design document
- The new Hide Balances feature has been added to the Account, Send, and Balances screen.
### Fixed
- The app navigation has been improved to always behave the same for system, gesture, or top app bar back navigation actions
### Fixed ### Fixed
- The app authentication now correctly handles authentication success after a previous failed state - The app authentication now correctly handles authentication success after a previous failed state

View File

@ -1,18 +1,24 @@
package co.electriccoin.zcash.ui.design.component package co.electriccoin.zcash.ui.design.component
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.basicMarquee import androidx.compose.foundation.basicMarquee
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import cash.z.ecc.android.sdk.model.MonetarySeparators import cash.z.ecc.android.sdk.model.MonetarySeparators
import co.electriccoin.zcash.spackle.Twig import co.electriccoin.zcash.spackle.Twig
import co.electriccoin.zcash.ui.design.R
import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import java.util.Locale import java.util.Locale
@ -24,6 +30,20 @@ private fun StyledBalanceComposablePreview() {
Column { Column {
StyledBalance( StyledBalance(
balanceParts = ZecAmountTriple(main = "1,234.56789012"), balanceParts = ZecAmountTriple(main = "1,234.56789012"),
isHideBalances = false,
textStyles =
Pair(
ZcashTheme.extendedTypography.balanceWidgetStyles.first,
ZcashTheme.extendedTypography.balanceWidgetStyles.second
),
modifier = Modifier
)
Spacer(modifier = Modifier.height(24.dp))
StyledBalance(
balanceParts = ZecAmountTriple(main = "1,234.56789012"),
isHideBalances = true,
textStyles = textStyles =
Pair( Pair(
ZcashTheme.extendedTypography.balanceWidgetStyles.first, ZcashTheme.extendedTypography.balanceWidgetStyles.first,
@ -41,52 +61,67 @@ private fun StyledBalanceComposablePreview() {
* requirements. The function displays the balance within two parts. * requirements. The function displays the balance within two parts.
* *
* @param balanceParts [ZecAmountTriple] class that holds balance parts * @param balanceParts [ZecAmountTriple] class that holds balance parts
* @param isHideBalances Flag referring about the balance being hidden or not
* @param hiddenBalancePlaceholder String holding the placeholder for the hidden balance
* @param textStyles Styles for the first and second part of the balance * @param textStyles Styles for the first and second part of the balance
* @param textColor Optional color to modify the default font color from [textStyles] * @param textColor Optional color to modify the default font color from [textStyles]
* @param modifier Modifier to modify the Text UI element as needed * @param modifier Modifier to modify the Text UI element as needed
*/ */
@OptIn(ExperimentalFoundationApi::class) @OptIn(ExperimentalFoundationApi::class)
@Suppress("LongParameterList")
@Composable @Composable
fun StyledBalance( fun StyledBalance(
balanceParts: ZecAmountTriple, balanceParts: ZecAmountTriple,
textStyles: Pair<TextStyle, TextStyle>, textStyles: Pair<TextStyle, TextStyle>,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
isHideBalances: Boolean = false,
hiddenBalancePlaceholder: String = stringResource(id = R.string.hide_balance_placeholder),
textColor: Color? = null, textColor: Color? = null,
) { ) {
val balanceSplit = splitBalance(balanceParts)
val content = val content =
buildAnnotatedString { if (isHideBalances) {
withStyle( buildAnnotatedString {
style = textStyles.first.toSpanStyle() withStyle(
) { style = textStyles.first.toSpanStyle()
append(balanceSplit.first) ) {
append(hiddenBalancePlaceholder)
}
} }
withStyle( } else {
style = textStyles.second.toSpanStyle() val balanceSplit = splitBalance(balanceParts)
) {
append(balanceSplit.second) buildAnnotatedString {
withStyle(
style = textStyles.first.toSpanStyle()
) {
append(balanceSplit.first)
}
withStyle(
style = textStyles.second.toSpanStyle()
) {
append(balanceSplit.second)
}
} }
} }
val resultModifier =
Modifier
.basicMarquee()
.animateContentSize()
.then(modifier)
if (textColor != null) { if (textColor != null) {
Text( Text(
text = content, text = content,
color = textColor, color = textColor,
maxLines = 1, maxLines = 1,
modifier = modifier = resultModifier
Modifier
.basicMarquee()
.then(modifier)
) )
} else { } else {
Text( Text(
text = content, text = content,
maxLines = 1, maxLines = 1,
modifier = modifier = resultModifier
Modifier
.basicMarquee()
.then(modifier)
) )
} }
} }

View File

@ -3,7 +3,6 @@
package co.electriccoin.zcash.ui.design.component package co.electriccoin.zcash.ui.design.component
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.RowScope
@ -34,6 +33,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.testTag import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
@ -51,7 +51,16 @@ import co.electriccoin.zcash.ui.design.theme.internal.TopAppBarColors
private fun TopAppBarTextComposablePreview() { private fun TopAppBarTextComposablePreview() {
ZcashTheme(forceDarkMode = false) { ZcashTheme(forceDarkMode = false) {
BlankSurface { BlankSurface {
SmallTopAppBar(titleText = "Screen A", backText = "Back") SmallTopAppBar(
navigationAction = {
TopAppBarBackNavigation(
onBack = {},
backText = "BACK",
backContentDescriptionText = "BACK"
)
},
titleText = "Screen A"
)
} }
} }
} }
@ -61,7 +70,16 @@ private fun TopAppBarTextComposablePreview() {
private fun TopAppBarTextDarkComposablePreview() { private fun TopAppBarTextDarkComposablePreview() {
ZcashTheme(forceDarkMode = true) { ZcashTheme(forceDarkMode = true) {
BlankSurface { BlankSurface {
SmallTopAppBar(titleText = "Screen A", backText = "Back") SmallTopAppBar(
navigationAction = {
TopAppBarBackNavigation(
onBack = {},
backText = "BACK",
backContentDescriptionText = "BACK"
)
},
titleText = "Screen A"
)
} }
} }
} }
@ -72,8 +90,14 @@ private fun TopAppBarTextRestoringComposablePreview() {
ZcashTheme(forceDarkMode = false) { ZcashTheme(forceDarkMode = false) {
BlankSurface { BlankSurface {
SmallTopAppBar( SmallTopAppBar(
navigationAction = {
TopAppBarBackNavigation(
onBack = {},
backText = "BACK",
backContentDescriptionText = "BACK"
)
},
titleText = "Screen A", titleText = "Screen A",
backText = "Back",
subTitle = "[RESTORING YOUR WALLET…]" subTitle = "[RESTORING YOUR WALLET…]"
) )
} }
@ -86,9 +110,15 @@ private fun TopAppBarTextRestoringLongComposablePreview() {
ZcashTheme(forceDarkMode = false) { ZcashTheme(forceDarkMode = false) {
BlankSurface { BlankSurface {
SmallTopAppBar( SmallTopAppBar(
navigationAction = {
TopAppBarBackNavigation(
onBack = {},
backText = "BACK",
backContentDescriptionText = "BACK"
)
},
subTitle = "[RESTORING YOUR WALLET LONG TEXT…]",
titleText = "Screen A", titleText = "Screen A",
backText = "Back",
subTitle = "[RESTORING YOUR WALLET LONG TEXT…]"
) )
} }
} }
@ -99,7 +129,16 @@ private fun TopAppBarTextRestoringLongComposablePreview() {
private fun TopAppBarLogoComposablePreview() { private fun TopAppBarLogoComposablePreview() {
ZcashTheme(forceDarkMode = false) { ZcashTheme(forceDarkMode = false) {
BlankSurface { BlankSurface {
SmallTopAppBar(showTitleLogo = true, backText = "Back") SmallTopAppBar(
navigationAction = {
TopAppBarBackNavigation(
onBack = {},
backText = "BACK",
backContentDescriptionText = "BACK"
)
},
showTitleLogo = true
)
} }
} }
} }
@ -110,8 +149,14 @@ private fun TopAppBarLogoRestoringComposablePreview() {
ZcashTheme(forceDarkMode = false) { ZcashTheme(forceDarkMode = false) {
BlankSurface { BlankSurface {
SmallTopAppBar( SmallTopAppBar(
navigationAction = {
TopAppBarBackNavigation(
onBack = {},
backText = "BACK",
backContentDescriptionText = "BACK"
)
},
showTitleLogo = true, showTitleLogo = true,
backText = "Back",
subTitle = "[RESTORING YOUR WALLET…]" subTitle = "[RESTORING YOUR WALLET…]"
) )
} }
@ -124,8 +169,14 @@ private fun TopAppBarLogoRestoringDarkComposablePreview() {
ZcashTheme(forceDarkMode = true) { ZcashTheme(forceDarkMode = true) {
BlankSurface { BlankSurface {
SmallTopAppBar( SmallTopAppBar(
navigationAction = {
TopAppBarBackNavigation(
onBack = {},
backText = "BACK",
backContentDescriptionText = "BACK"
)
},
showTitleLogo = true, showTitleLogo = true,
backText = "Back",
subTitle = "[RESTORING YOUR WALLET…]" subTitle = "[RESTORING YOUR WALLET…]"
) )
} }
@ -157,7 +208,13 @@ private fun TopAppBarOneVisibleActionMenuComposablePreview() {
BlankSurface { BlankSurface {
SmallTopAppBar( SmallTopAppBar(
titleText = "Screen C", titleText = "Screen C",
backText = "Back", navigationAction = {
TopAppBarBackNavigation(
onBack = {},
backText = "BACK",
backContentDescriptionText = "BACK"
)
},
regularActions = { regularActions = {
TopBarOneVisibleActionMenuExample( TopBarOneVisibleActionMenuExample(
actionCallback = {} actionCallback = {}
@ -175,12 +232,18 @@ private fun TopAppBarHamburgerMenuComposablePreview() {
BlankSurface { BlankSurface {
SmallTopAppBar( SmallTopAppBar(
titleText = "Screen D", titleText = "Screen D",
backText = "Back",
hamburgerMenuActions = { hamburgerMenuActions = {
TopBarHamburgerMenuExample( TopBarHamburgerMenuExample(
actionCallback = {} actionCallback = {}
) )
} },
navigationAction = {
TopAppBarBackNavigation(
onBack = {},
backText = "BACK",
backContentDescriptionText = "BACK"
)
},
) )
} }
} }
@ -285,15 +348,61 @@ private fun TopBarOneVisibleActionMenuExample(
) )
} }
@Composable
fun TopAppBarBackNavigation(
backContentDescriptionText: String? = null,
backIconVector: ImageVector = Icons.AutoMirrored.Filled.ArrowBack,
backText: String? = null,
onBack: () -> Unit
) {
Row(
modifier =
Modifier
.wrapContentSize()
.clip(RoundedCornerShape(ZcashTheme.dimens.regularRippleEffectCorner))
.clickable { onBack() }
.padding(all = ZcashTheme.dimens.spacingMid),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = backIconVector,
contentDescription = backContentDescriptionText,
)
backText?.let {
Spacer(modifier = Modifier.size(size = ZcashTheme.dimens.spacingSmall))
Text(text = backText)
}
}
}
@Composable
fun TopAppBarHideBalancesNavigation(
iconVector: ImageVector,
onClick: () -> Unit,
modifier: Modifier = Modifier,
contentDescription: String? = null,
) {
IconButton(
onClick = onClick,
modifier = modifier
) {
Icon(
imageVector = iconVector,
contentDescription = contentDescription,
modifier = Modifier.size(24.dp)
)
}
}
@Composable @Composable
@Suppress("LongParameterList") @Suppress("LongParameterList")
fun GridBgSmallTopAppBar( fun GridBgSmallTopAppBar(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
backContentDescriptionText: String? = null,
backText: String? = null,
colors: TopAppBarColors = ZcashTheme.colors.topAppBarColors, colors: TopAppBarColors = ZcashTheme.colors.topAppBarColors,
hamburgerMenuActions: (@Composable RowScope.() -> Unit)? = null, hamburgerMenuActions: (@Composable RowScope.() -> Unit)? = null,
onBack: (() -> Unit)? = null, navigationAction: @Composable () -> Unit = {},
regularActions: (@Composable RowScope.() -> Unit)? = null, regularActions: (@Composable RowScope.() -> Unit)? = null,
subTitle: String? = null, subTitle: String? = null,
showTitleLogo: Boolean = false, showTitleLogo: Boolean = false,
@ -309,11 +418,9 @@ fun GridBgSmallTopAppBar(
gridLineWidth = ZcashTheme.dimens.gridLineWidth gridLineWidth = ZcashTheme.dimens.gridLineWidth
) )
), ),
backContentDescriptionText = backContentDescriptionText,
backText = backText,
colors = colors.copyColors(containerColor = Color.Transparent), colors = colors.copyColors(containerColor = Color.Transparent),
hamburgerMenuActions = hamburgerMenuActions, hamburgerMenuActions = hamburgerMenuActions,
onBack = onBack, navigationAction = navigationAction,
regularActions = regularActions, regularActions = regularActions,
subTitle = subTitle, subTitle = subTitle,
showTitleLogo = showTitleLogo, showTitleLogo = showTitleLogo,
@ -322,15 +429,13 @@ fun GridBgSmallTopAppBar(
} }
@Composable @Composable
@Suppress("LongParameterList", "LongMethod") @Suppress("LongParameterList")
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
fun SmallTopAppBar( fun SmallTopAppBar(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
backContentDescriptionText: String? = null,
backText: String? = null,
colors: TopAppBarColors = ZcashTheme.colors.topAppBarColors, colors: TopAppBarColors = ZcashTheme.colors.topAppBarColors,
hamburgerMenuActions: (@Composable RowScope.() -> Unit)? = null, hamburgerMenuActions: (@Composable RowScope.() -> Unit)? = null,
onBack: (() -> Unit)? = null, navigationAction: @Composable () -> Unit = {},
regularActions: (@Composable RowScope.() -> Unit)? = null, regularActions: (@Composable RowScope.() -> Unit)? = null,
subTitle: String? = null, subTitle: String? = null,
showTitleLogo: Boolean = false, showTitleLogo: Boolean = false,
@ -377,28 +482,7 @@ fun SmallTopAppBar(
} }
}, },
navigationIcon = { navigationIcon = {
backText?.let { navigationAction()
Box(
modifier =
Modifier
.wrapContentSize()
.clip(RoundedCornerShape(ZcashTheme.dimens.regularRippleEffectCorner))
.clickable { onBack?.run { onBack() } }
) {
Row(
modifier = Modifier.padding(all = ZcashTheme.dimens.spacingDefault),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = backContentDescriptionText,
tint = colors.navigationColor,
)
Spacer(modifier = Modifier.size(size = ZcashTheme.dimens.spacingSmall))
Text(text = backText.uppercase())
}
}
}
}, },
actions = { actions = {
regularActions?.invoke(this) regularActions?.invoke(this)

View File

@ -1,3 +1,4 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="amount_with_fiat_currency_symbol" formatted="true"><xliff:g id="fiat_currency_symbol" example="$">%1$s</xliff:g><xliff:g id="amount" example="123">%2$s</xliff:g></string> <string name="amount_with_fiat_currency_symbol" formatted="true"><xliff:g id="fiat_currency_symbol" example="$">%1$s</xliff:g><xliff:g id="amount" example="123">%2$s</xliff:g></string>
<string name="hide_balance_placeholder">-----</string>
</resources> </resources>

View File

@ -26,7 +26,7 @@ class AboutViewTest {
assertEquals(0, testSetup.getOnBackCount()) assertEquals(0, testSetup.getOnBackCount())
composeTestRule.onNodeWithText(getStringResource(R.string.about_back).uppercase()).also { composeTestRule.onNodeWithText(getStringResource(R.string.back_navigation).uppercase()).also {
it.assertExists() it.assertExists()
} }
@ -61,7 +61,9 @@ class AboutViewTest {
assertEquals(0, testSetup.getOnBackCount()) assertEquals(0, testSetup.getOnBackCount())
composeTestRule.onNodeWithContentDescription(getStringResource(R.string.about_back_content_description)).also { composeTestRule.onNodeWithContentDescription(
getStringResource(R.string.back_navigation_content_description)
).also {
it.performClick() it.performClick()
} }

View File

@ -24,6 +24,7 @@ class AccountTestSetup(
val initialTransactionState: TransactionUiState = TransactionHistoryUiStateFixture.new() val initialTransactionState: TransactionUiState = TransactionHistoryUiStateFixture.new()
private val onSettingsCount = AtomicInteger(0) private val onSettingsCount = AtomicInteger(0)
private val onHideBalancesCount = AtomicInteger(0)
private val onReceiveCount = AtomicInteger(0) private val onReceiveCount = AtomicInteger(0)
private val onSendCount = AtomicInteger(0) private val onSendCount = AtomicInteger(0)
private val onItemClickCount = AtomicInteger(0) private val onItemClickCount = AtomicInteger(0)
@ -44,6 +45,11 @@ class AccountTestSetup(
return onSettingsCount.get() return onSettingsCount.get()
} }
fun getOnHideBalancesCount(): Int {
composeTestRule.waitForIdle()
return onHideBalancesCount.get()
}
fun getOnReceiveCount(): Int { fun getOnReceiveCount(): Int {
composeTestRule.waitForIdle() composeTestRule.waitForIdle()
return onReceiveCount.get() return onReceiveCount.get()
@ -61,31 +67,35 @@ class AccountTestSetup(
@Composable @Composable
@Suppress("TestFunctionName") @Suppress("TestFunctionName")
fun DefaultContent() { fun DefaultContent(isHideBalances: Boolean) {
Account( Account(
balanceState = BalanceStateFixture.new(), balanceState = BalanceStateFixture.new(),
goSettings = { goSettings = {
onSettingsCount.incrementAndGet() onSettingsCount.incrementAndGet()
}, },
goBalances = {}, goBalances = {},
transactionsUiState = initialTransactionState, hideStatusDialog = {},
onHideBalances = {
onHideBalancesCount.incrementAndGet()
},
isHideBalances = isHideBalances,
onTransactionItemAction = { onTransactionItemAction = {
onItemClickCount.incrementAndGet() onItemClickCount.incrementAndGet()
}, },
hideStatusDialog = {},
showStatusDialog = null,
onStatusClick = {}, onStatusClick = {},
showStatusDialog = null,
snackbarHostState = SnackbarHostState(), snackbarHostState = SnackbarHostState(),
topAppBarSubTitleState = TopAppBarSubTitleState.None, topAppBarSubTitleState = TopAppBarSubTitleState.None,
transactionsUiState = initialTransactionState,
walletRestoringState = WalletRestoringState.NONE, walletRestoringState = WalletRestoringState.NONE,
walletSnapshot = WalletSnapshotFixture.new(), walletSnapshot = WalletSnapshotFixture.new(),
) )
} }
fun setDefaultContent() { fun setDefaultContent(isHideBalances: Boolean = false) {
composeTestRule.setContent { composeTestRule.setContent {
ZcashTheme { ZcashTheme {
DefaultContent() DefaultContent(isHideBalances)
} }
} }
} }

View File

@ -29,11 +29,12 @@ class HistoryTestSetup(
composeTestRule.setContent { composeTestRule.setContent {
ZcashTheme { ZcashTheme {
HistoryContainer( HistoryContainer(
transactionState = initialHistoryUiState, isHideBalances = false,
onStatusClick = {}, onStatusClick = {},
onTransactionItemAction = { onTransactionItemAction = {
onItemIdClickCount.incrementAndGet() onItemIdClickCount.incrementAndGet()
}, },
transactionState = initialHistoryUiState,
walletRestoringState = WalletRestoringState.NONE, walletRestoringState = WalletRestoringState.NONE,
walletSnapshot = WalletSnapshotFixture.new() walletSnapshot = WalletSnapshotFixture.new()
) )

View File

@ -40,7 +40,7 @@ class AccountViewIntegrationTest : UiTestPrerequisites() {
val testSetup = newTestSetup(walletSnapshot) val testSetup = newTestSetup(walletSnapshot)
restorationTester.setContent { restorationTester.setContent {
testSetup.DefaultContent() testSetup.DefaultContent(isHideBalances = false)
} }
assertEquals(WalletSnapshotFixture.SAPLING_BALANCE, testSetup.getWalletSnapshot().saplingBalance) assertEquals(WalletSnapshotFixture.SAPLING_BALANCE, testSetup.getWalletSnapshot().saplingBalance)

View File

@ -10,6 +10,7 @@ import co.electriccoin.zcash.ui.design.component.CommonTag
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
import co.electriccoin.zcash.ui.screen.account.AccountTag import co.electriccoin.zcash.ui.screen.account.AccountTag
import co.electriccoin.zcash.ui.screen.account.AccountTestSetup import co.electriccoin.zcash.ui.screen.account.AccountTestSetup
import co.electriccoin.zcash.ui.screen.send.clickHideBalances
import co.electriccoin.zcash.ui.screen.send.clickSettingsTopAppBarMenu import co.electriccoin.zcash.ui.screen.send.clickSettingsTopAppBarMenu
import org.junit.Assert import org.junit.Assert
import org.junit.Rule import org.junit.Rule
@ -49,11 +50,25 @@ class AccountViewTest : UiTestPrerequisites() {
Assert.assertEquals(1, testSetup.getOnSettingsCount()) Assert.assertEquals(1, testSetup.getOnSettingsCount())
} }
private fun newTestSetup(walletSnapshot: WalletSnapshot = WalletSnapshotFixture.new()) = @Test
AccountTestSetup( @MediumTest
composeTestRule, fun hide_balances_btn_click_test() {
walletSnapshot = walletSnapshot, val testSetup = newTestSetup()
).apply {
setDefaultContent() Assert.assertEquals(0, testSetup.getOnHideBalancesCount())
}
composeTestRule.clickHideBalances()
Assert.assertEquals(1, testSetup.getOnHideBalancesCount())
}
private fun newTestSetup(
walletSnapshot: WalletSnapshot = WalletSnapshotFixture.new(),
isHideBalances: Boolean = false
) = AccountTestSetup(
composeTestRule,
walletSnapshot = walletSnapshot,
).apply {
setDefaultContent(isHideBalances)
}
} }

View File

@ -38,6 +38,8 @@ class BalancesTestSetup(
onSettingsCount.incrementAndGet() onSettingsCount.incrementAndGet()
}, },
hideStatusDialog = {}, hideStatusDialog = {},
isHideBalances = false,
onHideBalances = {},
showStatusDialog = null, showStatusDialog = null,
onStatusClick = {}, onStatusClick = {},
snackbarHostState = SnackbarHostState(), snackbarHostState = SnackbarHostState(),

View File

@ -113,7 +113,7 @@ class ExportPrivateDataViewTest : UiTestPrerequisites() {
} }
private fun ComposeContentTestRule.clickBack() { private fun ComposeContentTestRule.clickBack() {
onNodeWithContentDescription(getStringResource(R.string.support_back_content_description)).also { onNodeWithContentDescription(getStringResource(R.string.back_navigation_content_description)).also {
it.performClick() it.performClick()
} }
} }

View File

@ -311,7 +311,7 @@ class RestoreViewTest : UiTestPrerequisites() {
assertEquals(0, testSetup.getOnBackCount()) assertEquals(0, testSetup.getOnBackCount())
composeTestRule.onNodeWithContentDescription( composeTestRule.onNodeWithContentDescription(
getStringResource(R.string.restore_back_content_description) getStringResource(R.string.back_navigation_content_description)
).also { ).also {
it.performClick() it.performClick()
} }
@ -331,7 +331,7 @@ class RestoreViewTest : UiTestPrerequisites() {
assertEquals(0, testSetup.getOnBackCount()) assertEquals(0, testSetup.getOnBackCount())
composeTestRule.onNodeWithContentDescription( composeTestRule.onNodeWithContentDescription(
getStringResource(R.string.restore_back_content_description) getStringResource(R.string.back_navigation_content_description)
).also { ).also {
it.performClick() it.performClick()
} }

View File

@ -98,7 +98,7 @@ class SecurityWarningViewTest : UiTestPrerequisites() {
} }
private fun ComposeContentTestRule.clickBack() { private fun ComposeContentTestRule.clickBack() {
onNodeWithContentDescription(getStringResource(R.string.support_back_content_description)).also { onNodeWithContentDescription(getStringResource(R.string.back_navigation_content_description)).also {
it.performClick() it.performClick()
} }
} }

View File

@ -39,7 +39,7 @@ class SeedRecoveryRecoveryViewTest : UiTestPrerequisites() {
assertEquals(0, testSetup.getOnCompleteCount()) assertEquals(0, testSetup.getOnCompleteCount())
assertEquals(0, testSetup.getOnBackCount()) assertEquals(0, testSetup.getOnBackCount())
composeTestRule.onNodeWithContentDescription(getStringResource(R.string.seed_recovery_back_content_description)) composeTestRule.onNodeWithContentDescription(getStringResource(R.string.back_navigation_content_description))
.also { .also {
it.assertExists() it.assertExists()
} }
@ -86,7 +86,7 @@ class SeedRecoveryRecoveryViewTest : UiTestPrerequisites() {
assertEquals(0, testSetup.getOnBackCount()) assertEquals(0, testSetup.getOnBackCount())
composeTestRule.onNodeWithContentDescription(getStringResource(R.string.seed_recovery_back_content_description)) composeTestRule.onNodeWithContentDescription(getStringResource(R.string.back_navigation_content_description))
.also { .also {
it.performClick() it.performClick()
} }

View File

@ -24,6 +24,12 @@ internal fun ComposeContentTestRule.clickSettingsTopAppBarMenu() {
} }
} }
internal fun ComposeContentTestRule.clickHideBalances() {
onNodeWithContentDescription(getStringResource(R.string.hide_balances_content_description)).also {
it.performClick()
}
}
internal fun ComposeContentTestRule.clickScanner() { internal fun ComposeContentTestRule.clickScanner() {
onNodeWithContentDescription(getStringResource(R.string.send_scan_content_description)).also { onNodeWithContentDescription(getStringResource(R.string.send_scan_content_description)).also {
it.performClick() it.performClick()

View File

@ -114,6 +114,8 @@ class SendViewTestSetup(
// TODO [#1194]: Cover Current balances UI widget with tests // TODO [#1194]: Cover Current balances UI widget with tests
// TODO [#1194]: https://github.com/Electric-Coin-Company/zashi-android/issues/1194 // TODO [#1194]: https://github.com/Electric-Coin-Company/zashi-android/issues/1194
}, },
isHideBalances = false,
onHideBalances = {},
hasCameraFeature = hasCameraFeature, hasCameraFeature = hasCameraFeature,
recipientAddressState = RecipientAddressState("", AddressType.Invalid()), recipientAddressState = RecipientAddressState("", AddressType.Invalid()),
onRecipientAddressChange = { onRecipientAddressChange = {

View File

@ -75,6 +75,8 @@ class SendViewIntegrationTest {
goBalances = {}, goBalances = {},
goSettings = {}, goSettings = {},
goSendConfirmation = {}, goSendConfirmation = {},
isHideBalances = false,
onHideBalances = {},
hasCameraFeature = true, hasCameraFeature = true,
monetarySeparators = monetarySeparators, monetarySeparators = monetarySeparators,
topAppBarSubTitleState = TopAppBarSubTitleState.None, topAppBarSubTitleState = TopAppBarSubTitleState.None,

View File

@ -31,7 +31,7 @@ class SettingsViewTest : UiTestPrerequisites() {
assertEquals(0, testSetup.getBackCount()) assertEquals(0, testSetup.getBackCount())
composeTestRule.onNodeWithContentDescription( composeTestRule.onNodeWithContentDescription(
getStringResource(R.string.settings_back_content_description) getStringResource(R.string.back_navigation_content_description)
).also { ).also {
it.performClick() it.performClick()
} }

View File

@ -116,7 +116,7 @@ class SupportViewTest : UiTestPrerequisites() {
} }
private fun ComposeContentTestRule.clickBack() { private fun ComposeContentTestRule.clickBack() {
onNodeWithContentDescription(getStringResource(R.string.support_back_content_description)).also { onNodeWithContentDescription(getStringResource(R.string.back_navigation_content_description)).also {
it.performClick() it.performClick()
} }
} }

View File

@ -1,6 +1,5 @@
package co.electriccoin.zcash.ui.common.compose package co.electriccoin.zcash.ui.common.compose
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
@ -46,6 +45,7 @@ private fun BalanceWidgetPreview() {
totalBalance = Zatoshi(1234567891234567L), totalBalance = Zatoshi(1234567891234567L),
spendableBalance = Zatoshi(1234567891234567L) spendableBalance = Zatoshi(1234567891234567L)
), ),
isHideBalances = false,
isReferenceToBalances = true, isReferenceToBalances = true,
onReferenceClick = {}, onReferenceClick = {},
modifier = Modifier modifier = Modifier
@ -65,6 +65,26 @@ private fun BalanceWidgetNotAvailableYetPreview() {
@Suppress("MagicNumber") @Suppress("MagicNumber")
BalanceWidget( BalanceWidget(
balanceState = BalanceState.Loading(Zatoshi(0L)), balanceState = BalanceState.Loading(Zatoshi(0L)),
isHideBalances = false,
isReferenceToBalances = true,
onReferenceClick = {},
modifier = Modifier
)
}
}
}
@Preview
@Composable
private fun BalanceWidgetHiddenAmountPreview() {
ZcashTheme(forceDarkMode = false) {
BlankSurface(
modifier = Modifier.fillMaxWidth()
) {
@Suppress("MagicNumber")
BalanceWidget(
balanceState = BalanceState.Loading(Zatoshi(0L)),
isHideBalances = true,
isReferenceToBalances = true, isReferenceToBalances = true,
onReferenceClick = {}, onReferenceClick = {},
modifier = Modifier modifier = Modifier
@ -86,6 +106,7 @@ sealed class BalanceState(open val totalBalance: Zatoshi) {
fun BalanceWidget( fun BalanceWidget(
balanceState: BalanceState, balanceState: BalanceState,
isReferenceToBalances: Boolean, isReferenceToBalances: Boolean,
isHideBalances: Boolean,
onReferenceClick: () -> Unit, onReferenceClick: () -> Unit,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
@ -96,12 +117,12 @@ fun BalanceWidget(
.then(modifier), .then(modifier),
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
BalanceWidgetBigLineOnly(parts = balanceState.totalBalance.toZecStringFull().asZecAmountTriple()) BalanceWidgetBigLineOnly(
isHideBalances = isHideBalances,
parts = balanceState.totalBalance.toZecStringFull().asZecAmountTriple()
)
Row( Row(verticalAlignment = Alignment.CenterVertically) {
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.animateContentSize()
) {
if (isReferenceToBalances) { if (isReferenceToBalances) {
Reference( Reference(
text = stringResource(id = co.electriccoin.zcash.ui.R.string.balance_widget_available), text = stringResource(id = co.electriccoin.zcash.ui.R.string.balance_widget_available),
@ -135,6 +156,7 @@ fun BalanceWidget(
is BalanceState.Available -> { is BalanceState.Available -> {
StyledBalance( StyledBalance(
balanceParts = balanceState.spendableBalance.toZecStringFull().asZecAmountTriple(), balanceParts = balanceState.spendableBalance.toZecStringFull().asZecAmountTriple(),
isHideBalances = isHideBalances,
textStyles = textStyles =
Pair( Pair(
ZcashTheme.extendedTypography.balanceWidgetStyles.third, ZcashTheme.extendedTypography.balanceWidgetStyles.third,
@ -157,6 +179,7 @@ fun BalanceWidget(
@Composable @Composable
fun BalanceWidgetBigLineOnly( fun BalanceWidgetBigLineOnly(
parts: ZecAmountTriple, parts: ZecAmountTriple,
isHideBalances: Boolean,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
Row( Row(
@ -165,6 +188,7 @@ fun BalanceWidgetBigLineOnly(
) { ) {
StyledBalance( StyledBalance(
balanceParts = parts, balanceParts = parts,
isHideBalances = isHideBalances,
textStyles = textStyles =
Pair( Pair(
ZcashTheme.extendedTypography.balanceWidgetStyles.first, ZcashTheme.extendedTypography.balanceWidgetStyles.first,

View File

@ -6,4 +6,5 @@ package co.electriccoin.zcash.ui.common.test
object CommonTag { object CommonTag {
const val WALLET_BIRTHDAY = "wallet_birthday" const val WALLET_BIRTHDAY = "wallet_birthday"
const val SETTINGS_TOP_BAR_BUTTON = "settings_top_bar_button" const val SETTINGS_TOP_BAR_BUTTON = "settings_top_bar_button"
const val HIDE_BALANCES_TOP_BAR_BUTTON = "hide_balances_top_bar_button"
} }

View File

@ -13,6 +13,8 @@ import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.WhileSubscribed import kotlinx.coroutines.flow.WhileSubscribed
import kotlinx.coroutines.flow.emitAll import kotlinx.coroutines.flow.emitAll
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -40,6 +42,29 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
setBooleanPreference(StandardPreferenceKeys.IS_RESTORING_INITIAL_WARNING_SEEN, true) setBooleanPreference(StandardPreferenceKeys.IS_RESTORING_INITIAL_WARNING_SEEN, true)
} }
/**
* A flow of the wallet balances visibility.
*/
val isHideBalances: StateFlow<Boolean?> = booleanStateFlow(StandardPreferenceKeys.IS_HIDE_BALANCES)
fun showOrHideBalances() {
viewModelScope.launch {
setBooleanPreference(StandardPreferenceKeys.IS_HIDE_BALANCES, isHideBalances.filterNotNull().first().not())
}
}
val configurationFlow: StateFlow<Configuration?> =
AndroidConfigurationFactory.getInstance(application).getConfigurationFlow()
.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT.inWholeMilliseconds),
null
)
//
// PRIVATE HELPERS
//
private fun booleanStateFlow(default: BooleanPreferenceDefault): StateFlow<Boolean?> = private fun booleanStateFlow(default: BooleanPreferenceDefault): StateFlow<Boolean?> =
flow<Boolean?> { flow<Boolean?> {
val preferenceProvider = StandardPreferenceSingleton.getInstance(getApplication()) val preferenceProvider = StandardPreferenceSingleton.getInstance(getApplication())
@ -50,14 +75,6 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
null null
) )
val configurationFlow: StateFlow<Configuration?> =
AndroidConfigurationFactory.getInstance(application).getConfigurationFlow()
.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT.inWholeMilliseconds),
null
)
private fun setBooleanPreference( private fun setBooleanPreference(
default: BooleanPreferenceDefault, default: BooleanPreferenceDefault,
newState: Boolean newState: Boolean

View File

@ -32,8 +32,6 @@ object StandardPreferenceKeys {
val IS_KEEP_SCREEN_ON_DURING_SYNC = BooleanPreferenceDefault(PreferenceKey("is_keep_screen_on_during_sync"), true) val IS_KEEP_SCREEN_ON_DURING_SYNC = BooleanPreferenceDefault(PreferenceKey("is_keep_screen_on_during_sync"), true)
val IS_DETAILED_SYNC_STATUS = BooleanPreferenceDefault(PreferenceKey("is_detailed_sync_status"), false)
val IS_RESTORING_INITIAL_WARNING_SEEN = val IS_RESTORING_INITIAL_WARNING_SEEN =
BooleanPreferenceDefault(PreferenceKey("IS_RESTORING_INITIAL_WARNING_SEEN"), false) BooleanPreferenceDefault(PreferenceKey("IS_RESTORING_INITIAL_WARNING_SEEN"), false)
@ -70,4 +68,9 @@ object StandardPreferenceKeys {
PreferenceKey("IS_SEND_FUNDS_AUTHENTICATION"), PreferenceKey("IS_SEND_FUNDS_AUTHENTICATION"),
true true
) )
val IS_HIDE_BALANCES =
BooleanPreferenceDefault(
PreferenceKey("IS_HIDE_BALANCES"),
false
)
} }

View File

@ -44,6 +44,7 @@ import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
import co.electriccoin.zcash.ui.common.model.VersionInfo import co.electriccoin.zcash.ui.common.model.VersionInfo
import co.electriccoin.zcash.ui.design.component.BlankBgScaffold import co.electriccoin.zcash.ui.design.component.BlankBgScaffold
import co.electriccoin.zcash.ui.design.component.SmallTopAppBar import co.electriccoin.zcash.ui.design.component.SmallTopAppBar
import co.electriccoin.zcash.ui.design.component.TopAppBarBackNavigation
import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.ConfigInfoFixture import co.electriccoin.zcash.ui.fixture.ConfigInfoFixture
import co.electriccoin.zcash.ui.fixture.VersionInfoFixture import co.electriccoin.zcash.ui.fixture.VersionInfoFixture
@ -119,9 +120,13 @@ private fun AboutTopAppBar(
TopAppBarSubTitleState.None -> null TopAppBarSubTitleState.None -> null
}, },
titleText = stringResource(id = R.string.about_title).uppercase(), titleText = stringResource(id = R.string.about_title).uppercase(),
backText = stringResource(id = R.string.about_back).uppercase(), navigationAction = {
backContentDescriptionText = stringResource(R.string.about_back_content_description), TopAppBarBackNavigation(
onBack = onBack, backText = stringResource(id = R.string.back_navigation).uppercase(),
backContentDescriptionText = stringResource(R.string.back_navigation_content_description),
onBack = onBack
)
},
regularActions = { regularActions = {
if (versionInfo.isDebuggable && !versionInfo.isRunningUnderTestService) { if (versionInfo.isDebuggable && !versionInfo.isRunningUnderTestService) {
DebugMenu(versionInfo, configInfo) DebugMenu(versionInfo, configInfo)

View File

@ -20,6 +20,7 @@ import co.electriccoin.zcash.ui.common.compose.LocalActivity
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
import co.electriccoin.zcash.ui.common.model.WalletRestoringState import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.common.model.WalletSnapshot import co.electriccoin.zcash.ui.common.model.WalletSnapshot
import co.electriccoin.zcash.ui.common.viewmodel.HomeViewModel
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
import co.electriccoin.zcash.ui.design.component.CircularScreenProgressIndicator import co.electriccoin.zcash.ui.design.component.CircularScreenProgressIndicator
import co.electriccoin.zcash.ui.screen.account.model.TransactionUiState import co.electriccoin.zcash.ui.screen.account.model.TransactionUiState
@ -43,6 +44,8 @@ internal fun WrapAccount(
val transactionHistoryViewModel by activity.viewModels<TransactionHistoryViewModel>() val transactionHistoryViewModel by activity.viewModels<TransactionHistoryViewModel>()
val homeViewModel by activity.viewModels<HomeViewModel>()
val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value
val transactionsUiState = transactionHistoryViewModel.transactionUiState.collectAsStateWithLifecycle().value val transactionsUiState = transactionHistoryViewModel.transactionUiState.collectAsStateWithLifecycle().value
@ -59,10 +62,14 @@ internal fun WrapAccount(
val walletSnapshot = walletViewModel.walletSnapshot.collectAsStateWithLifecycle().value val walletSnapshot = walletViewModel.walletSnapshot.collectAsStateWithLifecycle().value
val isHideBalances = homeViewModel.isHideBalances.collectAsStateWithLifecycle().value ?: false
WrapAccount( WrapAccount(
balanceState = balanceState, balanceState = balanceState,
goBalances = goBalances, goBalances = goBalances,
goSettings = goSettings, goSettings = goSettings,
isHideBalances = isHideBalances,
onHideBalances = { homeViewModel.showOrHideBalances() },
synchronizer = synchronizer, synchronizer = synchronizer,
topAppBarSubTitleState = walletState, topAppBarSubTitleState = walletState,
transactionHistoryViewModel = transactionHistoryViewModel, transactionHistoryViewModel = transactionHistoryViewModel,
@ -82,9 +89,11 @@ internal fun WrapAccount(
balanceState: BalanceState, balanceState: BalanceState,
goBalances: () -> Unit, goBalances: () -> Unit,
goSettings: () -> Unit, goSettings: () -> Unit,
transactionsUiState: TransactionUiState, isHideBalances: Boolean,
synchronizer: Synchronizer?, synchronizer: Synchronizer?,
onHideBalances: () -> Unit,
topAppBarSubTitleState: TopAppBarSubTitleState, topAppBarSubTitleState: TopAppBarSubTitleState,
transactionsUiState: TransactionUiState,
transactionHistoryViewModel: TransactionHistoryViewModel, transactionHistoryViewModel: TransactionHistoryViewModel,
walletRestoringState: WalletRestoringState, walletRestoringState: WalletRestoringState,
walletSnapshot: WalletSnapshot? walletSnapshot: WalletSnapshot?
@ -107,9 +116,11 @@ internal fun WrapAccount(
} else { } else {
Account( Account(
balanceState = balanceState, balanceState = balanceState,
isHideBalances = isHideBalances,
transactionsUiState = transactionsUiState, transactionsUiState = transactionsUiState,
showStatusDialog = showStatusDialog.value, showStatusDialog = showStatusDialog.value,
hideStatusDialog = { showStatusDialog.value = null }, hideStatusDialog = { showStatusDialog.value = null },
onHideBalances = onHideBalances,
onStatusClick = { status -> onStatusClick = { status ->
when (status) { when (status) {
is StatusAction.Detailed -> showStatusDialog.value = status is StatusAction.Detailed -> showStatusDialog.value = status

View File

@ -12,9 +12,11 @@ import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.testTag import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import cash.z.ecc.android.sdk.model.Zatoshi import cash.z.ecc.android.sdk.model.Zatoshi
import co.electriccoin.zcash.ui.R import co.electriccoin.zcash.ui.R
@ -27,6 +29,7 @@ import co.electriccoin.zcash.ui.common.model.WalletSnapshot
import co.electriccoin.zcash.ui.common.test.CommonTag import co.electriccoin.zcash.ui.common.test.CommonTag
import co.electriccoin.zcash.ui.design.component.BlankBgScaffold import co.electriccoin.zcash.ui.design.component.BlankBgScaffold
import co.electriccoin.zcash.ui.design.component.SmallTopAppBar import co.electriccoin.zcash.ui.design.component.SmallTopAppBar
import co.electriccoin.zcash.ui.design.component.TopAppBarHideBalancesNavigation
import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.BalanceStateFixture import co.electriccoin.zcash.ui.fixture.BalanceStateFixture
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
@ -41,12 +44,14 @@ private fun HistoryLoadingComposablePreview() {
ZcashTheme(forceDarkMode = false) { ZcashTheme(forceDarkMode = false) {
Account( Account(
balanceState = BalanceStateFixture.new(), balanceState = BalanceStateFixture.new(),
isHideBalances = false,
goBalances = {}, goBalances = {},
goSettings = {}, goSettings = {},
hideStatusDialog = {}, hideStatusDialog = {},
showStatusDialog = null, onHideBalances = {},
onStatusClick = {}, onStatusClick = {},
onTransactionItemAction = {}, onTransactionItemAction = {},
showStatusDialog = null,
snackbarHostState = SnackbarHostState(), snackbarHostState = SnackbarHostState(),
topAppBarSubTitleState = TopAppBarSubTitleState.None, topAppBarSubTitleState = TopAppBarSubTitleState.None,
transactionsUiState = TransactionUiState.Loading, transactionsUiState = TransactionUiState.Loading,
@ -67,12 +72,14 @@ private fun HistoryListComposablePreview() {
Zatoshi(123_000_000L), Zatoshi(123_000_000L),
Zatoshi(123_000_000L) Zatoshi(123_000_000L)
), ),
isHideBalances = false,
goBalances = {}, goBalances = {},
goSettings = {}, goSettings = {},
hideStatusDialog = {}, hideStatusDialog = {},
showStatusDialog = null, onHideBalances = {},
onStatusClick = {}, onStatusClick = {},
onTransactionItemAction = {}, onTransactionItemAction = {},
showStatusDialog = null,
snackbarHostState = SnackbarHostState(), snackbarHostState = SnackbarHostState(),
topAppBarSubTitleState = TopAppBarSubTitleState.None, topAppBarSubTitleState = TopAppBarSubTitleState.None,
transactionsUiState = TransactionUiState.Done(transactions = TransactionsFixture.new()), transactionsUiState = TransactionUiState.Done(transactions = TransactionsFixture.new()),
@ -88,10 +95,12 @@ internal fun Account(
balanceState: BalanceState, balanceState: BalanceState,
goBalances: () -> Unit, goBalances: () -> Unit,
goSettings: () -> Unit, goSettings: () -> Unit,
isHideBalances: Boolean,
hideStatusDialog: () -> Unit, hideStatusDialog: () -> Unit,
showStatusDialog: StatusAction.Detailed?, onHideBalances: () -> Unit,
onStatusClick: (StatusAction) -> Unit, onStatusClick: (StatusAction) -> Unit,
onTransactionItemAction: (TrxItemAction) -> Unit, onTransactionItemAction: (TrxItemAction) -> Unit,
showStatusDialog: StatusAction.Detailed?,
snackbarHostState: SnackbarHostState, snackbarHostState: SnackbarHostState,
topAppBarSubTitleState: TopAppBarSubTitleState, topAppBarSubTitleState: TopAppBarSubTitleState,
transactionsUiState: TransactionUiState, transactionsUiState: TransactionUiState,
@ -101,6 +110,8 @@ internal fun Account(
BlankBgScaffold( BlankBgScaffold(
topBar = { topBar = {
AccountTopAppBar( AccountTopAppBar(
isHideBalances = isHideBalances,
onHideBalances = onHideBalances,
onSettings = goSettings, onSettings = goSettings,
subTitleState = topAppBarSubTitleState, subTitleState = topAppBarSubTitleState,
) )
@ -111,6 +122,7 @@ internal fun Account(
) { paddingValues -> ) { paddingValues ->
AccountMainContent( AccountMainContent(
balanceState = balanceState, balanceState = balanceState,
isHideBalances = isHideBalances,
goBalances = goBalances, goBalances = goBalances,
onStatusClick = onStatusClick, onStatusClick = onStatusClick,
onTransactionItemAction = onTransactionItemAction, onTransactionItemAction = onTransactionItemAction,
@ -137,6 +149,8 @@ internal fun Account(
@Composable @Composable
private fun AccountTopAppBar( private fun AccountTopAppBar(
isHideBalances: Boolean,
onHideBalances: () -> Unit,
onSettings: () -> Unit, onSettings: () -> Unit,
subTitleState: TopAppBarSubTitleState subTitleState: TopAppBarSubTitleState
) { ) {
@ -158,7 +172,22 @@ private fun AccountTopAppBar(
contentDescription = stringResource(id = R.string.settings_menu_content_description) contentDescription = stringResource(id = R.string.settings_menu_content_description)
) )
} }
} },
navigationAction = {
TopAppBarHideBalancesNavigation(
contentDescription = stringResource(id = R.string.hide_balances_content_description),
iconVector =
ImageVector.vectorResource(
if (isHideBalances) {
R.drawable.ic_hide_balances_on
} else {
R.drawable.ic_hide_balances_off
}
),
onClick = onHideBalances,
modifier = Modifier.testTag(CommonTag.HIDE_BALANCES_TOP_BAR_BUTTON)
)
},
) )
} }
@ -167,10 +196,11 @@ private fun AccountTopAppBar(
private fun AccountMainContent( private fun AccountMainContent(
balanceState: BalanceState, balanceState: BalanceState,
goBalances: () -> Unit, goBalances: () -> Unit,
isHideBalances: Boolean,
isWalletRestoringState: WalletRestoringState,
onTransactionItemAction: (TrxItemAction) -> Unit, onTransactionItemAction: (TrxItemAction) -> Unit,
onStatusClick: (StatusAction) -> Unit, onStatusClick: (StatusAction) -> Unit,
transactionState: TransactionUiState, transactionState: TransactionUiState,
isWalletRestoringState: WalletRestoringState,
walletSnapshot: WalletSnapshot, walletSnapshot: WalletSnapshot,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
@ -183,6 +213,7 @@ private fun AccountMainContent(
BalancesStatus( BalancesStatus(
balanceState = balanceState, balanceState = balanceState,
goBalances = goBalances, goBalances = goBalances,
isHideBalances = isHideBalances,
modifier = modifier =
Modifier Modifier
.padding(horizontal = ZcashTheme.dimens.screenHorizontalSpacingRegular) .padding(horizontal = ZcashTheme.dimens.screenHorizontalSpacingRegular)
@ -191,6 +222,7 @@ private fun AccountMainContent(
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge)) Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge))
HistoryContainer( HistoryContainer(
isHideBalances = isHideBalances,
onStatusClick = onStatusClick, onStatusClick = onStatusClick,
onTransactionItemAction = onTransactionItemAction, onTransactionItemAction = onTransactionItemAction,
transactionState = transactionState, transactionState = transactionState,
@ -204,6 +236,7 @@ private fun AccountMainContent(
private fun BalancesStatus( private fun BalancesStatus(
balanceState: BalanceState, balanceState: BalanceState,
goBalances: () -> Unit, goBalances: () -> Unit,
isHideBalances: Boolean,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
Column( Column(
@ -217,6 +250,7 @@ private fun BalancesStatus(
) { ) {
BalanceWidget( BalanceWidget(
balanceState = balanceState, balanceState = balanceState,
isHideBalances = isHideBalances,
isReferenceToBalances = true, isReferenceToBalances = true,
onReferenceClick = goBalances onReferenceClick = goBalances
) )

View File

@ -83,6 +83,7 @@ private fun ComposablePreview() {
HistoryContainer( HistoryContainer(
onTransactionItemAction = {}, onTransactionItemAction = {},
onStatusClick = {}, onStatusClick = {},
isHideBalances = false,
transactionState = TransactionUiState.Loading, transactionState = TransactionUiState.Loading,
walletRestoringState = WalletRestoringState.SYNCING, walletRestoringState = WalletRestoringState.SYNCING,
walletSnapshot = WalletSnapshotFixture.new() walletSnapshot = WalletSnapshotFixture.new()
@ -98,6 +99,7 @@ private fun ComposableHistoryListPreview() {
transactionState = TransactionUiState.Done(transactions = TransactionsFixture.new()), transactionState = TransactionUiState.Done(transactions = TransactionsFixture.new()),
onTransactionItemAction = {}, onTransactionItemAction = {},
onStatusClick = {}, onStatusClick = {},
isHideBalances = false,
walletRestoringState = WalletRestoringState.RESTORING, walletRestoringState = WalletRestoringState.RESTORING,
walletSnapshot = WalletSnapshotFixture.new() walletSnapshot = WalletSnapshotFixture.new()
) )
@ -116,6 +118,7 @@ private val dateFormat: DateFormat by lazy {
internal fun HistoryContainer( internal fun HistoryContainer(
onStatusClick: (StatusAction) -> Unit, onStatusClick: (StatusAction) -> Unit,
onTransactionItemAction: (TrxItemAction) -> Unit, onTransactionItemAction: (TrxItemAction) -> Unit,
isHideBalances: Boolean,
transactionState: TransactionUiState, transactionState: TransactionUiState,
walletRestoringState: WalletRestoringState, walletRestoringState: WalletRestoringState,
walletSnapshot: WalletSnapshot, walletSnapshot: WalletSnapshot,
@ -167,6 +170,7 @@ internal fun HistoryContainer(
is TransactionUiState.Prepared -> { is TransactionUiState.Prepared -> {
HistoryList( HistoryList(
transactions = transactionState.transactions, transactions = transactionState.transactions,
isHideBalances = isHideBalances,
onAction = onTransactionItemAction, onAction = onTransactionItemAction,
) )
} }
@ -211,6 +215,7 @@ private fun EmptyTransactionHistory() {
@Composable @Composable
private fun HistoryList( private fun HistoryList(
transactions: ImmutableList<TransactionUi>, transactions: ImmutableList<TransactionUi>,
isHideBalances: Boolean,
onAction: (TrxItemAction) -> Unit, onAction: (TrxItemAction) -> Unit,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
@ -220,6 +225,7 @@ private fun HistoryList(
items(transactions.size) { index -> items(transactions.size) { index ->
HistoryItem( HistoryItem(
transaction = transactions[index], transaction = transactions[index],
isHideBalances = isHideBalances,
onAction = onAction onAction = onAction
) )
@ -239,6 +245,7 @@ private fun ComposableHistoryListItemPreview() {
BlankSurface { BlankSurface {
HistoryItem( HistoryItem(
onAction = {}, onAction = {},
isHideBalances = false,
transaction = TransactionUiFixture.new() transaction = TransactionUiFixture.new()
) )
} }
@ -253,6 +260,7 @@ private fun ComposableHistoryListItemExpandedPreview() {
Column { Column {
HistoryItem( HistoryItem(
onAction = {}, onAction = {},
isHideBalances = false,
transaction = transaction =
TransactionUiFixture.new( TransactionUiFixture.new(
overview = TransactionOverviewFixture.new().copy(isSentTransaction = true), overview = TransactionOverviewFixture.new().copy(isSentTransaction = true),
@ -261,6 +269,7 @@ private fun ComposableHistoryListItemExpandedPreview() {
) )
HistoryItem( HistoryItem(
onAction = {}, onAction = {},
isHideBalances = false,
transaction = transaction =
TransactionUiFixture.new( TransactionUiFixture.new(
overview = TransactionOverviewFixture.new().copy(isSentTransaction = false), overview = TransactionOverviewFixture.new().copy(isSentTransaction = false),
@ -279,6 +288,7 @@ private fun ComposableHistoryListItemsPreview() {
BlankSurface { BlankSurface {
HistoryItem( HistoryItem(
onAction = {}, onAction = {},
isHideBalances = false,
transaction = transaction =
TransactionUiFixture.new( TransactionUiFixture.new(
messages = persistentListOf("Message 1", "Message 2", "Message 3"), messages = persistentListOf("Message 1", "Message 2", "Message 3"),
@ -295,6 +305,7 @@ const val ADDRESS_IN_TITLE_WIDTH_RATIO = 0.5f
@Suppress("LongMethod") @Suppress("LongMethod")
private fun HistoryItem( private fun HistoryItem(
transaction: TransactionUi, transaction: TransactionUi,
isHideBalances: Boolean,
onAction: (TrxItemAction) -> Unit, onAction: (TrxItemAction) -> Unit,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
@ -373,6 +384,7 @@ private fun HistoryItem(
Column { Column {
HistoryItemCollapsedMainPart( HistoryItemCollapsedMainPart(
transaction = transaction, transaction = transaction,
isHideBalances = isHideBalances,
typeText = typeText, typeText = typeText,
textStyle = textStyle, textStyle = textStyle,
textColor = textColor, textColor = textColor,
@ -417,6 +429,7 @@ private fun HistoryItemCollapsedMainPart(
typeText: String, typeText: String,
textStyle: TextStyle, textStyle: TextStyle,
textColor: Color, textColor: Color,
isHideBalances: Boolean,
onAction: (TrxItemAction) -> Unit, onAction: (TrxItemAction) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
@ -475,6 +488,7 @@ private fun HistoryItemCollapsedMainPart(
suffix = stringResource(id = R.string.general_etc) suffix = stringResource(id = R.string.general_etc)
).asZecAmountTriple(prefix) ).asZecAmountTriple(prefix)
}, },
isHideBalances = isHideBalances,
textStyles = textStyles =
Pair( Pair(
first = valueTextStyle, first = valueTextStyle,
@ -812,6 +826,8 @@ private fun HistoryItemTransactionFeePart(
} else { } else {
StyledBalance( StyledBalance(
balanceParts = fee.toZecStringFull().asZecAmountTriple(), balanceParts = fee.toZecStringFull().asZecAmountTriple(),
// Fees are always visible
isHideBalances = false,
textStyles = textStyles =
Pair( Pair(
first = ZcashTheme.extendedTypography.transactionItemStyles.feeFirstPart, first = ZcashTheme.extendedTypography.transactionItemStyles.feeFirstPart,

View File

@ -23,6 +23,7 @@ import co.electriccoin.zcash.ui.design.MINIMAL_WEIGHT
import co.electriccoin.zcash.ui.design.component.BlankBgScaffold import co.electriccoin.zcash.ui.design.component.BlankBgScaffold
import co.electriccoin.zcash.ui.design.component.PrimaryButton import co.electriccoin.zcash.ui.design.component.PrimaryButton
import co.electriccoin.zcash.ui.design.component.SmallTopAppBar import co.electriccoin.zcash.ui.design.component.SmallTopAppBar
import co.electriccoin.zcash.ui.design.component.TopAppBarBackNavigation
import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.design.theme.ZcashTheme.dimens import co.electriccoin.zcash.ui.design.theme.ZcashTheme.dimens
import co.electriccoin.zcash.ui.screen.advancedsettings.AdvancedSettingsTag import co.electriccoin.zcash.ui.screen.advancedsettings.AdvancedSettingsTag
@ -97,9 +98,13 @@ private fun AdvancedSettingsTopAppBar(
}, },
modifier = Modifier.testTag(AdvancedSettingsTag.ADVANCED_SETTINGS_TOP_APP_BAR), modifier = Modifier.testTag(AdvancedSettingsTag.ADVANCED_SETTINGS_TOP_APP_BAR),
showTitleLogo = true, showTitleLogo = true,
backText = stringResource(id = R.string.advanced_settings_back).uppercase(), navigationAction = {
backContentDescriptionText = stringResource(R.string.advanced_settings_back_content_description), TopAppBarBackNavigation(
onBack = onBack, backText = stringResource(id = R.string.back_navigation).uppercase(),
backContentDescriptionText = stringResource(R.string.back_navigation_content_description),
onBack = onBack
)
}
) )
} }

View File

@ -26,6 +26,7 @@ import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
import co.electriccoin.zcash.ui.common.model.WalletRestoringState import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.common.model.WalletSnapshot import co.electriccoin.zcash.ui.common.model.WalletSnapshot
import co.electriccoin.zcash.ui.common.viewmodel.CheckUpdateViewModel import co.electriccoin.zcash.ui.common.viewmodel.CheckUpdateViewModel
import co.electriccoin.zcash.ui.common.viewmodel.HomeViewModel
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
import co.electriccoin.zcash.ui.configuration.ConfigurationEntries import co.electriccoin.zcash.ui.configuration.ConfigurationEntries
import co.electriccoin.zcash.ui.configuration.RemoteConfig import co.electriccoin.zcash.ui.configuration.RemoteConfig
@ -54,6 +55,8 @@ internal fun WrapBalances(
val createTransactionsViewModel by activity.viewModels<CreateTransactionsViewModel>() val createTransactionsViewModel by activity.viewModels<CreateTransactionsViewModel>()
val homeViewModel by activity.viewModels<HomeViewModel>()
val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value
val walletSnapshot = walletViewModel.walletSnapshot.collectAsStateWithLifecycle().value val walletSnapshot = walletViewModel.walletSnapshot.collectAsStateWithLifecycle().value
@ -64,6 +67,8 @@ internal fun WrapBalances(
val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value val walletState = walletViewModel.walletStateInformation.collectAsStateWithLifecycle().value
val isHideBalances = homeViewModel.isHideBalances.collectAsStateWithLifecycle().value ?: false
val checkUpdateViewModel by activity.viewModels<CheckUpdateViewModel> { val checkUpdateViewModel by activity.viewModels<CheckUpdateViewModel> {
CheckUpdateViewModel.CheckUpdateViewModelFactory( CheckUpdateViewModel.CheckUpdateViewModelFactory(
activity.application, activity.application,
@ -79,7 +84,9 @@ internal fun WrapBalances(
checkUpdateViewModel = checkUpdateViewModel, checkUpdateViewModel = checkUpdateViewModel,
goSettings = goSettings, goSettings = goSettings,
goMultiTrxSubmissionFailure = goMultiTrxSubmissionFailure, goMultiTrxSubmissionFailure = goMultiTrxSubmissionFailure,
isHideBalances = isHideBalances,
lifecycleScope = activity.lifecycleScope, lifecycleScope = activity.lifecycleScope,
onHideBalances = { homeViewModel.showOrHideBalances() },
spendingKey = spendingKey, spendingKey = spendingKey,
synchronizer = synchronizer, synchronizer = synchronizer,
topAppBarSubTitleState = walletState, topAppBarSubTitleState = walletState,
@ -101,6 +108,8 @@ internal fun WrapBalances(
goSettings: () -> Unit, goSettings: () -> Unit,
goMultiTrxSubmissionFailure: () -> Unit, goMultiTrxSubmissionFailure: () -> Unit,
lifecycleScope: CoroutineScope, lifecycleScope: CoroutineScope,
isHideBalances: Boolean,
onHideBalances: () -> Unit,
spendingKey: UnifiedSpendingKey?, spendingKey: UnifiedSpendingKey?,
synchronizer: Synchronizer?, synchronizer: Synchronizer?,
topAppBarSubTitleState: TopAppBarSubTitleState, topAppBarSubTitleState: TopAppBarSubTitleState,
@ -158,7 +167,9 @@ internal fun WrapBalances(
Balances( Balances(
balanceState = balanceState, balanceState = balanceState,
isFiatConversionEnabled = isFiatConversionEnabled, isFiatConversionEnabled = isFiatConversionEnabled,
isHideBalances = isHideBalances,
isUpdateAvailable = isUpdateAvailable, isUpdateAvailable = isUpdateAvailable,
onHideBalances = onHideBalances,
onSettings = goSettings, onSettings = goSettings,
isShowingErrorDialog = isShowingErrorDialog, isShowingErrorDialog = isShowingErrorDialog,
setShowErrorDialog = setShowErrorDialog, setShowErrorDialog = setShowErrorDialog,

View File

@ -79,6 +79,7 @@ import co.electriccoin.zcash.ui.design.component.Reference
import co.electriccoin.zcash.ui.design.component.Small import co.electriccoin.zcash.ui.design.component.Small
import co.electriccoin.zcash.ui.design.component.SmallTopAppBar import co.electriccoin.zcash.ui.design.component.SmallTopAppBar
import co.electriccoin.zcash.ui.design.component.StyledBalance import co.electriccoin.zcash.ui.design.component.StyledBalance
import co.electriccoin.zcash.ui.design.component.TopAppBarHideBalancesNavigation
import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.BalanceStateFixture import co.electriccoin.zcash.ui.fixture.BalanceStateFixture
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
@ -94,11 +95,13 @@ private fun ComposableBalancesPreview() {
Balances( Balances(
balanceState = BalanceStateFixture.new(), balanceState = BalanceStateFixture.new(),
isFiatConversionEnabled = false, isFiatConversionEnabled = false,
isHideBalances = false,
isUpdateAvailable = false, isUpdateAvailable = false,
isShowingErrorDialog = false, isShowingErrorDialog = false,
hideStatusDialog = {}, hideStatusDialog = {},
showStatusDialog = null, showStatusDialog = null,
setShowErrorDialog = {}, setShowErrorDialog = {},
onHideBalances = {},
onSettings = {}, onSettings = {},
onShielding = {}, onShielding = {},
onStatusClick = {}, onStatusClick = {},
@ -118,11 +121,13 @@ private fun ComposableBalancesShieldDarkPreview() {
Balances( Balances(
balanceState = BalanceStateFixture.new(), balanceState = BalanceStateFixture.new(),
isFiatConversionEnabled = false, isFiatConversionEnabled = false,
isHideBalances = false,
isUpdateAvailable = false, isUpdateAvailable = false,
isShowingErrorDialog = true, isShowingErrorDialog = true,
hideStatusDialog = {}, hideStatusDialog = {},
showStatusDialog = null, showStatusDialog = null,
setShowErrorDialog = {}, setShowErrorDialog = {},
onHideBalances = {},
onSettings = {}, onSettings = {},
onShielding = {}, onShielding = {},
onStatusClick = {}, onStatusClick = {},
@ -153,14 +158,16 @@ private fun ComposableBalancesShieldErrorDialogPreview() {
fun Balances( fun Balances(
balanceState: BalanceState, balanceState: BalanceState,
isFiatConversionEnabled: Boolean, isFiatConversionEnabled: Boolean,
isHideBalances: Boolean,
isUpdateAvailable: Boolean, isUpdateAvailable: Boolean,
isShowingErrorDialog: Boolean, isShowingErrorDialog: Boolean,
hideStatusDialog: () -> Unit, hideStatusDialog: () -> Unit,
showStatusDialog: StatusAction.Detailed?, onHideBalances: () -> Unit,
setShowErrorDialog: (Boolean) -> Unit,
onSettings: () -> Unit, onSettings: () -> Unit,
onShielding: () -> Unit, onShielding: () -> Unit,
onStatusClick: (StatusAction) -> Unit, onStatusClick: (StatusAction) -> Unit,
showStatusDialog: StatusAction.Detailed?,
setShowErrorDialog: (Boolean) -> Unit,
shieldState: ShieldState, shieldState: ShieldState,
snackbarHostState: SnackbarHostState, snackbarHostState: SnackbarHostState,
topAppBarSubTitleState: TopAppBarSubTitleState, topAppBarSubTitleState: TopAppBarSubTitleState,
@ -170,6 +177,8 @@ fun Balances(
BlankBgScaffold( BlankBgScaffold(
topBar = { topBar = {
BalancesTopAppBar( BalancesTopAppBar(
isHideBalances = isHideBalances,
onHideBalances = onHideBalances,
onSettings = onSettings, onSettings = onSettings,
subTitleState = topAppBarSubTitleState, subTitleState = topAppBarSubTitleState,
) )
@ -184,6 +193,7 @@ fun Balances(
BalancesMainContent( BalancesMainContent(
balanceState = balanceState, balanceState = balanceState,
isFiatConversionEnabled = isFiatConversionEnabled, isFiatConversionEnabled = isFiatConversionEnabled,
isHideBalances = isHideBalances,
isUpdateAvailable = isUpdateAvailable, isUpdateAvailable = isUpdateAvailable,
onShielding = onShielding, onShielding = onShielding,
onStatusClick = onStatusClick, onStatusClick = onStatusClick,
@ -256,6 +266,8 @@ fun ShieldingErrorDialog(
@Composable @Composable
private fun BalancesTopAppBar( private fun BalancesTopAppBar(
isHideBalances: Boolean,
onHideBalances: () -> Unit,
onSettings: () -> Unit, onSettings: () -> Unit,
subTitleState: TopAppBarSubTitleState subTitleState: TopAppBarSubTitleState
) { ) {
@ -279,6 +291,21 @@ private fun BalancesTopAppBar(
) )
} }
}, },
navigationAction = {
TopAppBarHideBalancesNavigation(
contentDescription = stringResource(id = R.string.hide_balances_content_description),
iconVector =
ImageVector.vectorResource(
if (isHideBalances) {
R.drawable.ic_hide_balances_on
} else {
R.drawable.ic_hide_balances_off
}
),
onClick = onHideBalances,
modifier = Modifier.testTag(CommonTag.HIDE_BALANCES_TOP_BAR_BUTTON)
)
},
) )
} }
@ -287,6 +314,7 @@ private fun BalancesTopAppBar(
private fun BalancesMainContent( private fun BalancesMainContent(
balanceState: BalanceState, balanceState: BalanceState,
isFiatConversionEnabled: Boolean, isFiatConversionEnabled: Boolean,
isHideBalances: Boolean,
isUpdateAvailable: Boolean, isUpdateAvailable: Boolean,
onShielding: () -> Unit, onShielding: () -> Unit,
onStatusClick: (StatusAction) -> Unit, onStatusClick: (StatusAction) -> Unit,
@ -307,6 +335,7 @@ private fun BalancesMainContent(
BalanceWidget( BalanceWidget(
balanceState = balanceState, balanceState = balanceState,
isHideBalances = isHideBalances,
isReferenceToBalances = false, isReferenceToBalances = false,
onReferenceClick = {} onReferenceClick = {}
) )
@ -321,13 +350,15 @@ private fun BalancesMainContent(
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault)) Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
BalancesOverview( BalancesOverview(
walletSnapshot = walletSnapshot,
isFiatConversionEnabled = isFiatConversionEnabled, isFiatConversionEnabled = isFiatConversionEnabled,
isHideBalances = isHideBalances,
walletSnapshot = walletSnapshot,
) )
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge)) Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge))
TransparentBalancePanel( TransparentBalancePanel(
isHideBalances = isHideBalances,
onShielding = onShielding, onShielding = onShielding,
shieldState = shieldState, shieldState = shieldState,
walletSnapshot = walletSnapshot, walletSnapshot = walletSnapshot,
@ -366,6 +397,7 @@ const val DEFAULT_LESS_THAN_FEE = 100_000L
@Composable @Composable
fun TransparentBalancePanel( fun TransparentBalancePanel(
isHideBalances: Boolean,
onShielding: () -> Unit, onShielding: () -> Unit,
shieldState: ShieldState, shieldState: ShieldState,
walletSnapshot: WalletSnapshot, walletSnapshot: WalletSnapshot,
@ -383,6 +415,7 @@ fun TransparentBalancePanel(
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault)) Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
TransparentBalanceRow( TransparentBalanceRow(
isHideBalances = isHideBalances,
isProgressbarVisible = shieldState == ShieldState.Running, isProgressbarVisible = shieldState == ShieldState.Running,
onHelpClick = { showHelpPanel = !showHelpPanel }, onHelpClick = { showHelpPanel = !showHelpPanel },
walletSnapshot = walletSnapshot walletSnapshot = walletSnapshot
@ -428,6 +461,7 @@ fun TransparentBalancePanel(
@Composable @Composable
fun TransparentBalanceRow( fun TransparentBalanceRow(
isHideBalances: Boolean,
isProgressbarVisible: Boolean, isProgressbarVisible: Boolean,
onHelpClick: () -> Unit, onHelpClick: () -> Unit,
walletSnapshot: WalletSnapshot, walletSnapshot: WalletSnapshot,
@ -466,6 +500,7 @@ fun TransparentBalanceRow(
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
StyledBalance( StyledBalance(
balanceParts = walletSnapshot.transparentBalance.toZecStringFull().asZecAmountTriple(), balanceParts = walletSnapshot.transparentBalance.toZecStringFull().asZecAmountTriple(),
isHideBalances = isHideBalances,
textStyles = textStyles =
Pair( Pair(
ZcashTheme.extendedTypography.balanceSingleStyles.first, ZcashTheme.extendedTypography.balanceSingleStyles.first,
@ -526,18 +561,19 @@ fun TransparentBalanceHelpPanel(onHideHelpPanel: () -> Unit) {
fun BalancesOverview( fun BalancesOverview(
walletSnapshot: WalletSnapshot, walletSnapshot: WalletSnapshot,
isFiatConversionEnabled: Boolean, isFiatConversionEnabled: Boolean,
isHideBalances: Boolean,
) { ) {
Column { Column {
SpendableBalanceRow(walletSnapshot) SpendableBalanceRow(isHideBalances, walletSnapshot)
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault)) Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
ChangePendingRow(walletSnapshot) ChangePendingRow(isHideBalances, walletSnapshot)
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault)) Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
// aka value pending // aka value pending
PendingTransactionsRow(walletSnapshot) PendingTransactionsRow(isHideBalances, walletSnapshot)
if (isFiatConversionEnabled) { if (isFiatConversionEnabled) {
val walletDisplayValues = val walletDisplayValues =
@ -574,7 +610,10 @@ fun BalancesOverview(
const val TEXT_PART_WIDTH_RATIO = 0.6f const val TEXT_PART_WIDTH_RATIO = 0.6f
@Composable @Composable
fun SpendableBalanceRow(walletSnapshot: WalletSnapshot) { fun SpendableBalanceRow(
isHideBalances: Boolean,
walletSnapshot: WalletSnapshot
) {
Row( Row(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
@ -588,6 +627,7 @@ fun SpendableBalanceRow(walletSnapshot: WalletSnapshot) {
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
StyledBalance( StyledBalance(
balanceParts = walletSnapshot.spendableBalance().toZecStringFull().asZecAmountTriple(), balanceParts = walletSnapshot.spendableBalance().toZecStringFull().asZecAmountTriple(),
isHideBalances = isHideBalances,
textStyles = textStyles =
Pair( Pair(
ZcashTheme.extendedTypography.balanceSingleStyles.first, ZcashTheme.extendedTypography.balanceSingleStyles.first,
@ -609,7 +649,10 @@ fun SpendableBalanceRow(walletSnapshot: WalletSnapshot) {
} }
@Composable @Composable
fun ChangePendingRow(walletSnapshot: WalletSnapshot) { fun ChangePendingRow(
isHideBalances: Boolean,
walletSnapshot: WalletSnapshot
) {
Row( Row(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
@ -623,6 +666,7 @@ fun ChangePendingRow(walletSnapshot: WalletSnapshot) {
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
StyledBalance( StyledBalance(
balanceParts = walletSnapshot.changePendingBalance().toZecStringFull().asZecAmountTriple(), balanceParts = walletSnapshot.changePendingBalance().toZecStringFull().asZecAmountTriple(),
isHideBalances = isHideBalances,
textStyles = textStyles =
Pair( Pair(
ZcashTheme.extendedTypography.balanceSingleStyles.first, ZcashTheme.extendedTypography.balanceSingleStyles.first,
@ -643,7 +687,10 @@ fun ChangePendingRow(walletSnapshot: WalletSnapshot) {
} }
@Composable @Composable
fun PendingTransactionsRow(walletSnapshot: WalletSnapshot) { fun PendingTransactionsRow(
isHideBalances: Boolean,
walletSnapshot: WalletSnapshot
) {
Row( Row(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
@ -657,6 +704,7 @@ fun PendingTransactionsRow(walletSnapshot: WalletSnapshot) {
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
StyledBalance( StyledBalance(
balanceParts = walletSnapshot.valuePendingBalance().toZecStringFull().asZecAmountTriple(), balanceParts = walletSnapshot.valuePendingBalance().toZecStringFull().asZecAmountTriple(),
isHideBalances = isHideBalances,
textStyles = textStyles =
Pair( Pair(
ZcashTheme.extendedTypography.balanceSingleStyles.first, ZcashTheme.extendedTypography.balanceSingleStyles.first,

View File

@ -45,6 +45,7 @@ import co.electriccoin.zcash.ui.design.component.FormTextField
import co.electriccoin.zcash.ui.design.component.PrimaryButton import co.electriccoin.zcash.ui.design.component.PrimaryButton
import co.electriccoin.zcash.ui.design.component.RadioButton import co.electriccoin.zcash.ui.design.component.RadioButton
import co.electriccoin.zcash.ui.design.component.SmallTopAppBar import co.electriccoin.zcash.ui.design.component.SmallTopAppBar
import co.electriccoin.zcash.ui.design.component.TopAppBarBackNavigation
import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.screen.chooseserver.ChooseServerTag import co.electriccoin.zcash.ui.screen.chooseserver.ChooseServerTag
import co.electriccoin.zcash.ui.screen.chooseserver.validateCustomServerValue import co.electriccoin.zcash.ui.screen.chooseserver.validateCustomServerValue
@ -233,9 +234,13 @@ private fun ChooseServerTopAppBar(
}, },
modifier = Modifier.testTag(ChooseServerTag.CHOOSE_SERVER_TOP_APP_BAR), modifier = Modifier.testTag(ChooseServerTag.CHOOSE_SERVER_TOP_APP_BAR),
showTitleLogo = true, showTitleLogo = true,
backText = stringResource(id = R.string.choose_server_back).uppercase(), navigationAction = {
backContentDescriptionText = stringResource(R.string.choose_server_back_content_description), TopAppBarBackNavigation(
onBack = onBack, backText = stringResource(id = R.string.back_navigation).uppercase(),
backContentDescriptionText = stringResource(R.string.back_navigation_content_description),
onBack = onBack
)
}
) )
} }

View File

@ -28,6 +28,7 @@ import co.electriccoin.zcash.ui.design.component.GridBgScaffold
import co.electriccoin.zcash.ui.design.component.GridBgSmallTopAppBar import co.electriccoin.zcash.ui.design.component.GridBgSmallTopAppBar
import co.electriccoin.zcash.ui.design.component.LabeledCheckBox import co.electriccoin.zcash.ui.design.component.LabeledCheckBox
import co.electriccoin.zcash.ui.design.component.PrimaryButton import co.electriccoin.zcash.ui.design.component.PrimaryButton
import co.electriccoin.zcash.ui.design.component.TopAppBarBackNavigation
import co.electriccoin.zcash.ui.design.component.TopScreenLogoTitle import co.electriccoin.zcash.ui.design.component.TopScreenLogoTitle
import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
@ -88,9 +89,13 @@ private fun DeleteWalletDataTopAppBar(
TopAppBarSubTitleState.Restoring -> stringResource(id = R.string.restoring_wallet_label) TopAppBarSubTitleState.Restoring -> stringResource(id = R.string.restoring_wallet_label)
TopAppBarSubTitleState.None -> null TopAppBarSubTitleState.None -> null
}, },
backText = stringResource(R.string.delete_wallet_back).uppercase(), navigationAction = {
backContentDescriptionText = stringResource(R.string.delete_wallet_back_content_description), TopAppBarBackNavigation(
onBack = onBack, backText = stringResource(id = R.string.back_navigation).uppercase(),
backContentDescriptionText = stringResource(R.string.back_navigation_content_description),
onBack = onBack
)
}
) )
} }

View File

@ -30,6 +30,7 @@ import co.electriccoin.zcash.ui.design.component.GridBgScaffold
import co.electriccoin.zcash.ui.design.component.GridBgSmallTopAppBar import co.electriccoin.zcash.ui.design.component.GridBgSmallTopAppBar
import co.electriccoin.zcash.ui.design.component.LabeledCheckBox import co.electriccoin.zcash.ui.design.component.LabeledCheckBox
import co.electriccoin.zcash.ui.design.component.PrimaryButton import co.electriccoin.zcash.ui.design.component.PrimaryButton
import co.electriccoin.zcash.ui.design.component.TopAppBarBackNavigation
import co.electriccoin.zcash.ui.design.component.TopScreenLogoTitle import co.electriccoin.zcash.ui.design.component.TopScreenLogoTitle
import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
@ -93,9 +94,13 @@ private fun ExportPrivateDataTopAppBar(
TopAppBarSubTitleState.Restoring -> stringResource(id = R.string.restoring_wallet_label) TopAppBarSubTitleState.Restoring -> stringResource(id = R.string.restoring_wallet_label)
TopAppBarSubTitleState.None -> null TopAppBarSubTitleState.None -> null
}, },
backText = stringResource(R.string.export_data_back).uppercase(), navigationAction = {
backContentDescriptionText = stringResource(R.string.export_data_back_content_description), TopAppBarBackNavigation(
onBack = onBack, backText = stringResource(id = R.string.back_navigation).uppercase(),
backContentDescriptionText = stringResource(R.string.back_navigation_content_description),
onBack = onBack
)
},
) )
} }

View File

@ -73,6 +73,7 @@ import co.electriccoin.zcash.ui.design.component.GridBgScaffold
import co.electriccoin.zcash.ui.design.component.GridBgSmallTopAppBar import co.electriccoin.zcash.ui.design.component.GridBgSmallTopAppBar
import co.electriccoin.zcash.ui.design.component.PrimaryButton import co.electriccoin.zcash.ui.design.component.PrimaryButton
import co.electriccoin.zcash.ui.design.component.Reference import co.electriccoin.zcash.ui.design.component.Reference
import co.electriccoin.zcash.ui.design.component.TopAppBarBackNavigation
import co.electriccoin.zcash.ui.design.component.TopScreenLogoTitle import co.electriccoin.zcash.ui.design.component.TopScreenLogoTitle
import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.screen.restore.RestoreTag import co.electriccoin.zcash.ui.screen.restore.RestoreTag
@ -355,9 +356,13 @@ private fun RestoreSeedTopAppBar(
) { ) {
GridBgSmallTopAppBar( GridBgSmallTopAppBar(
modifier = modifier, modifier = modifier,
backText = stringResource(id = R.string.restore_back).uppercase(), navigationAction = {
backContentDescriptionText = stringResource(R.string.restore_back_content_description), TopAppBarBackNavigation(
onBack = onBack, backText = stringResource(id = R.string.back_navigation).uppercase(),
backContentDescriptionText = stringResource(R.string.back_navigation_content_description),
onBack = onBack
)
},
regularActions = { regularActions = {
ClearSeedMenuItem( ClearSeedMenuItem(
onSeedClear = onClear onSeedClear = onClear
@ -373,9 +378,13 @@ private fun RestoreSeedBirthdayTopAppBar(
) { ) {
GridBgSmallTopAppBar( GridBgSmallTopAppBar(
modifier = modifier, modifier = modifier,
backText = stringResource(id = R.string.restore_back).uppercase(), navigationAction = {
backContentDescriptionText = stringResource(R.string.restore_back_content_description), TopAppBarBackNavigation(
onBack = onBack, backText = stringResource(id = R.string.back_navigation).uppercase(),
backContentDescriptionText = stringResource(R.string.back_navigation_content_description),
onBack = onBack
)
},
) )
} }

View File

@ -71,6 +71,7 @@ import co.electriccoin.zcash.ui.design.component.BlankSurface
import co.electriccoin.zcash.ui.design.component.SecondaryButton import co.electriccoin.zcash.ui.design.component.SecondaryButton
import co.electriccoin.zcash.ui.design.component.Small import co.electriccoin.zcash.ui.design.component.Small
import co.electriccoin.zcash.ui.design.component.SmallTopAppBar import co.electriccoin.zcash.ui.design.component.SmallTopAppBar
import co.electriccoin.zcash.ui.design.component.TopAppBarBackNavigation
import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.screen.scan.ScanTag import co.electriccoin.zcash.ui.screen.scan.ScanTag
import co.electriccoin.zcash.ui.screen.scan.model.ScanState import co.electriccoin.zcash.ui.screen.scan.model.ScanState
@ -284,15 +285,16 @@ private fun ScanTopAppBar(
TopAppBarSubTitleState.Restoring -> stringResource(id = R.string.restoring_wallet_label) TopAppBarSubTitleState.Restoring -> stringResource(id = R.string.restoring_wallet_label)
TopAppBarSubTitleState.None -> null TopAppBarSubTitleState.None -> null
}, },
backText = navigationAction = {
if (showBack) { if (showBack) {
stringResource(id = R.string.scan_back) TopAppBarBackNavigation(
} else { backText = stringResource(id = R.string.back_navigation).uppercase(),
null backContentDescriptionText = stringResource(R.string.back_navigation_content_description),
}, onBack = onBack
backContentDescriptionText = stringResource(id = R.string.scan_back_content_description), )
}
},
colors = ZcashTheme.colors.transparentTopAppBarColors, colors = ZcashTheme.colors.transparentTopAppBarColors,
onBack = onBack,
) )
} }

View File

@ -29,6 +29,7 @@ import co.electriccoin.zcash.ui.design.component.GridBgScaffold
import co.electriccoin.zcash.ui.design.component.GridBgSmallTopAppBar import co.electriccoin.zcash.ui.design.component.GridBgSmallTopAppBar
import co.electriccoin.zcash.ui.design.component.LabeledCheckBox import co.electriccoin.zcash.ui.design.component.LabeledCheckBox
import co.electriccoin.zcash.ui.design.component.PrimaryButton import co.electriccoin.zcash.ui.design.component.PrimaryButton
import co.electriccoin.zcash.ui.design.component.TopAppBarBackNavigation
import co.electriccoin.zcash.ui.design.component.TopScreenLogoTitle import co.electriccoin.zcash.ui.design.component.TopScreenLogoTitle
import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.VersionInfoFixture import co.electriccoin.zcash.ui.fixture.VersionInfoFixture
@ -90,9 +91,13 @@ fun SecurityWarning(
@Composable @Composable
private fun SecurityWarningTopAppBar(onBack: () -> Unit) { private fun SecurityWarningTopAppBar(onBack: () -> Unit) {
GridBgSmallTopAppBar( GridBgSmallTopAppBar(
backText = stringResource(R.string.security_warning_back).uppercase(), navigationAction = {
backContentDescriptionText = stringResource(R.string.security_warning_back_content_description), TopAppBarBackNavigation(
onBack = onBack, backText = stringResource(id = R.string.back_navigation).uppercase(),
backContentDescriptionText = stringResource(R.string.back_navigation_content_description),
onBack = onBack
)
}
) )
} }

View File

@ -49,6 +49,7 @@ import co.electriccoin.zcash.ui.design.component.ChipGrid
import co.electriccoin.zcash.ui.design.component.GridBgScaffold import co.electriccoin.zcash.ui.design.component.GridBgScaffold
import co.electriccoin.zcash.ui.design.component.GridBgSmallTopAppBar import co.electriccoin.zcash.ui.design.component.GridBgSmallTopAppBar
import co.electriccoin.zcash.ui.design.component.PrimaryButton import co.electriccoin.zcash.ui.design.component.PrimaryButton
import co.electriccoin.zcash.ui.design.component.TopAppBarBackNavigation
import co.electriccoin.zcash.ui.design.component.TopScreenLogoTitle import co.electriccoin.zcash.ui.design.component.TopScreenLogoTitle
import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.VersionInfoFixture import co.electriccoin.zcash.ui.fixture.VersionInfoFixture
@ -127,9 +128,13 @@ private fun SeedRecoveryTopAppBar(
TopAppBarSubTitleState.None -> null TopAppBarSubTitleState.None -> null
}, },
modifier = modifier, modifier = modifier,
backText = stringResource(id = R.string.seed_recovery_back).uppercase(), navigationAction = {
backContentDescriptionText = stringResource(R.string.seed_recovery_back_content_description), TopAppBarBackNavigation(
onBack = onBack, backText = stringResource(id = R.string.back_navigation).uppercase(),
backContentDescriptionText = stringResource(R.string.back_navigation_content_description),
onBack = onBack
)
},
regularActions = { regularActions = {
if (versionInfo.isDebuggable && !versionInfo.isRunningUnderTestService) { if (versionInfo.isDebuggable && !versionInfo.isRunningUnderTestService) {
DebugMenu( DebugMenu(

View File

@ -24,6 +24,7 @@ import co.electriccoin.zcash.ui.common.compose.BalanceState
import co.electriccoin.zcash.ui.common.compose.LocalActivity import co.electriccoin.zcash.ui.common.compose.LocalActivity
import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState import co.electriccoin.zcash.ui.common.model.TopAppBarSubTitleState
import co.electriccoin.zcash.ui.common.model.WalletSnapshot import co.electriccoin.zcash.ui.common.model.WalletSnapshot
import co.electriccoin.zcash.ui.common.viewmodel.HomeViewModel
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
import co.electriccoin.zcash.ui.design.component.CircularScreenProgressIndicator import co.electriccoin.zcash.ui.design.component.CircularScreenProgressIndicator
import co.electriccoin.zcash.ui.screen.send.ext.Saver import co.electriccoin.zcash.ui.screen.send.ext.Saver
@ -50,6 +51,8 @@ internal fun WrapSend(
val walletViewModel by activity.viewModels<WalletViewModel>() val walletViewModel by activity.viewModels<WalletViewModel>()
val homeViewModel by activity.viewModels<HomeViewModel>()
val hasCameraFeature = activity.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY) val hasCameraFeature = activity.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)
val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value
@ -66,8 +69,12 @@ internal fun WrapSend(
val balanceState = walletViewModel.balanceState.collectAsStateWithLifecycle().value val balanceState = walletViewModel.balanceState.collectAsStateWithLifecycle().value
val isHideBalances = homeViewModel.isHideBalances.collectAsStateWithLifecycle().value ?: false
WrapSend( WrapSend(
balanceState = balanceState, balanceState = balanceState,
isHideBalances = isHideBalances,
onHideBalances = { homeViewModel.showOrHideBalances() },
sendArguments = sendArguments, sendArguments = sendArguments,
synchronizer = synchronizer, synchronizer = synchronizer,
walletSnapshot = walletSnapshot, walletSnapshot = walletSnapshot,
@ -88,6 +95,7 @@ internal fun WrapSend(
@Composable @Composable
internal fun WrapSend( internal fun WrapSend(
balanceState: BalanceState, balanceState: BalanceState,
isHideBalances: Boolean,
goToQrScanner: () -> Unit, goToQrScanner: () -> Unit,
goBack: () -> Unit, goBack: () -> Unit,
goBalances: () -> Unit, goBalances: () -> Unit,
@ -95,6 +103,7 @@ internal fun WrapSend(
goSendConfirmation: (ZecSend) -> Unit, goSendConfirmation: (ZecSend) -> Unit,
hasCameraFeature: Boolean, hasCameraFeature: Boolean,
monetarySeparators: MonetarySeparators, monetarySeparators: MonetarySeparators,
onHideBalances: () -> Unit,
sendArguments: SendArguments?, sendArguments: SendArguments?,
spendingKey: UnifiedSpendingKey?, spendingKey: UnifiedSpendingKey?,
synchronizer: Synchronizer?, synchronizer: Synchronizer?,
@ -181,6 +190,7 @@ internal fun WrapSend(
} else { } else {
Send( Send(
balanceState = balanceState, balanceState = balanceState,
isHideBalances = isHideBalances,
sendStage = sendStage, sendStage = sendStage,
onCreateZecSend = { newZecSend -> onCreateZecSend = { newZecSend ->
scope.launch { scope.launch {
@ -199,6 +209,7 @@ internal fun WrapSend(
} }
}, },
onBack = onBackAction, onBack = onBackAction,
onHideBalances = onHideBalances,
onSettings = goSettings, onSettings = goSettings,
recipientAddressState = recipientAddressState, recipientAddressState = recipientAddressState,
onRecipientAddressChange = { onRecipientAddressChange = {

View File

@ -32,6 +32,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusDirection import androidx.compose.ui.focus.FocusDirection
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.positionInRoot import androidx.compose.ui.layout.positionInRoot
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
@ -39,6 +40,7 @@ import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.testTag import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.ImeAction
@ -74,6 +76,7 @@ import co.electriccoin.zcash.ui.design.component.FormTextField
import co.electriccoin.zcash.ui.design.component.PrimaryButton import co.electriccoin.zcash.ui.design.component.PrimaryButton
import co.electriccoin.zcash.ui.design.component.Small import co.electriccoin.zcash.ui.design.component.Small
import co.electriccoin.zcash.ui.design.component.SmallTopAppBar import co.electriccoin.zcash.ui.design.component.SmallTopAppBar
import co.electriccoin.zcash.ui.design.component.TopAppBarHideBalancesNavigation
import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.BalanceStateFixture import co.electriccoin.zcash.ui.fixture.BalanceStateFixture
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
@ -93,6 +96,7 @@ private fun PreviewSendForm() {
sendStage = SendStage.Form, sendStage = SendStage.Form,
onCreateZecSend = {}, onCreateZecSend = {},
onBack = {}, onBack = {},
onHideBalances = {},
onSettings = {}, onSettings = {},
onQrScannerOpen = {}, onQrScannerOpen = {},
goBalances = {}, goBalances = {},
@ -105,7 +109,8 @@ private fun PreviewSendForm() {
memoState = MemoState.new("Test message"), memoState = MemoState.new("Test message"),
topAppBarSubTitleState = TopAppBarSubTitleState.None, topAppBarSubTitleState = TopAppBarSubTitleState.None,
walletSnapshot = WalletSnapshotFixture.new(), walletSnapshot = WalletSnapshotFixture.new(),
balanceState = BalanceStateFixture.new() balanceState = BalanceStateFixture.new(),
isHideBalances = false,
) )
} }
} }
@ -118,6 +123,7 @@ private fun SendFormTransparentAddressPreview() {
sendStage = SendStage.Form, sendStage = SendStage.Form,
onCreateZecSend = {}, onCreateZecSend = {},
onBack = {}, onBack = {},
onHideBalances = {},
onSettings = {}, onSettings = {},
onQrScannerOpen = {}, onQrScannerOpen = {},
goBalances = {}, goBalances = {},
@ -134,7 +140,8 @@ private fun SendFormTransparentAddressPreview() {
memoState = MemoState.new("Test message"), memoState = MemoState.new("Test message"),
topAppBarSubTitleState = TopAppBarSubTitleState.None, topAppBarSubTitleState = TopAppBarSubTitleState.None,
walletSnapshot = WalletSnapshotFixture.new(), walletSnapshot = WalletSnapshotFixture.new(),
balanceState = BalanceStateFixture.new() balanceState = BalanceStateFixture.new(),
isHideBalances = false,
) )
} }
} }
@ -146,6 +153,8 @@ private fun SendFormTransparentAddressPreview() {
@Composable @Composable
fun Send( fun Send(
balanceState: BalanceState, balanceState: BalanceState,
isHideBalances: Boolean,
onHideBalances: () -> Unit,
sendStage: SendStage, sendStage: SendStage,
onCreateZecSend: (ZecSend) -> Unit, onCreateZecSend: (ZecSend) -> Unit,
onBack: () -> Unit, onBack: () -> Unit,
@ -164,12 +173,15 @@ fun Send(
) { ) {
BlankBgScaffold(topBar = { BlankBgScaffold(topBar = {
SendTopAppBar( SendTopAppBar(
isHideBalances = isHideBalances,
onHideBalances = onHideBalances,
subTitleState = topAppBarSubTitleState, subTitleState = topAppBarSubTitleState,
onSettings = onSettings onSettings = onSettings
) )
}) { paddingValues -> }) { paddingValues ->
SendMainContent( SendMainContent(
balanceState = balanceState, balanceState = balanceState,
isHideBalances = isHideBalances,
walletSnapshot = walletSnapshot, walletSnapshot = walletSnapshot,
onBack = onBack, onBack = onBack,
sendStage = sendStage, sendStage = sendStage,
@ -197,6 +209,8 @@ fun Send(
@Composable @Composable
private fun SendTopAppBar( private fun SendTopAppBar(
isHideBalances: Boolean,
onHideBalances: () -> Unit,
onSettings: () -> Unit, onSettings: () -> Unit,
subTitleState: TopAppBarSubTitleState subTitleState: TopAppBarSubTitleState
) { ) {
@ -219,6 +233,21 @@ private fun SendTopAppBar(
) )
} }
}, },
navigationAction = {
TopAppBarHideBalancesNavigation(
contentDescription = stringResource(id = R.string.hide_balances_content_description),
iconVector =
ImageVector.vectorResource(
if (isHideBalances) {
R.drawable.ic_hide_balances_on
} else {
R.drawable.ic_hide_balances_off
}
),
onClick = onHideBalances,
modifier = Modifier.testTag(CommonTag.HIDE_BALANCES_TOP_BAR_BUTTON)
)
},
) )
} }
@ -226,6 +255,7 @@ private fun SendTopAppBar(
@Composable @Composable
private fun SendMainContent( private fun SendMainContent(
balanceState: BalanceState, balanceState: BalanceState,
isHideBalances: Boolean,
walletSnapshot: WalletSnapshot, walletSnapshot: WalletSnapshot,
onBack: () -> Unit, onBack: () -> Unit,
goBalances: () -> Unit, goBalances: () -> Unit,
@ -246,6 +276,7 @@ private fun SendMainContent(
SendForm( SendForm(
balanceState = balanceState, balanceState = balanceState,
isHideBalances = isHideBalances,
walletSnapshot = walletSnapshot, walletSnapshot = walletSnapshot,
recipientAddressState = recipientAddressState, recipientAddressState = recipientAddressState,
onRecipientAddressChange = onRecipientAddressChange, onRecipientAddressChange = onRecipientAddressChange,
@ -278,6 +309,7 @@ private fun SendMainContent(
@Composable @Composable
private fun SendForm( private fun SendForm(
balanceState: BalanceState, balanceState: BalanceState,
isHideBalances: Boolean,
walletSnapshot: WalletSnapshot, walletSnapshot: WalletSnapshot,
recipientAddressState: RecipientAddressState, recipientAddressState: RecipientAddressState,
onRecipientAddressChange: (String) -> Unit, onRecipientAddressChange: (String) -> Unit,
@ -311,6 +343,7 @@ private fun SendForm(
BalanceWidget( BalanceWidget(
balanceState = balanceState, balanceState = balanceState,
isHideBalances = isHideBalances,
isReferenceToBalances = true, isReferenceToBalances = true,
onReferenceClick = goBalances onReferenceClick = goBalances
) )

View File

@ -55,6 +55,7 @@ import co.electriccoin.zcash.ui.design.component.Small
import co.electriccoin.zcash.ui.design.component.SmallTopAppBar import co.electriccoin.zcash.ui.design.component.SmallTopAppBar
import co.electriccoin.zcash.ui.design.component.StyledBalance import co.electriccoin.zcash.ui.design.component.StyledBalance
import co.electriccoin.zcash.ui.design.component.Tiny import co.electriccoin.zcash.ui.design.component.Tiny
import co.electriccoin.zcash.ui.design.component.TopAppBarBackNavigation
import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.screen.sendconfirmation.SendConfirmationTag import co.electriccoin.zcash.ui.screen.sendconfirmation.SendConfirmationTag
import co.electriccoin.zcash.ui.screen.sendconfirmation.model.SendConfirmationStage import co.electriccoin.zcash.ui.screen.sendconfirmation.model.SendConfirmationStage
@ -303,12 +304,13 @@ private fun SendConfirmationTopAppBar(
SmallTopAppBar( SmallTopAppBar(
subTitle = subTitle, subTitle = subTitle,
titleText = stringResource(id = R.string.send_confirmation_multiple_error_title), titleText = stringResource(id = R.string.send_confirmation_multiple_error_title),
backText = stringResource(id = R.string.send_confirmation_multiple_error_back), navigationAction = {
backContentDescriptionText = TopAppBarBackNavigation(
stringResource( backText = stringResource(id = R.string.back_navigation).uppercase(),
id = R.string.send_confirmation_multiple_error_back_content_description backContentDescriptionText = stringResource(R.string.back_navigation_content_description),
), onBack = onBack
onBack = onBack, )
},
) )
} }
} }
@ -371,7 +373,11 @@ private fun SendConfirmationContent(
Small(stringResource(R.string.send_confirmation_amount)) Small(stringResource(R.string.send_confirmation_amount))
BalanceWidgetBigLineOnly(parts = zecSend.amount.toZecStringFull().asZecAmountTriple()) BalanceWidgetBigLineOnly(
parts = zecSend.amount.toZecStringFull().asZecAmountTriple(),
// We don't hide any balance in confirmation screen
isHideBalances = false
)
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault)) Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
@ -392,6 +398,8 @@ private fun SendConfirmationContent(
// due to: "Smart cast to 'Proposal' is impossible, because 'zecSend.proposal' is a public API // due to: "Smart cast to 'Proposal' is impossible, because 'zecSend.proposal' is a public API
// property declared in different module. See more details on the Kotlin forum. // property declared in different module. See more details on the Kotlin forum.
balanceParts = zecSend.proposal!!.totalFeeRequired().toZecStringFull().asZecAmountTriple(), balanceParts = zecSend.proposal!!.totalFeeRequired().toZecStringFull().asZecAmountTriple(),
// We don't hide any balance in confirmation screen
isHideBalances = false,
textStyles = textStyles =
Pair( Pair(
ZcashTheme.extendedTypography.balanceSingleStyles.first, ZcashTheme.extendedTypography.balanceSingleStyles.first,

View File

@ -33,6 +33,7 @@ import co.electriccoin.zcash.ui.design.MINIMAL_WEIGHT
import co.electriccoin.zcash.ui.design.component.BlankBgScaffold import co.electriccoin.zcash.ui.design.component.BlankBgScaffold
import co.electriccoin.zcash.ui.design.component.PrimaryButton import co.electriccoin.zcash.ui.design.component.PrimaryButton
import co.electriccoin.zcash.ui.design.component.SmallTopAppBar import co.electriccoin.zcash.ui.design.component.SmallTopAppBar
import co.electriccoin.zcash.ui.design.component.TopAppBarBackNavigation
import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.design.theme.ZcashTheme.dimens import co.electriccoin.zcash.ui.design.theme.ZcashTheme.dimens
import co.electriccoin.zcash.ui.screen.settings.SettingsTag import co.electriccoin.zcash.ui.screen.settings.SettingsTag
@ -128,9 +129,13 @@ private fun SettingsTopAppBar(
}, },
modifier = Modifier.testTag(SettingsTag.SETTINGS_TOP_APP_BAR), modifier = Modifier.testTag(SettingsTag.SETTINGS_TOP_APP_BAR),
showTitleLogo = true, showTitleLogo = true,
backText = stringResource(id = R.string.settings_back).uppercase(), navigationAction = {
backContentDescriptionText = stringResource(R.string.settings_back_content_description), TopAppBarBackNavigation(
onBack = onBack, backText = stringResource(id = R.string.back_navigation).uppercase(),
backContentDescriptionText = stringResource(R.string.back_navigation_content_description),
onBack = onBack
)
},
regularActions = { regularActions = {
if (troubleshootingParameters.isEnabled) { if (troubleshootingParameters.isEnabled) {
TroubleshootingMenu( TroubleshootingMenu(

View File

@ -38,6 +38,7 @@ import co.electriccoin.zcash.ui.design.component.FormTextField
import co.electriccoin.zcash.ui.design.component.GridBgScaffold import co.electriccoin.zcash.ui.design.component.GridBgScaffold
import co.electriccoin.zcash.ui.design.component.GridBgSmallTopAppBar import co.electriccoin.zcash.ui.design.component.GridBgSmallTopAppBar
import co.electriccoin.zcash.ui.design.component.PrimaryButton import co.electriccoin.zcash.ui.design.component.PrimaryButton
import co.electriccoin.zcash.ui.design.component.TopAppBarBackNavigation
import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
@Preview @Preview
@ -141,9 +142,13 @@ private fun SupportTopAppBar(
TopAppBarSubTitleState.None -> null TopAppBarSubTitleState.None -> null
}, },
titleText = stringResource(id = R.string.support_header), titleText = stringResource(id = R.string.support_header),
backText = stringResource(id = R.string.support_back).uppercase(), navigationAction = {
backContentDescriptionText = stringResource(R.string.support_back_content_description), TopAppBarBackNavigation(
onBack = onBack, backText = stringResource(id = R.string.back_navigation).uppercase(),
backContentDescriptionText = stringResource(R.string.back_navigation_content_description),
onBack = onBack
)
},
) )
} }

View File

@ -1,7 +1,5 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="about_title">About</string> <string name="about_title">About</string>
<string name="about_back">Back</string>
<string name="about_back_content_description">Back</string>
<string name="about_version_format" formatted="true">Version <xliff:g example="1.0" id="version_name">%1$s <string name="about_version_format" formatted="true">Version <xliff:g example="1.0" id="version_name">%1$s
</xliff:g></string> </xliff:g></string>
<string name="about_debug_menu_app_name">App name: <string name="about_debug_menu_app_name">App name:

View File

@ -1,7 +1,4 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="advanced_settings_back">Back</string>
<string name="advanced_settings_back_content_description">Back</string>
<string name="advanced_settings_backup_wallet">Recovery phrase</string> <string name="advanced_settings_backup_wallet">Recovery phrase</string>
<string name="advanced_settings_export_private_data">Export private data</string> <string name="advanced_settings_export_private_data">Export private data</string>
<string name="advanced_settings_choose_server">Choose a server</string> <string name="advanced_settings_choose_server">Choose a server</string>
@ -10,5 +7,4 @@
Delete <xliff:g id="app_name" example="Zashi">%1$s</xliff:g> Delete <xliff:g id="app_name" example="Zashi">%1$s</xliff:g>
</string> </string>
<string name="advanced_settings_delete_wallet_footnote">(You will be asked to confirm on next screen)</string> <string name="advanced_settings_delete_wallet_footnote">(You will be asked to confirm on next screen)</string>
</resources> </resources>

View File

@ -1,7 +1,4 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="choose_server_back">Back</string>
<string name="choose_server_back_content_description">Back</string>
<string name="choose_server_title">Server</string> <string name="choose_server_title">Server</string>
<string name="choose_server_default_label">default: <xliff:g id="server" example="example.com:123">%1$s</xliff:g></string> <string name="choose_server_default_label">default: <xliff:g id="server" example="example.com:123">%1$s</xliff:g></string>
<string name="choose_server_custom">custom</string> <string name="choose_server_custom">custom</string>

View File

@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="17dp"
android:height="11dp"
android:viewportWidth="17"
android:viewportHeight="11">
<group>
<clip-path
android:pathData="M0,0.5h17v10h-17z"/>
<path
android:pathData="M8.498,10.5C5.022,10.491 1.809,8.678 0.062,5.733C-0.024,5.589 -0.024,5.412 0.062,5.267C2.756,0.705 8.717,-0.856 13.377,1.781C14.858,2.62 16.086,3.823 16.943,5.272C17.029,5.416 17.029,5.593 16.943,5.738C15.196,8.683 11.982,10.5 8.502,10.505L8.498,10.5ZM1.028,5.5C3.59,9.54 9.007,10.78 13.134,8.273C14.286,7.574 15.253,6.623 15.967,5.5C13.411,1.465 7.993,0.22 3.866,2.727C2.714,3.426 1.742,4.377 1.028,5.505V5.5ZM8.498,8.538C6.784,8.538 5.399,7.178 5.399,5.5C5.399,3.823 6.789,2.467 8.502,2.467C10.216,2.467 11.602,3.827 11.602,5.5C11.602,7.178 10.212,8.534 8.498,8.534V8.538Z"
android:fillColor="#101010"/>
</group>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="17dp"
android:height="17dp"
android:viewportWidth="17"
android:viewportHeight="17">
<path
android:pathData="M2.476,16.569L15.977,1.194C16.186,0.95 16.167,0.573 15.92,0.366C15.673,0.159 15.293,0.178 15.084,0.423L11.723,4.262C10.698,3.848 9.673,3.641 8.609,3.641C3.691,3.641 0.254,8.195 0.121,8.383C-0.05,8.59 -0.031,8.872 0.121,9.079C1.45,10.717 2.856,11.921 4.28,12.712L1.583,15.798C1.374,16.043 1.393,16.419 1.64,16.626C1.754,16.72 1.887,16.777 2.02,16.777C2.191,16.758 2.362,16.701 2.476,16.569ZM1.355,8.703C2.229,7.687 5.02,4.789 8.609,4.789C9.388,4.789 10.147,4.92 10.888,5.184L9.976,6.238C9.54,5.974 9.046,5.843 8.495,5.843C6.9,5.843 5.59,7.141 5.59,8.722C5.59,9.399 5.837,10.02 6.217,10.51L5.077,11.808C3.805,11.15 2.571,10.115 1.355,8.703ZM16.869,8.346C17.04,8.553 17.04,8.854 16.888,9.061C16.736,9.249 13.318,13.803 8.4,13.803C7.812,13.803 7.223,13.728 6.653,13.596L7.565,12.561C7.85,12.599 8.134,12.618 8.419,12.618C11.97,12.636 14.762,9.738 15.635,8.722C14.781,7.725 13.907,6.934 13.034,6.313L13.812,5.429C14.856,6.181 15.882,7.141 16.869,8.346Z"
android:fillColor="#000000"/>
</vector>

View File

@ -2,12 +2,17 @@
<!-- This is replaced by a resource overlay via app/build.gradle.kts --> <!-- This is replaced by a resource overlay via app/build.gradle.kts -->
<string name="app_name">zashi-ui</string> <string name="app_name">zashi-ui</string>
<string name="back_navigation">Back</string>
<string name="back_navigation_content_description">Back</string>
<string name="fiat_currency_conversion_rate_unavailable">Unavailable</string> <string name="fiat_currency_conversion_rate_unavailable">Unavailable</string>
<string name="empty_char">-</string> <string name="empty_char">-</string>
<string name="zcash_logo_content_description">Zcash logo</string> <string name="zcash_logo_content_description">Zcash logo</string>
<string name="settings_menu_content_description">Open Settings</string> <string name="settings_menu_content_description">Open Settings</string>
<string name="balance_widget_available">Available Balance:</string> <string name="balance_widget_available">Available Balance:</string>
<string name="hide_balances_content_description">Hide balances</string>
<!-- This is replaced by a resource overlay via app/build.gradle.kts --> <!-- This is replaced by a resource overlay via app/build.gradle.kts -->
<string name="support_email_address" /> <string name="support_email_address" />

View File

@ -1,7 +1,4 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="delete_wallet_back">Back</string>
<string name="delete_wallet_back_content_description">Back</string>
<string name="delete_wallet_title"> <string name="delete_wallet_title">
Delete <xliff:g id="app_name" example="Zashi">%1$s</xliff:g> Delete <xliff:g id="app_name" example="Zashi">%1$s</xliff:g>
</string> </string>
@ -23,5 +20,4 @@
</string> </string>
<string name="delete_wallet_failed">Wallet deletion failed. Try it again, please.</string> <string name="delete_wallet_failed">Wallet deletion failed. Try it again, please.</string>
</resources> </resources>

View File

@ -9,8 +9,6 @@
funds, only the ability to see what you do with your funds.</string> funds, only the ability to see what you do with your funds.</string>
<string name="export_data_confirm">Export private data</string> <string name="export_data_confirm">Export private data</string>
<string name="export_data_agree">I agree</string> <string name="export_data_agree">I agree</string>
<string name="export_data_back">Back</string>
<string name="export_data_back_content_description">Back</string>
<string name="export_data_export_data_chooser_title">Share internal Zashi data with:</string> <string name="export_data_export_data_chooser_title">Share internal Zashi data with:</string>
<string name="export_data_unable_to_share">Unable to find an application to share with.</string> <string name="export_data_unable_to_share">Unable to find an application to share with.</string>
</resources> </resources>

View File

@ -1,6 +1,4 @@
<resources> <resources>
<string name="restore_back">Back</string>
<string name="restore_back_content_description">Back</string>
<string name="restore_button_clear">Clear Seed</string> <string name="restore_button_clear">Clear Seed</string>
<string name="restore_title">Enter secret recovery phrase</string> <string name="restore_title">Enter secret recovery phrase</string>
@ -14,5 +12,4 @@
<string name="restore_birthday_header">Wallet birthday height</string> <string name="restore_birthday_header">Wallet birthday height</string>
<string name="restore_birthday_sub_header">(optional)</string> <string name="restore_birthday_sub_header">(optional)</string>
<string name="restore_birthday_button_restore">Restore</string> <string name="restore_birthday_button_restore">Restore</string>
</resources> </resources>

View File

@ -1,6 +1,4 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="scan_back">Back</string>
<string name="scan_back_content_description">Back</string>
<string name="scan_preview_content_description">Camera</string> <string name="scan_preview_content_description">Camera</string>
<string name="scan_cancel_button">Cancel</string> <string name="scan_cancel_button">Cancel</string>

View File

@ -1,7 +1,5 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="security_warning_header">Security warning:</string> <string name="security_warning_header">Security warning:</string>
<string name="security_warning_back">Back</string>
<string name="security_warning_back_content_description">Back</string>
<string name="security_warning_text" formatted="true">Zashi <xliff:g example="0.2.0" id="version_name">%1$s <string name="security_warning_text" formatted="true">Zashi <xliff:g example="0.2.0" id="version_name">%1$s
</xliff:g>is a Zcash-only, shielded wallet — built by Zcashers for Zcashers. Zashi has been engineered for your </xliff:g>is a Zcash-only, shielded wallet — built by Zcashers for Zcashers. Zashi has been engineered for your

View File

@ -1,6 +1,4 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="seed_recovery_back">Back</string>
<string name="seed_recovery_back_content_description">Back</string>
<string name="seed_recovery_header">Your secret recovery phrase</string> <string name="seed_recovery_header">Your secret recovery phrase</string>
<string name="seed_recovery_description">The following 24 words are the keys to your funds and are the only way to <string name="seed_recovery_description">The following 24 words are the keys to your funds and are the only way to
recover your funds if you get locked out or get a new device. Protect your ZEC by storing this phrase in a recover your funds if you get locked out or get a new device. Protect your ZEC by storing this phrase in a

View File

@ -13,8 +13,6 @@
<string name="send_confirmation_dialog_error_btn">OK</string> <string name="send_confirmation_dialog_error_btn">OK</string>
<string name="send_confirmation_multiple_error_title">Transaction error</string> <string name="send_confirmation_multiple_error_title">Transaction error</string>
<string name="send_confirmation_multiple_error_back">Back</string>
<string name="send_confirmation_multiple_error_back_content_description">Back</string>
<string name="send_confirmation_multiple_error_text_1">Sending to this recipient required multiple transactions, <string name="send_confirmation_multiple_error_text_1">Sending to this recipient required multiple transactions,
but only some of them succeeded. Your funds are safe, but they need to be recovered with the help of Zashi but only some of them succeeded. Your funds are safe, but they need to be recovered with the help of Zashi
team support.</string> team support.</string>

View File

@ -1,7 +1,4 @@
<resources> <resources>
<string name="settings_back">Back</string>
<string name="settings_back_content_description">Back</string>
<string name="settings_troubleshooting_menu_content_description">Additional settings</string> <string name="settings_troubleshooting_menu_content_description">Additional settings</string>
<string name="settings_troubleshooting_rescan">Rescan blockchain</string> <string name="settings_troubleshooting_rescan">Rescan blockchain</string>
<string name="settings_troubleshooting_enable_background_sync">Background sync</string> <string name="settings_troubleshooting_enable_background_sync">Background sync</string>
@ -11,5 +8,4 @@
<string name="settings_send_us_feedback">Send us feedback</string> <string name="settings_send_us_feedback">Send us feedback</string>
<string name="settings_advanced_settings">Advanced</string> <string name="settings_advanced_settings">Advanced</string>
<string name="settings_about">About</string> <string name="settings_about">About</string>
</resources> </resources>

View File

@ -1,7 +1,5 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="support_header">Support</string> <string name="support_header">Support</string>
<string name="support_back">Back</string>
<string name="support_back_content_description">Back</string>
<string name="support_hint">How can we help?</string> <string name="support_hint">How can we help?</string>
<string name="support_send">Send</string> <string name="support_send">Send</string>