[#1264] Handle unavailable AccountBalance

- Closes #1264
- Changelog update
This commit is contained in:
Honza Rychnovský 2024-04-08 12:59:03 +02:00 committed by GitHub
parent b34d086cc0
commit bca1c32b8c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 219 additions and 84 deletions

View File

@ -29,6 +29,8 @@ directly impact users rather than highlighting other key architectural updates.*
screen) screen)
- The sending and shielding funds logic has been connected to the new Proposal API from the Zcash SDK - The sending and shielding funds logic has been connected to the new Proposal API from the Zcash SDK
- The error dialog contains an error description now. It's useful for tracking down the failure cause. - The error dialog contains an error description now. It's useful for tracking down the failure cause.
- A small circular progress indicator is displayed when the app runs block synchronization, and the available balance
is zero instead of reflecting a result value.
### Fixed ### Fixed
- Button sizing has been updated to align with the design guidelines and preserve stretching if necessary - Button sizing has been updated to align with the design guidelines and preserve stretching if necessary

View File

@ -11,6 +11,7 @@ import androidx.compose.material3.LinearProgressIndicator
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.Color
import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -60,9 +61,12 @@ fun CircularMidProgressIndicator(modifier: Modifier = Modifier) {
} }
@Composable @Composable
fun CircularSmallProgressIndicator(modifier: Modifier = Modifier) { fun CircularSmallProgressIndicator(
modifier: Modifier = Modifier,
color: Color = ZcashTheme.colors.circularProgressBarSmall,
) {
CircularProgressIndicator( CircularProgressIndicator(
color = ZcashTheme.colors.circularProgressBarSmall, color = color,
strokeWidth = 2.dp, strokeWidth = 2.dp,
modifier = modifier =
Modifier Modifier

View File

@ -12,6 +12,7 @@ data class Dimens(
// Default spacings: // Default spacings:
val spacingNone: Dp, val spacingNone: Dp,
val spacingXtiny: Dp, val spacingXtiny: Dp,
val spacingMin: Dp,
val spacingTiny: Dp, val spacingTiny: Dp,
val spacingSmall: Dp, val spacingSmall: Dp,
val spacingMid: Dp, val spacingMid: Dp,
@ -61,6 +62,7 @@ private val defaultDimens =
spacingNone = 0.dp, spacingNone = 0.dp,
spacingXtiny = 2.dp, spacingXtiny = 2.dp,
spacingTiny = 4.dp, spacingTiny = 4.dp,
spacingMin = 6.dp,
spacingSmall = 8.dp, spacingSmall = 8.dp,
spacingMid = 12.dp, spacingMid = 12.dp,
spacingDefault = 16.dp, spacingDefault = 16.dp,

View File

@ -15,6 +15,7 @@ data class ExtendedColors(
val callout: Color, val callout: Color,
val onCallout: Color, val onCallout: Color,
val circularProgressBarSmall: Color, val circularProgressBarSmall: Color,
val circularProgressBarSmallDark: Color,
val circularProgressBarScreen: Color, val circularProgressBarScreen: Color,
val linearProgressBarTrack: Color, val linearProgressBarTrack: Color,
val linearProgressBarBackground: Color, val linearProgressBarBackground: Color,

View File

@ -51,9 +51,10 @@ internal object Dark {
val radioButtonTextColor = Color(0xFF4E4E4E) val radioButtonTextColor = Color(0xFF4E4E4E)
val circularProgressBarSmall = Color(0xFF8B8A8A) val circularProgressBarSmall = Color(0xFF8B8A8A)
val circularProgressBarSmallDark = textBodyOnBackground
val circularProgressBarScreen = Color(0xFFFFFFFF) val circularProgressBarScreen = Color(0xFFFFFFFF)
val linearProgressBarTrack = Color(0xFFD9D9D9) val linearProgressBarTrack = Color(0xFFD9D9D9)
val linearProgressBarBackground = Light.complementaryColor val linearProgressBarBackground = complementaryColor
val restoringTopAppBarColor = Color(0xFF8A8888) val restoringTopAppBarColor = Color(0xFF8A8888)
val callout = Color(0xFFFFFFFF) val callout = Color(0xFFFFFFFF)
@ -111,6 +112,7 @@ internal object Light {
val circularProgressBarSmall = Color(0xFF8B8A8A) val circularProgressBarSmall = Color(0xFF8B8A8A)
val circularProgressBarScreen = Color(0xFF000000) val circularProgressBarScreen = Color(0xFF000000)
val circularProgressBarSmallDark = textBodyOnBackground
val linearProgressBarTrack = Color(0xFFD9D9D9) val linearProgressBarTrack = Color(0xFFD9D9D9)
val linearProgressBarBackground = complementaryColor val linearProgressBarBackground = complementaryColor
val restoringTopAppBarColor = Color(0xFF8A8888) val restoringTopAppBarColor = Color(0xFF8A8888)
@ -164,6 +166,7 @@ internal val DarkExtendedColorPalette =
callout = Dark.callout, callout = Dark.callout,
onCallout = Dark.onCallout, onCallout = Dark.onCallout,
circularProgressBarSmall = Dark.circularProgressBarSmall, circularProgressBarSmall = Dark.circularProgressBarSmall,
circularProgressBarSmallDark = Dark.circularProgressBarSmallDark,
circularProgressBarScreen = Dark.circularProgressBarScreen, circularProgressBarScreen = Dark.circularProgressBarScreen,
linearProgressBarTrack = Dark.linearProgressBarTrack, linearProgressBarTrack = Dark.linearProgressBarTrack,
linearProgressBarBackground = Dark.linearProgressBarBackground, linearProgressBarBackground = Dark.linearProgressBarBackground,
@ -208,12 +211,13 @@ internal val LightExtendedColorPalette =
onCallout = Light.onCallout, onCallout = Light.onCallout,
circularProgressBarScreen = Light.circularProgressBarScreen, circularProgressBarScreen = Light.circularProgressBarScreen,
circularProgressBarSmall = Light.circularProgressBarSmall, circularProgressBarSmall = Light.circularProgressBarSmall,
circularProgressBarSmallDark = Light.circularProgressBarSmallDark,
linearProgressBarTrack = Light.linearProgressBarTrack, linearProgressBarTrack = Light.linearProgressBarTrack,
linearProgressBarBackground = Light.linearProgressBarBackground, linearProgressBarBackground = Light.linearProgressBarBackground,
restoringTopAppBarColor = Light.restoringTopAppBarColor, restoringTopAppBarColor = Light.restoringTopAppBarColor,
chipIndex = Light.textChipIndex, chipIndex = Light.textChipIndex,
textCommon = Light.textCommon, textCommon = Light.textCommon,
textMedium = Dark.textMedium, textMedium = Light.textMedium,
textDisabled = Light.textDisabled, textDisabled = Light.textDisabled,
textFieldFrame = Light.textFieldFrame, textFieldFrame = Light.textFieldFrame,
textFieldError = Light.textFieldError, textFieldError = Light.textFieldError,
@ -253,6 +257,7 @@ internal val LocalExtendedColors =
onCallout = Color.Unspecified, onCallout = Color.Unspecified,
circularProgressBarScreen = Color.Unspecified, circularProgressBarScreen = Color.Unspecified,
circularProgressBarSmall = Color.Unspecified, circularProgressBarSmall = Color.Unspecified,
circularProgressBarSmallDark = Color.Unspecified,
linearProgressBarTrack = Color.Unspecified, linearProgressBarTrack = Color.Unspecified,
linearProgressBarBackground = Color.Unspecified, linearProgressBarBackground = Color.Unspecified,
restoringTopAppBarColor = Color.Unspecified, restoringTopAppBarColor = Color.Unspecified,

View File

@ -5,6 +5,7 @@ import androidx.compose.ui.test.junit4.ComposeContentTestRule
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.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.BalanceStateFixture
import co.electriccoin.zcash.ui.screen.account.history.fixture.TransactionHistoryUiStateFixture import co.electriccoin.zcash.ui.screen.account.history.fixture.TransactionHistoryUiStateFixture
import co.electriccoin.zcash.ui.screen.account.model.TransactionUiState import co.electriccoin.zcash.ui.screen.account.model.TransactionUiState
import co.electriccoin.zcash.ui.screen.account.view.Account import co.electriccoin.zcash.ui.screen.account.view.Account
@ -59,6 +60,7 @@ class AccountTestSetup(
@Suppress("TestFunctionName") @Suppress("TestFunctionName")
fun DefaultContent() { fun DefaultContent() {
Account( Account(
balanceState = BalanceStateFixture.new(),
goSettings = { goSettings = {
onSettingsCount.incrementAndGet() onSettingsCount.incrementAndGet()
}, },
@ -67,7 +69,6 @@ class AccountTestSetup(
onTransactionItemAction = { onTransactionItemAction = {
onItemClickCount.incrementAndGet() onItemClickCount.incrementAndGet()
}, },
walletSnapshot = walletSnapshot,
walletRestoringState = WalletRestoringState.NONE, walletRestoringState = WalletRestoringState.NONE,
) )
} }

View File

@ -5,6 +5,7 @@ import androidx.compose.ui.test.junit4.ComposeContentTestRule
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.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.BalanceStateFixture
import co.electriccoin.zcash.ui.screen.balances.model.ShieldState import co.electriccoin.zcash.ui.screen.balances.model.ShieldState
import co.electriccoin.zcash.ui.screen.balances.view.Balances import co.electriccoin.zcash.ui.screen.balances.view.Balances
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
@ -30,6 +31,7 @@ class BalancesTestSetup(
@Suppress("TestFunctionName") @Suppress("TestFunctionName")
fun DefaultContent() { fun DefaultContent() {
Balances( Balances(
balanceState = BalanceStateFixture.new(),
onSettings = { onSettings = {
onSettingsCount.incrementAndGet() onSettingsCount.incrementAndGet()
}, },
@ -40,7 +42,7 @@ class BalancesTestSetup(
onShielding = {}, onShielding = {},
shieldState = ShieldState.Available, shieldState = ShieldState.Available,
walletSnapshot = walletSnapshot, walletSnapshot = walletSnapshot,
walletRestoringState = WalletRestoringState.NONE walletRestoringState = WalletRestoringState.NONE,
) )
} }

View File

@ -14,6 +14,7 @@ import cash.z.ecc.android.sdk.model.ZecSend
import cash.z.ecc.android.sdk.type.AddressType import cash.z.ecc.android.sdk.type.AddressType
import co.electriccoin.zcash.ui.common.model.WalletRestoringState import co.electriccoin.zcash.ui.common.model.WalletRestoringState
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.WalletSnapshotFixture import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
import co.electriccoin.zcash.ui.screen.send.ext.Saver import co.electriccoin.zcash.ui.screen.send.ext.Saver
import co.electriccoin.zcash.ui.screen.send.model.AmountState import co.electriccoin.zcash.ui.screen.send.model.AmountState
@ -109,13 +110,7 @@ class SendViewTestSetup(
// TODO [#1260]: Cover Send.Form screen UI with tests // TODO [#1260]: Cover Send.Form screen UI with tests
// TODO [#1260]: https://github.com/Electric-Coin-Company/zashi-android/issues/1260 // TODO [#1260]: https://github.com/Electric-Coin-Company/zashi-android/issues/1260
Send( Send(
walletSnapshot = balanceState = BalanceStateFixture.new(),
WalletSnapshotFixture.new(
saplingBalance =
WalletBalanceFixture.new(
available = Zatoshi(Zatoshi.MAX_INCLUSIVE.div(100))
)
),
sendStage = sendStage, sendStage = sendStage,
onCreateZecSend = setZecSend, onCreateZecSend = setZecSend,
focusManager = LocalFocusManager.current, focusManager = LocalFocusManager.current,
@ -134,11 +129,18 @@ class SendViewTestSetup(
// TODO [#1260]: Cover Send.Form screen UI with tests // TODO [#1260]: Cover Send.Form screen UI with tests
// TODO [#1260]: https://github.com/Electric-Coin-Company/zashi-android/issues/1260 // TODO [#1260]: https://github.com/Electric-Coin-Company/zashi-android/issues/1260
}, },
amountState = AmountState.new(context, "", monetarySeparators),
setAmountState = {}, setAmountState = {},
memoState = MemoState.new(""), amountState = AmountState.new(context, "", monetarySeparators),
setMemoState = {}, setMemoState = {},
walletRestoringState = WalletRestoringState.NONE memoState = MemoState.new(""),
walletRestoringState = WalletRestoringState.NONE,
walletSnapshot =
WalletSnapshotFixture.new(
saplingBalance =
WalletBalanceFixture.new(
available = Zatoshi(Zatoshi.MAX_INCLUSIVE.div(100))
)
),
) )
} }
} }

View File

@ -12,6 +12,7 @@ import cash.z.ecc.android.sdk.model.Zatoshi
import cash.z.ecc.android.sdk.model.ZcashNetwork import cash.z.ecc.android.sdk.model.ZcashNetwork
import cash.z.ecc.sdk.fixture.ZecSendFixture import cash.z.ecc.sdk.fixture.ZecSendFixture
import co.electriccoin.zcash.ui.common.model.WalletRestoringState import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.fixture.BalanceStateFixture
import co.electriccoin.zcash.ui.fixture.MockSynchronizer import co.electriccoin.zcash.ui.fixture.MockSynchronizer
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
import co.electriccoin.zcash.ui.screen.send.WrapSend import co.electriccoin.zcash.ui.screen.send.WrapSend
@ -68,18 +69,19 @@ class SendViewIntegrationTest {
restorationTester.setContent { restorationTester.setContent {
WrapSend( WrapSend(
balanceState = BalanceStateFixture.new(),
sendArguments = null, sendArguments = null,
focusManager = LocalFocusManager.current,
synchronizer = synchronizer, synchronizer = synchronizer,
walletSnapshot = walletSnapshot, walletSnapshot = walletSnapshot,
spendingKey = spendingKey, spendingKey = spendingKey,
focusManager = LocalFocusManager.current,
goToQrScanner = {}, goToQrScanner = {},
goBack = {}, goBack = {},
goBalances = {}, goBalances = {},
hasCameraFeature = true,
goSettings = {}, goSettings = {},
monetarySeparators = monetarySeparators,
goSendConfirmation = {}, goSendConfirmation = {},
hasCameraFeature = true,
monetarySeparators = monetarySeparators,
walletRestoringState = WalletRestoringState.NONE, walletRestoringState = WalletRestoringState.NONE,
) )
} }

View File

@ -1,5 +1,6 @@
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
@ -17,20 +18,16 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Devices import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import cash.z.ecc.android.sdk.model.WalletBalance
import cash.z.ecc.android.sdk.model.Zatoshi import cash.z.ecc.android.sdk.model.Zatoshi
import cash.z.ecc.android.sdk.model.toZecString import cash.z.ecc.android.sdk.model.toZecString
import cash.z.ecc.sdk.type.ZcashCurrency import cash.z.ecc.sdk.type.ZcashCurrency
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
import co.electriccoin.zcash.ui.common.model.spendableBalance
import co.electriccoin.zcash.ui.common.model.totalBalance
import co.electriccoin.zcash.ui.design.R import co.electriccoin.zcash.ui.design.R
import co.electriccoin.zcash.ui.design.component.Body import co.electriccoin.zcash.ui.design.component.Body
import co.electriccoin.zcash.ui.design.component.CircularSmallProgressIndicator
import co.electriccoin.zcash.ui.design.component.GradientSurface import co.electriccoin.zcash.ui.design.component.GradientSurface
import co.electriccoin.zcash.ui.design.component.Reference import co.electriccoin.zcash.ui.design.component.Reference
import co.electriccoin.zcash.ui.design.component.StyledBalance import co.electriccoin.zcash.ui.design.component.StyledBalance
import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
@Preview(device = Devices.PIXEL_2) @Preview(device = Devices.PIXEL_2)
@Composable @Composable
@ -42,14 +39,10 @@ private fun BalanceWidgetPreview() {
@Suppress("MagicNumber") @Suppress("MagicNumber")
( (
BalanceWidget( BalanceWidget(
walletSnapshot = balanceState =
WalletSnapshotFixture.new( BalanceState.Available(
saplingBalance = totalBalance = Zatoshi(1234567891234567L),
WalletBalance( spendableBalance = Zatoshi(1234567891234567L)
Zatoshi(1234567891234567),
Zatoshi(123456789),
Zatoshi(123)
)
), ),
isReferenceToBalances = true, isReferenceToBalances = true,
onReferenceClick = {}, onReferenceClick = {},
@ -60,9 +53,35 @@ private fun BalanceWidgetPreview() {
} }
} }
@Preview(device = Devices.PIXEL_2)
@Composable
private fun BalanceWidgetNotAvailableYetPreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface(
modifier = Modifier.fillMaxWidth()
) {
@Suppress("MagicNumber")
BalanceWidget(
balanceState = BalanceState.Loading(Zatoshi(0L)),
isReferenceToBalances = true,
onReferenceClick = {},
modifier = Modifier
)
}
}
}
sealed class BalanceState(open val totalBalance: Zatoshi) {
data object None : BalanceState(Zatoshi(0L))
data class Loading(override val totalBalance: Zatoshi) : BalanceState(totalBalance)
data class Available(override val totalBalance: Zatoshi, val spendableBalance: Zatoshi) : BalanceState(totalBalance)
}
@Composable @Composable
fun BalanceWidget( fun BalanceWidget(
walletSnapshot: WalletSnapshot, balanceState: BalanceState,
isReferenceToBalances: Boolean, isReferenceToBalances: Boolean,
onReferenceClick: () -> Unit, onReferenceClick: () -> Unit,
modifier: Modifier = Modifier modifier: Modifier = Modifier
@ -74,10 +93,11 @@ fun BalanceWidget(
.then(modifier), .then(modifier),
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
BalanceWidgetBigLineOnly(text = walletSnapshot.totalBalance().toZecString()) BalanceWidgetBigLineOnly(text = balanceState.totalBalance.toZecString())
Row( Row(
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.animateContentSize()
) { ) {
if (isReferenceToBalances) { if (isReferenceToBalances) {
Reference( Reference(
@ -94,16 +114,23 @@ fun BalanceWidget(
Spacer(modifier = Modifier.width(ZcashTheme.dimens.spacingTiny)) Spacer(modifier = Modifier.width(ZcashTheme.dimens.spacingTiny))
StyledBalance( when (balanceState) {
balanceString = walletSnapshot.spendableBalance().toZecString(), BalanceState.None, is BalanceState.Loading -> {
textStyles = CircularSmallProgressIndicator(color = ZcashTheme.colors.circularProgressBarSmallDark)
Pair( }
ZcashTheme.extendedTypography.balanceWidgetStyles.third, is BalanceState.Available -> {
ZcashTheme.extendedTypography.balanceWidgetStyles.fourth StyledBalance(
balanceString = balanceState.spendableBalance.toZecString(),
textStyles =
Pair(
ZcashTheme.extendedTypography.balanceWidgetStyles.third,
ZcashTheme.extendedTypography.balanceWidgetStyles.fourth
)
) )
) }
}
Spacer(modifier = Modifier.width(ZcashTheme.dimens.spacingTiny)) Spacer(modifier = Modifier.width(ZcashTheme.dimens.spacingMin))
Body( Body(
text = ZcashCurrency.getLocalizedName(LocalContext.current), text = ZcashCurrency.getLocalizedName(LocalContext.current),

View File

@ -27,10 +27,13 @@ import co.electriccoin.lightwallet.client.model.LightWalletEndpoint
import co.electriccoin.zcash.global.getInstance import co.electriccoin.zcash.global.getInstance
import co.electriccoin.zcash.spackle.Twig import co.electriccoin.zcash.spackle.Twig
import co.electriccoin.zcash.ui.common.ANDROID_STATE_FLOW_TIMEOUT import co.electriccoin.zcash.ui.common.ANDROID_STATE_FLOW_TIMEOUT
import co.electriccoin.zcash.ui.common.compose.BalanceState
import co.electriccoin.zcash.ui.common.extension.throttle import co.electriccoin.zcash.ui.common.extension.throttle
import co.electriccoin.zcash.ui.common.model.OnboardingState import co.electriccoin.zcash.ui.common.model.OnboardingState
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.model.spendableBalance
import co.electriccoin.zcash.ui.common.model.totalBalance
import co.electriccoin.zcash.ui.preference.EncryptedPreferenceKeys import co.electriccoin.zcash.ui.preference.EncryptedPreferenceKeys
import co.electriccoin.zcash.ui.preference.EncryptedPreferenceSingleton import co.electriccoin.zcash.ui.preference.EncryptedPreferenceSingleton
import co.electriccoin.zcash.ui.preference.StandardPreferenceKeys import co.electriccoin.zcash.ui.preference.StandardPreferenceKeys
@ -238,6 +241,43 @@ class WalletViewModel(application: Application) : AndroidViewModel(application)
initialValue = TransactionHistorySyncState.Loading initialValue = TransactionHistorySyncState.Loading
) )
/**
* A flow of the wallet balances state used for the UI layer. It combines [WalletSnapshot] with
* [WalletRestoringState] and provides the correct [BalanceState] UI state.
*/
val balanceState: StateFlow<BalanceState> =
walletSnapshot
.filterNotNull()
.combine(walletRestoringState) {
walletSnapshot: WalletSnapshot, walletRestoringState: WalletRestoringState ->
when (walletRestoringState) {
WalletRestoringState.NONE -> BalanceState.None
WalletRestoringState.INITIATING ->
BalanceState.Available(
totalBalance = walletSnapshot.totalBalance(),
spendableBalance = walletSnapshot.spendableBalance()
)
WalletRestoringState.RESTORING, WalletRestoringState.SYNCING -> {
if (walletSnapshot.spendableBalance().value == 0L &&
walletSnapshot.totalBalance().value > 0L
) {
BalanceState.Loading(
totalBalance = walletSnapshot.totalBalance()
)
} else {
BalanceState.Available(
totalBalance = walletSnapshot.totalBalance(),
spendableBalance = walletSnapshot.spendableBalance()
)
}
}
}
}.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(ANDROID_STATE_FLOW_TIMEOUT),
BalanceState.None
)
/** /**
* Creates a wallet asynchronously and then persists it. Clients observe * Creates a wallet asynchronously and then persists it. Clients observe
* [secretState] to see the side effects. This would be used for a user creating a new wallet. * [secretState] to see the side effects. This would be used for a user creating a new wallet.

View File

@ -0,0 +1,19 @@
package co.electriccoin.zcash.ui.fixture
import cash.z.ecc.android.sdk.model.Zatoshi
import co.electriccoin.zcash.ui.common.compose.BalanceState
object BalanceStateFixture {
private const val BALANCE_VALUE = 0L
val TOTAL_BALANCE = Zatoshi(BALANCE_VALUE)
val SPENDABLE_BALANCE = Zatoshi(BALANCE_VALUE)
fun new(
totalBalance: Zatoshi = TOTAL_BALANCE,
spendableBalance: Zatoshi = SPENDABLE_BALANCE
) = BalanceState.Available(
totalBalance = totalBalance,
spendableBalance = spendableBalance
)
}

View File

@ -12,8 +12,8 @@ import cash.z.ecc.android.sdk.Synchronizer
import cash.z.ecc.android.sdk.internal.Twig import cash.z.ecc.android.sdk.internal.Twig
import co.electriccoin.zcash.spackle.ClipboardManagerUtil import co.electriccoin.zcash.spackle.ClipboardManagerUtil
import co.electriccoin.zcash.ui.R import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.common.compose.BalanceState
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.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
@ -36,8 +36,6 @@ internal fun WrapAccount(
val transactionHistoryViewModel by activity.viewModels<TransactionHistoryViewModel>() val transactionHistoryViewModel by activity.viewModels<TransactionHistoryViewModel>()
val walletSnapshot = walletViewModel.walletSnapshot.collectAsStateWithLifecycle().value
val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value val synchronizer = walletViewModel.synchronizer.collectAsStateWithLifecycle().value
val transactionsUiState = transactionHistoryViewModel.transactionUiState.collectAsStateWithLifecycle().value val transactionsUiState = transactionHistoryViewModel.transactionUiState.collectAsStateWithLifecycle().value
@ -48,7 +46,10 @@ internal fun WrapAccount(
val walletRestoringState = walletViewModel.walletRestoringState.collectAsStateWithLifecycle().value val walletRestoringState = walletViewModel.walletRestoringState.collectAsStateWithLifecycle().value
val balanceState = walletViewModel.balanceState.collectAsStateWithLifecycle().value
WrapAccount( WrapAccount(
balanceState = balanceState,
context = activity.applicationContext, context = activity.applicationContext,
goBalances = goBalances, goBalances = goBalances,
goSettings = goSettings, goSettings = goSettings,
@ -56,7 +57,6 @@ internal fun WrapAccount(
synchronizer = synchronizer, synchronizer = synchronizer,
transactionHistoryViewModel = transactionHistoryViewModel, transactionHistoryViewModel = transactionHistoryViewModel,
transactionsUiState = transactionsUiState, transactionsUiState = transactionsUiState,
walletSnapshot = walletSnapshot,
walletRestoringState = walletRestoringState walletRestoringState = walletRestoringState
) )
@ -68,6 +68,7 @@ internal fun WrapAccount(
@VisibleForTesting @VisibleForTesting
@Suppress("LongParameterList") @Suppress("LongParameterList")
internal fun WrapAccount( internal fun WrapAccount(
balanceState: BalanceState,
context: Context, context: Context,
scope: CoroutineScope, scope: CoroutineScope,
goBalances: () -> Unit, goBalances: () -> Unit,
@ -75,17 +76,16 @@ internal fun WrapAccount(
transactionsUiState: TransactionUiState, transactionsUiState: TransactionUiState,
synchronizer: Synchronizer?, synchronizer: Synchronizer?,
transactionHistoryViewModel: TransactionHistoryViewModel, transactionHistoryViewModel: TransactionHistoryViewModel,
walletSnapshot: WalletSnapshot?,
walletRestoringState: WalletRestoringState, walletRestoringState: WalletRestoringState,
) { ) {
if (null == synchronizer || null == walletSnapshot) { if (null == synchronizer) {
// TODO [#1146]: Consider moving CircularScreenProgressIndicator from Android layer to View layer // TODO [#1146]: Consider moving CircularScreenProgressIndicator from Android layer to View layer
// TODO [#1146]: Improve this by allowing screen composition and updating it after the data is available // TODO [#1146]: Improve this by allowing screen composition and updating it after the data is available
// TODO [#1146]: https://github.com/Electric-Coin-Company/zashi-android/issues/1146 // TODO [#1146]: https://github.com/Electric-Coin-Company/zashi-android/issues/1146
CircularScreenProgressIndicator() CircularScreenProgressIndicator()
} else { } else {
Account( Account(
walletSnapshot = walletSnapshot, balanceState = balanceState,
transactionsUiState = transactionsUiState, transactionsUiState = transactionsUiState,
onTransactionItemAction = { action -> onTransactionItemAction = { action ->
when (action) { when (action) {

View File

@ -15,15 +15,16 @@ 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.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import cash.z.ecc.android.sdk.model.Zatoshi
import co.electriccoin.zcash.ui.R import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.common.compose.BalanceState
import co.electriccoin.zcash.ui.common.compose.BalanceWidget import co.electriccoin.zcash.ui.common.compose.BalanceWidget
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.test.CommonTag import co.electriccoin.zcash.ui.common.test.CommonTag
import co.electriccoin.zcash.ui.design.component.GradientSurface import co.electriccoin.zcash.ui.design.component.GradientSurface
import co.electriccoin.zcash.ui.design.component.SmallTopAppBar import co.electriccoin.zcash.ui.design.component.SmallTopAppBar
import co.electriccoin.zcash.ui.design.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture import co.electriccoin.zcash.ui.fixture.BalanceStateFixture
import co.electriccoin.zcash.ui.screen.account.AccountTag import co.electriccoin.zcash.ui.screen.account.AccountTag
import co.electriccoin.zcash.ui.screen.account.fixture.TransactionsFixture import co.electriccoin.zcash.ui.screen.account.fixture.TransactionsFixture
import co.electriccoin.zcash.ui.screen.account.model.TransactionUiState import co.electriccoin.zcash.ui.screen.account.model.TransactionUiState
@ -34,12 +35,12 @@ private fun HistoryLoadingComposablePreview() {
ZcashTheme(forceDarkMode = false) { ZcashTheme(forceDarkMode = false) {
GradientSurface { GradientSurface {
Account( Account(
walletSnapshot = WalletSnapshotFixture.new(),
goBalances = {}, goBalances = {},
goSettings = {}, goSettings = {},
transactionsUiState = TransactionUiState.Loading,
onTransactionItemAction = {}, onTransactionItemAction = {},
walletRestoringState = WalletRestoringState.SYNCING transactionsUiState = TransactionUiState.Loading,
walletRestoringState = WalletRestoringState.SYNCING,
balanceState = BalanceStateFixture.new()
) )
} }
} }
@ -52,12 +53,12 @@ private fun HistoryListComposablePreview() {
GradientSurface { GradientSurface {
@Suppress("MagicNumber") @Suppress("MagicNumber")
Account( Account(
walletSnapshot = WalletSnapshotFixture.new(),
goBalances = {}, goBalances = {},
goSettings = {}, goSettings = {},
transactionsUiState = TransactionUiState.Done(transactions = TransactionsFixture.new()),
onTransactionItemAction = {}, onTransactionItemAction = {},
walletRestoringState = WalletRestoringState.NONE transactionsUiState = TransactionUiState.Done(transactions = TransactionsFixture.new()),
walletRestoringState = WalletRestoringState.NONE,
balanceState = BalanceState.Available(Zatoshi(123_000_000L), Zatoshi(123_000_000L))
) )
} }
} }
@ -66,12 +67,12 @@ private fun HistoryListComposablePreview() {
@Composable @Composable
@Suppress("LongParameterList") @Suppress("LongParameterList")
internal fun Account( internal fun Account(
balanceState: BalanceState,
goBalances: () -> Unit, goBalances: () -> Unit,
goSettings: () -> Unit, goSettings: () -> Unit,
onTransactionItemAction: (TrxItemAction) -> Unit, onTransactionItemAction: (TrxItemAction) -> Unit,
transactionsUiState: TransactionUiState, transactionsUiState: TransactionUiState,
walletRestoringState: WalletRestoringState, walletRestoringState: WalletRestoringState,
walletSnapshot: WalletSnapshot,
) { ) {
Scaffold(topBar = { Scaffold(topBar = {
AccountTopAppBar( AccountTopAppBar(
@ -80,7 +81,7 @@ internal fun Account(
) )
}) { paddingValues -> }) { paddingValues ->
AccountMainContent( AccountMainContent(
walletSnapshot = walletSnapshot, balanceState = balanceState,
goBalances = goBalances, goBalances = goBalances,
transactionState = transactionsUiState, transactionState = transactionsUiState,
walletRestoringState = walletRestoringState, walletRestoringState = walletRestoringState,
@ -125,7 +126,7 @@ private fun AccountTopAppBar(
@Composable @Composable
@Suppress("LongParameterList") @Suppress("LongParameterList")
private fun AccountMainContent( private fun AccountMainContent(
walletSnapshot: WalletSnapshot, balanceState: BalanceState,
goBalances: () -> Unit, goBalances: () -> Unit,
onTransactionItemAction: (TrxItemAction) -> Unit, onTransactionItemAction: (TrxItemAction) -> Unit,
transactionState: TransactionUiState, transactionState: TransactionUiState,
@ -139,7 +140,7 @@ private fun AccountMainContent(
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingSmall)) Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingSmall))
BalancesStatus( BalancesStatus(
walletSnapshot = walletSnapshot, balanceState = balanceState,
goBalances = goBalances, goBalances = goBalances,
modifier = modifier =
Modifier Modifier
@ -158,9 +159,9 @@ private fun AccountMainContent(
@Composable @Composable
private fun BalancesStatus( private fun BalancesStatus(
walletSnapshot: WalletSnapshot, balanceState: BalanceState,
goBalances: () -> Unit, goBalances: () -> Unit,
modifier: Modifier = Modifier modifier: Modifier = Modifier,
) { ) {
Column( Column(
modifier = modifier =
@ -172,7 +173,7 @@ private fun BalancesStatus(
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
BalanceWidget( BalanceWidget(
walletSnapshot = walletSnapshot, balanceState = balanceState,
isReferenceToBalances = true, isReferenceToBalances = true,
onReferenceClick = goBalances onReferenceClick = goBalances
) )

View File

@ -16,6 +16,7 @@ import cash.z.ecc.android.sdk.model.UnifiedSpendingKey
import cash.z.ecc.android.sdk.model.Zatoshi import cash.z.ecc.android.sdk.model.Zatoshi
import co.electriccoin.zcash.spackle.Twig import co.electriccoin.zcash.spackle.Twig
import co.electriccoin.zcash.ui.R import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.common.compose.BalanceState
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
@ -58,7 +59,10 @@ internal fun WrapBalances(
) )
} }
val balanceState = walletViewModel.balanceState.collectAsStateWithLifecycle().value
WrapBalances( WrapBalances(
balanceState = balanceState,
checkUpdateViewModel = checkUpdateViewModel, checkUpdateViewModel = checkUpdateViewModel,
createTransactionsViewModel = createTransactionsViewModel, createTransactionsViewModel = createTransactionsViewModel,
goSettings = goSettings, goSettings = goSettings,
@ -76,6 +80,7 @@ const val DEFAULT_SHIELDING_THRESHOLD = 100000L
@VisibleForTesting @VisibleForTesting
@Suppress("LongParameterList", "LongMethod") @Suppress("LongParameterList", "LongMethod")
internal fun WrapBalances( internal fun WrapBalances(
balanceState: BalanceState,
checkUpdateViewModel: CheckUpdateViewModel, checkUpdateViewModel: CheckUpdateViewModel,
createTransactionsViewModel: CreateTransactionsViewModel, createTransactionsViewModel: CreateTransactionsViewModel,
goSettings: () -> Unit, goSettings: () -> Unit,
@ -123,6 +128,7 @@ internal fun WrapBalances(
CircularScreenProgressIndicator() CircularScreenProgressIndicator()
} else { } else {
Balances( Balances(
balanceState = balanceState,
onSettings = goSettings, onSettings = goSettings,
isFiatConversionEnabled = isFiatConversionEnabled, isFiatConversionEnabled = isFiatConversionEnabled,
isUpdateAvailable = isUpdateAvailable, isUpdateAvailable = isUpdateAvailable,

View File

@ -52,6 +52,7 @@ import cash.z.ecc.android.sdk.model.Zatoshi
import cash.z.ecc.android.sdk.model.toZecString import cash.z.ecc.android.sdk.model.toZecString
import cash.z.ecc.sdk.extension.toPercentageWithDecimal import cash.z.ecc.sdk.extension.toPercentageWithDecimal
import co.electriccoin.zcash.ui.R import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.common.compose.BalanceState
import co.electriccoin.zcash.ui.common.compose.BalanceWidget import co.electriccoin.zcash.ui.common.compose.BalanceWidget
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
@ -72,6 +73,7 @@ import co.electriccoin.zcash.ui.design.component.Reference
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.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.BalanceStateFixture
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
import co.electriccoin.zcash.ui.screen.balances.BalancesTag import co.electriccoin.zcash.ui.screen.balances.BalancesTag
import co.electriccoin.zcash.ui.screen.balances.model.ShieldState import co.electriccoin.zcash.ui.screen.balances.model.ShieldState
@ -92,6 +94,7 @@ private fun ComposableBalancesPreview() {
shieldState = ShieldState.Available, shieldState = ShieldState.Available,
walletSnapshot = WalletSnapshotFixture.new(), walletSnapshot = WalletSnapshotFixture.new(),
walletRestoringState = WalletRestoringState.NONE, walletRestoringState = WalletRestoringState.NONE,
balanceState = BalanceStateFixture.new()
) )
} }
} }
@ -112,6 +115,7 @@ private fun ComposableBalancesShieldFailurePreview() {
shieldState = ShieldState.Available, shieldState = ShieldState.Available,
walletSnapshot = WalletSnapshotFixture.new(), walletSnapshot = WalletSnapshotFixture.new(),
walletRestoringState = WalletRestoringState.NONE, walletRestoringState = WalletRestoringState.NONE,
balanceState = BalanceStateFixture.new()
) )
} }
} }
@ -129,6 +133,7 @@ fun Balances(
shieldState: ShieldState, shieldState: ShieldState,
walletSnapshot: WalletSnapshot?, walletSnapshot: WalletSnapshot?,
walletRestoringState: WalletRestoringState, walletRestoringState: WalletRestoringState,
balanceState: BalanceState,
) { ) {
Scaffold(topBar = { Scaffold(topBar = {
BalancesTopAppBar( BalancesTopAppBar(
@ -140,6 +145,7 @@ fun Balances(
CircularScreenProgressIndicator() CircularScreenProgressIndicator()
} else { } else {
BalancesMainContent( BalancesMainContent(
balanceState = balanceState,
isFiatConversionEnabled = isFiatConversionEnabled, isFiatConversionEnabled = isFiatConversionEnabled,
isUpdateAvailable = isUpdateAvailable, isUpdateAvailable = isUpdateAvailable,
onShielding = onShielding, onShielding = onShielding,
@ -228,6 +234,7 @@ private fun BalancesTopAppBar(
@Suppress("LongParameterList") @Suppress("LongParameterList")
@Composable @Composable
private fun BalancesMainContent( private fun BalancesMainContent(
balanceState: BalanceState,
isFiatConversionEnabled: Boolean, isFiatConversionEnabled: Boolean,
isUpdateAvailable: Boolean, isUpdateAvailable: Boolean,
onShielding: () -> Unit, onShielding: () -> Unit,
@ -246,7 +253,7 @@ private fun BalancesMainContent(
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingSmall)) Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingSmall))
BalanceWidget( BalanceWidget(
walletSnapshot = walletSnapshot, balanceState = balanceState,
isReferenceToBalances = false, isReferenceToBalances = false,
onReferenceClick = {} onReferenceClick = {}
) )

View File

@ -22,6 +22,7 @@ import cash.z.ecc.android.sdk.model.ZecSend
import cash.z.ecc.android.sdk.model.proposeSend import cash.z.ecc.android.sdk.model.proposeSend
import cash.z.ecc.android.sdk.model.toZecString import cash.z.ecc.android.sdk.model.toZecString
import co.electriccoin.zcash.spackle.Twig import co.electriccoin.zcash.spackle.Twig
import co.electriccoin.zcash.ui.common.compose.BalanceState
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.HomeViewModel
@ -74,20 +75,23 @@ internal fun WrapSend(
val walletRestoringState = walletViewModel.walletRestoringState.collectAsStateWithLifecycle().value val walletRestoringState = walletViewModel.walletRestoringState.collectAsStateWithLifecycle().value
val balanceState = walletViewModel.balanceState.collectAsStateWithLifecycle().value
WrapSend( WrapSend(
sendArguments, balanceState = balanceState,
synchronizer, sendArguments = sendArguments,
walletSnapshot, synchronizer = synchronizer,
spendingKey, walletSnapshot = walletSnapshot,
focusManager, spendingKey = spendingKey,
goToQrScanner, focusManager = focusManager,
goBack, goToQrScanner = goToQrScanner,
goBalances, goBack = goBack,
goSettings, goBalances = goBalances,
goSendConfirmation, goSettings = goSettings,
hasCameraFeature, goSendConfirmation = goSendConfirmation,
monetarySeparators, hasCameraFeature = hasCameraFeature,
walletRestoringState monetarySeparators = monetarySeparators,
walletRestoringState = walletRestoringState
) )
} }
@ -95,6 +99,7 @@ internal fun WrapSend(
@VisibleForTesting @VisibleForTesting
@Composable @Composable
internal fun WrapSend( internal fun WrapSend(
balanceState: BalanceState,
sendArguments: SendArguments?, sendArguments: SendArguments?,
synchronizer: Synchronizer?, synchronizer: Synchronizer?,
walletSnapshot: WalletSnapshot?, walletSnapshot: WalletSnapshot?,
@ -178,7 +183,7 @@ internal fun WrapSend(
CircularScreenProgressIndicator() CircularScreenProgressIndicator()
} else { } else {
Send( Send(
walletSnapshot = walletSnapshot, balanceState = balanceState,
sendStage = sendStage, sendStage = sendStage,
onCreateZecSend = { newZecSend -> onCreateZecSend = { newZecSend ->
scope.launch { scope.launch {
@ -219,7 +224,8 @@ internal fun WrapSend(
onQrScannerOpen = goToQrScanner, onQrScannerOpen = goToQrScanner,
goBalances = goBalances, goBalances = goBalances,
hasCameraFeature = hasCameraFeature, hasCameraFeature = hasCameraFeature,
walletRestoringState = walletRestoringState walletRestoringState = walletRestoringState,
walletSnapshot = walletSnapshot,
) )
} }
} }

View File

@ -51,6 +51,7 @@ import cash.z.ecc.sdk.fixture.ZatoshiFixture
import cash.z.ecc.sdk.type.ZcashCurrency import cash.z.ecc.sdk.type.ZcashCurrency
import co.electriccoin.zcash.spackle.Twig import co.electriccoin.zcash.spackle.Twig
import co.electriccoin.zcash.ui.R import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.common.compose.BalanceState
import co.electriccoin.zcash.ui.common.compose.BalanceWidget import co.electriccoin.zcash.ui.common.compose.BalanceWidget
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
@ -67,6 +68,7 @@ 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.theme.ZcashTheme import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.BalanceStateFixture
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
import co.electriccoin.zcash.ui.screen.send.SendTag import co.electriccoin.zcash.ui.screen.send.SendTag
import co.electriccoin.zcash.ui.screen.send.model.AmountState import co.electriccoin.zcash.ui.screen.send.model.AmountState
@ -81,7 +83,6 @@ private fun PreviewSendForm() {
ZcashTheme(forceDarkMode = false) { ZcashTheme(forceDarkMode = false) {
GradientSurface { GradientSurface {
Send( Send(
walletSnapshot = WalletSnapshotFixture.new(),
sendStage = SendStage.Form, sendStage = SendStage.Form,
onCreateZecSend = {}, onCreateZecSend = {},
focusManager = LocalFocusManager.current, focusManager = LocalFocusManager.current,
@ -96,7 +97,9 @@ private fun PreviewSendForm() {
amountState = AmountState.Valid(ZatoshiFixture.ZATOSHI_LONG.toString(), ZatoshiFixture.new()), amountState = AmountState.Valid(ZatoshiFixture.ZATOSHI_LONG.toString(), ZatoshiFixture.new()),
setMemoState = {}, setMemoState = {},
memoState = MemoState.new("Test message"), memoState = MemoState.new("Test message"),
walletRestoringState = WalletRestoringState.NONE walletRestoringState = WalletRestoringState.NONE,
walletSnapshot = WalletSnapshotFixture.new(),
balanceState = BalanceStateFixture.new()
) )
} }
} }
@ -108,6 +111,7 @@ private fun PreviewSendForm() {
@Suppress("LongParameterList") @Suppress("LongParameterList")
@Composable @Composable
fun Send( fun Send(
balanceState: BalanceState,
sendStage: SendStage, sendStage: SendStage,
onCreateZecSend: (ZecSend) -> Unit, onCreateZecSend: (ZecSend) -> Unit,
focusManager: FocusManager, focusManager: FocusManager,
@ -132,6 +136,7 @@ fun Send(
) )
}) { paddingValues -> }) { paddingValues ->
SendMainContent( SendMainContent(
balanceState = balanceState,
walletSnapshot = walletSnapshot, walletSnapshot = walletSnapshot,
onBack = onBack, onBack = onBack,
focusManager = focusManager, focusManager = focusManager,
@ -188,6 +193,7 @@ private fun SendTopAppBar(
@Suppress("LongParameterList") @Suppress("LongParameterList")
@Composable @Composable
private fun SendMainContent( private fun SendMainContent(
balanceState: BalanceState,
walletSnapshot: WalletSnapshot, walletSnapshot: WalletSnapshot,
focusManager: FocusManager, focusManager: FocusManager,
onBack: () -> Unit, onBack: () -> Unit,
@ -208,6 +214,7 @@ private fun SendMainContent(
// loader if calling the Proposal API takes longer than expected // loader if calling the Proposal API takes longer than expected
SendForm( SendForm(
balanceState = balanceState,
walletSnapshot = walletSnapshot, walletSnapshot = walletSnapshot,
recipientAddressState = recipientAddressState, recipientAddressState = recipientAddressState,
onRecipientAddressChange = onRecipientAddressChange, onRecipientAddressChange = onRecipientAddressChange,
@ -242,6 +249,7 @@ const val DEFAULT_LESS_THAN_FEE = 100_000L
@Suppress("LongMethod", "LongParameterList") @Suppress("LongMethod", "LongParameterList")
@Composable @Composable
private fun SendForm( private fun SendForm(
balanceState: BalanceState,
walletSnapshot: WalletSnapshot, walletSnapshot: WalletSnapshot,
focusManager: FocusManager, focusManager: FocusManager,
recipientAddressState: RecipientAddressState, recipientAddressState: RecipientAddressState,
@ -275,7 +283,7 @@ private fun SendForm(
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingSmall)) Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingSmall))
BalanceWidget( BalanceWidget(
walletSnapshot = walletSnapshot, balanceState = balanceState,
isReferenceToBalances = true, isReferenceToBalances = true,
onReferenceClick = goBalances onReferenceClick = goBalances
) )