[#1264] Handle unavailable AccountBalance
- Closes #1264 - Changelog update
This commit is contained in:
parent
b34d086cc0
commit
bca1c32b8c
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
|
)
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
)
|
||||||
|
}
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 = {}
|
||||||
)
|
)
|
||||||
|
|
|
@ -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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue