Extend shielding state (#1322)

- This adds `ShieldState.Shielded` that helps us keep the correct UI state of the Transparent funds widget after the user starts shielding action
- This also brings little UI improvement in PrimaryButton sizing
This commit is contained in:
Honza Rychnovský 2024-04-08 07:49:53 +02:00 committed by GitHub
parent 8c027003cc
commit b34d086cc0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 40 additions and 13 deletions

View File

@ -86,7 +86,7 @@ fun PrimaryButton(
horizontal = ZcashTheme.dimens.spacingNone,
vertical = ZcashTheme.dimens.spacingSmall
),
contentPaddingValues: PaddingValues = PaddingValues(all = 15.dp)
contentPaddingValues: PaddingValues = PaddingValues(all = 15.5.dp)
) {
Button(
shape = RectangleShape,

View File

@ -8,12 +8,14 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import cash.z.ecc.android.sdk.SdkSynchronizer
import cash.z.ecc.android.sdk.Synchronizer
import cash.z.ecc.android.sdk.model.UnifiedSpendingKey
import cash.z.ecc.android.sdk.model.Zatoshi
import co.electriccoin.zcash.spackle.Twig
import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
import co.electriccoin.zcash.ui.common.viewmodel.CheckUpdateViewModel
@ -85,6 +87,8 @@ internal fun WrapBalances(
) {
val scope = rememberCoroutineScope()
val context = LocalContext.current
// To show information about the app update, if available
val isUpdateAvailable =
checkUpdateViewModel.updateInfo.collectAsStateWithLifecycle().value.let {
@ -94,15 +98,10 @@ internal fun WrapBalances(
val isFiatConversionEnabled = ConfigurationEntries.IS_FIAT_CONVERSION_ENABLED.getValue(RemoteConfig.current)
val (shieldState, setShieldState) =
rememberSaveable(stateSaver = ShieldState.Saver) {
mutableStateOf(
if (walletSnapshot?.hasTransparentFunds == true) {
ShieldState.Available
} else {
ShieldState.None
}
)
}
rememberSaveable(stateSaver = ShieldState.Saver) { mutableStateOf(ShieldState.None) }
// Keep the state always up-to-date with the latest transparent balance
setShieldState(updateTransparentBalanceState(shieldState, walletSnapshot))
val (isShowingErrorDialog, setShowErrorDialog) = rememberSaveable { mutableStateOf(false) }
@ -145,10 +144,12 @@ internal fun WrapBalances(
transparentReceiver = null
)
}.onSuccess { newProposal ->
Twig.debug { "Shielding proposal result: ${newProposal?.toPrettyString()}" }
Twig.info { "Shielding proposal result: ${newProposal?.toPrettyString()}" }
if (newProposal == null) {
showShieldingError(null)
showShieldingError(
context.getString(R.string.balances_shielding_dialog_error_below_threshold)
)
} else {
val result =
createTransactionsViewModel.runCreateTransactions(
@ -159,7 +160,7 @@ internal fun WrapBalances(
when (result) {
SubmitResult.Success -> {
Twig.info { "Shielding transaction done successfully" }
setShieldState(ShieldState.None)
setShieldState(ShieldState.Shielded)
// Triggering transaction history refresh to be notified about the newly created
// transaction asap
(synchronizer as SdkSynchronizer).refreshTransactions()
@ -188,3 +189,21 @@ internal fun WrapBalances(
)
}
}
fun updateTransparentBalanceState(
currentShieldState: ShieldState,
walletSnapshot: WalletSnapshot?
): ShieldState {
return when {
(walletSnapshot == null) -> {
currentShieldState
}
(
walletSnapshot.transparentBalance >= Zatoshi(DEFAULT_SHIELDING_THRESHOLD) &&
currentShieldState.isEnabled()
) -> ShieldState.Available
else -> {
currentShieldState
}
}
}

View File

@ -9,12 +9,17 @@ sealed class ShieldState {
data object Running : ShieldState()
data object Shielded : ShieldState()
data class Failed(val error: String) : ShieldState()
fun isEnabled() = this != Running && this !is Failed && this != Shielded
companion object {
private const val TYPE_NONE = "none" // $NON-NLS
private const val TYPE_AVAILABLE = "available" // $NON-NLS
private const val TYPE_RUNNING = "running" // $NON-NLS
private const val TYPE_SHIELDED = "shielded" // $NON-NLS
private const val TYPE_FAILED = "failed" // $NON-NLS
private const val KEY_TYPE = "type" // $NON-NLS
@ -34,6 +39,7 @@ sealed class ShieldState {
TYPE_NONE -> None
TYPE_AVAILABLE -> Available
TYPE_RUNNING -> Running
TYPE_SHIELDED -> Shielded
TYPE_FAILED -> Failed((it[KEY_ERROR] as String))
else -> null
}
@ -48,6 +54,7 @@ sealed class ShieldState {
None -> saverMap[KEY_TYPE] = TYPE_NONE
Available -> saverMap[KEY_TYPE] = TYPE_AVAILABLE
Running -> saverMap[KEY_TYPE] = TYPE_RUNNING
Shielded -> saverMap[KEY_TYPE] = TYPE_SHIELDED
is Failed -> {
saverMap[KEY_TYPE] = TYPE_FAILED
saverMap[KEY_ERROR] = this.error

View File

@ -33,4 +33,5 @@
<string name="balances_shielding_dialog_error_title">Failed to shield funds</string>
<string name="balances_shielding_dialog_error_text">Error: The attempt to shield the transparent funds failed. Try it again, please.</string>
<string name="balances_shielding_dialog_error_btn">OK</string>
<string name="balances_shielding_dialog_error_below_threshold">The current transparent balance is zero or below the allowed shielding limit.</string>
</resources>