[#1319] Restoring state UI in Account and Balances (#1334)

* [#1319] Restoring state UI in Account and Balances

- Closes #1319

* [#1319] Restoring state widget in Account

- Closes #1319

* Add syncing widget to Account while restoring

* Update changelog

Plus reset the previously unreleased app record
This commit is contained in:
Honza Rychnovský 2024-04-12 11:55:44 +02:00 committed by GitHub
parent bcdf328cb4
commit cad8e48bf8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 197 additions and 74 deletions

View File

@ -9,8 +9,6 @@ directly impact users rather than highlighting other key architectural updates.*
## [Unreleased]
## [0.2.0 (594)] - 2024-04-09
### Added
- Advanced Settings screen that provides more technical options like Export private data, Recovery phrase, or
Choose server has been added
@ -21,8 +19,8 @@ directly impact users rather than highlighting other key architectural updates.*
- Transitions between screens are now animated with a simple slide animation
- Proposal API from the Zcash SDK has been integrated together with handling error states for multi-transaction
submission
- New Restoring Your Wallet label has been added to all post-onboarding screens to notify users about the current
state of the wallet-restoring process.
- New Restoring Your Wallet label and Synchronization widget have been added to all post-onboarding screens to notify
users about the current state of the wallet-restoring process
### Changed
- The Transaction History UI has been incorporated into the Account screen and completely reworked according to the

View File

@ -192,6 +192,7 @@ fun TitleLarge(
fun Small(
text: String,
modifier: Modifier = Modifier,
textFontWeight: FontWeight = FontWeight.Normal,
maxLines: Int = Int.MAX_VALUE,
overflow: TextOverflow = TextOverflow.Clip,
textAlign: TextAlign = TextAlign.Start,
@ -200,6 +201,7 @@ fun Small(
Text(
text = text,
color = color,
fontWeight = textFontWeight,
maxLines = maxLines,
overflow = overflow,
textAlign = textAlign,

View File

@ -26,6 +26,7 @@ data class ExtendedColors(
val textDisabled: Color,
val textFieldHint: Color,
val textFieldError: Color,
val textFieldWarning: Color,
val textFieldFrame: Color,
val textDescription: Color,
val textPending: Color,
@ -48,6 +49,7 @@ data class ExtendedColors(
val radioButtonTextColor: Color,
val historyBackgroundColor: Color,
val historyRedColor: Color,
val historySyncingColor: Color,
) {
@Composable
fun surfaceGradient() =

View File

@ -29,6 +29,7 @@ internal object Dark {
val textChipIndex = Color(0xFFFFB900)
val textFieldFrame = Color(0xFF231F20)
val textFieldError = Color(0xFFFF0000)
val textFieldWarning = Color(0xFFF40202)
val textFieldHint = Color(0xFFB7B7B7)
val textDescription = Color(0xFF777777)
val textProgress = Color(0xFF8B8A8A)
@ -71,7 +72,8 @@ internal object Dark {
val buttonShadowColor = Color(0xFFFFFFFF)
val historyBackgroundColor = Color(0xFFF6F6F6)
val historyRedColor = Color(0xFFF40202)
val historyRedColor = textFieldWarning
val historySyncingColor = panelBackgroundColor
}
internal object Light {
@ -88,6 +90,7 @@ internal object Light {
val textDisabled = Color(0xFFB7B7B7)
val textFieldFrame = Color(0xFF231F20)
val textFieldError = Color(0xFFCD0002)
val textFieldWarning = Color(0xFFF40202)
val textFieldHint = Color(0xFFB7B7B7)
val textChipIndex = Color(0xFFEE8592)
val textDescription = Color(0xFF777777)
@ -130,7 +133,8 @@ internal object Light {
val buttonShadowColor = Color(0xFF000000)
val historyBackgroundColor = Color(0xFFF6F6F6)
val historyRedColor = Color(0xFFF40202)
val historyRedColor = textFieldWarning
val historySyncingColor = Dark.panelBackgroundColor
}
internal val DarkColorPalette =
@ -177,6 +181,7 @@ internal val DarkExtendedColorPalette =
textDisabled = Dark.textDisabled,
textFieldFrame = Dark.textFieldFrame,
textFieldError = Dark.textFieldError,
textFieldWarning = Dark.textFieldWarning,
textFieldHint = Dark.textFieldHint,
textDescription = Dark.textDescription,
textPending = Dark.textProgress,
@ -199,6 +204,7 @@ internal val DarkExtendedColorPalette =
radioButtonTextColor = Dark.radioButtonTextColor,
historyBackgroundColor = Dark.historyBackgroundColor,
historyRedColor = Dark.historyRedColor,
historySyncingColor = Dark.historySyncingColor,
)
internal val LightExtendedColorPalette =
@ -221,6 +227,7 @@ internal val LightExtendedColorPalette =
textDisabled = Light.textDisabled,
textFieldFrame = Light.textFieldFrame,
textFieldError = Light.textFieldError,
textFieldWarning = Light.textFieldWarning,
textFieldHint = Light.textFieldHint,
textDescription = Light.textDescription,
textPending = Light.textProgress,
@ -243,6 +250,7 @@ internal val LightExtendedColorPalette =
radioButtonTextColor = Light.radioButtonTextColor,
historyBackgroundColor = Light.historyBackgroundColor,
historyRedColor = Light.historyRedColor,
historySyncingColor = Light.historySyncingColor,
)
@Suppress("CompositionLocalAllowlist")
@ -267,6 +275,7 @@ internal val LocalExtendedColors =
textDisabled = Color.Unspecified,
textFieldHint = Color.Unspecified,
textFieldError = Color.Unspecified,
textFieldWarning = Color.Unspecified,
textFieldFrame = Color.Unspecified,
textDescription = Color.Unspecified,
textPending = Color.Unspecified,
@ -289,5 +298,6 @@ internal val LocalExtendedColors =
radioButtonTextColor = Color.Unspecified,
historyBackgroundColor = Color.Unspecified,
historyRedColor = Color.Unspecified,
historySyncingColor = Color.Unspecified,
)
}

View File

@ -6,6 +6,7 @@ import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
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.screen.account.history.fixture.TransactionHistoryUiStateFixture
import co.electriccoin.zcash.ui.screen.account.model.TransactionUiState
import co.electriccoin.zcash.ui.screen.account.view.Account
@ -70,6 +71,7 @@ class AccountTestSetup(
onItemClickCount.incrementAndGet()
},
walletRestoringState = WalletRestoringState.NONE,
walletSnapshot = WalletSnapshotFixture.new()
)
}

View File

@ -3,6 +3,7 @@ package co.electriccoin.zcash.ui.screen.account.history
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
import co.electriccoin.zcash.ui.screen.account.model.TransactionUiState
import co.electriccoin.zcash.ui.screen.account.view.HistoryContainer
import java.util.concurrent.atomic.AtomicInteger
@ -32,7 +33,8 @@ class HistoryTestSetup(
onTransactionItemAction = {
onItemIdClickCount.incrementAndGet()
},
walletRestoringState = WalletRestoringState.NONE
walletRestoringState = WalletRestoringState.NONE,
walletSnapshot = WalletSnapshotFixture.new()
)
}
}

View File

@ -0,0 +1,93 @@
package co.electriccoin.zcash.ui.common.compose
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
import cash.z.ecc.sdk.extension.toPercentageWithDecimal
import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
import co.electriccoin.zcash.ui.design.component.BodySmall
import co.electriccoin.zcash.ui.design.component.GradientSurface
import co.electriccoin.zcash.ui.design.component.LinearProgressIndicator
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
import co.electriccoin.zcash.ui.screen.balances.model.WalletDisplayValues
@Preview(device = Devices.PIXEL_4_XL)
@Composable
private fun BalanceWidgetPreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface(
modifier = Modifier.fillMaxWidth()
) {
SynchronizationStatus(
isUpdateAvailable = false,
isDetailedStatus = false,
walletSnapshot = WalletSnapshotFixture.new()
)
}
}
}
@Composable
fun SynchronizationStatus(
isUpdateAvailable: Boolean,
isDetailedStatus: Boolean,
walletSnapshot: WalletSnapshot,
modifier: Modifier = Modifier,
testTag: String? = null,
) {
val walletDisplayValues =
WalletDisplayValues.getNextValues(
context = LocalContext.current,
walletSnapshot = walletSnapshot,
isUpdateAvailable = isUpdateAvailable,
isDetailedStatus = isDetailedStatus
)
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier
) {
if (walletDisplayValues.statusText.isNotEmpty()) {
BodySmall(
text = walletDisplayValues.statusText,
modifier = testTag?.let { Modifier.testTag(testTag) } ?: Modifier,
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingSmall))
}
BodySmall(
text =
stringResource(
id = R.string.balances_status_syncing_percentage,
walletSnapshot.progress.toPercentageWithDecimal()
),
textFontWeight = FontWeight.Black
)
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingSmall))
LinearProgressIndicator(
progress = walletSnapshot.progress.decimal,
modifier =
Modifier.padding(
horizontal = ZcashTheme.dimens.spacingUpLarge
)
)
}
}

View File

@ -14,6 +14,7 @@ import co.electriccoin.zcash.spackle.ClipboardManagerUtil
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.WalletSnapshot
import co.electriccoin.zcash.ui.common.viewmodel.WalletViewModel
import co.electriccoin.zcash.ui.design.component.CircularScreenProgressIndicator
import co.electriccoin.zcash.ui.screen.account.model.TransactionUiState
@ -48,6 +49,8 @@ internal fun WrapAccount(
val balanceState = walletViewModel.balanceState.collectAsStateWithLifecycle().value
val walletSnapshot = walletViewModel.walletSnapshot.collectAsStateWithLifecycle().value
WrapAccount(
balanceState = balanceState,
context = activity.applicationContext,
@ -57,7 +60,8 @@ internal fun WrapAccount(
synchronizer = synchronizer,
transactionHistoryViewModel = transactionHistoryViewModel,
transactionsUiState = transactionsUiState,
walletRestoringState = walletRestoringState
walletRestoringState = walletRestoringState,
walletSnapshot = walletSnapshot
)
// For benchmarking purposes
@ -77,8 +81,9 @@ internal fun WrapAccount(
synchronizer: Synchronizer?,
transactionHistoryViewModel: TransactionHistoryViewModel,
walletRestoringState: WalletRestoringState,
walletSnapshot: WalletSnapshot?
) {
if (null == synchronizer) {
if (null == synchronizer || null == walletSnapshot) {
// 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]: https://github.com/Electric-Coin-Company/zashi-android/issues/1146
@ -127,7 +132,8 @@ internal fun WrapAccount(
},
goBalances = goBalances,
goSettings = goSettings,
walletRestoringState = walletRestoringState
walletRestoringState = walletRestoringState,
walletSnapshot = walletSnapshot
)
}
}

View File

@ -20,11 +20,13 @@ 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.model.WalletRestoringState
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
import co.electriccoin.zcash.ui.common.test.CommonTag
import co.electriccoin.zcash.ui.design.component.GradientSurface
import co.electriccoin.zcash.ui.design.component.SmallTopAppBar
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.screen.account.AccountTag
import co.electriccoin.zcash.ui.screen.account.fixture.TransactionsFixture
import co.electriccoin.zcash.ui.screen.account.model.TransactionUiState
@ -40,7 +42,8 @@ private fun HistoryLoadingComposablePreview() {
onTransactionItemAction = {},
transactionsUiState = TransactionUiState.Loading,
walletRestoringState = WalletRestoringState.SYNCING,
balanceState = BalanceStateFixture.new()
balanceState = BalanceStateFixture.new(),
walletSnapshot = WalletSnapshotFixture.new(),
)
}
}
@ -55,10 +58,11 @@ private fun HistoryListComposablePreview() {
Account(
goBalances = {},
goSettings = {},
balanceState = BalanceState.Available(Zatoshi(123_000_000L), Zatoshi(123_000_000L)),
onTransactionItemAction = {},
transactionsUiState = TransactionUiState.Done(transactions = TransactionsFixture.new()),
walletRestoringState = WalletRestoringState.NONE,
balanceState = BalanceState.Available(Zatoshi(123_000_000L), Zatoshi(123_000_000L))
walletSnapshot = WalletSnapshotFixture.new(),
)
}
}
@ -73,6 +77,7 @@ internal fun Account(
onTransactionItemAction: (TrxItemAction) -> Unit,
transactionsUiState: TransactionUiState,
walletRestoringState: WalletRestoringState,
walletSnapshot: WalletSnapshot,
) {
Scaffold(topBar = {
AccountTopAppBar(
@ -83,9 +88,10 @@ internal fun Account(
AccountMainContent(
balanceState = balanceState,
goBalances = goBalances,
onTransactionItemAction = onTransactionItemAction,
transactionState = transactionsUiState,
walletRestoringState = walletRestoringState,
onTransactionItemAction = onTransactionItemAction,
walletSnapshot = walletSnapshot,
modifier =
Modifier.padding(
top = paddingValues.calculateTopPadding() + ZcashTheme.dimens.spacingDefault,
@ -131,6 +137,7 @@ private fun AccountMainContent(
onTransactionItemAction: (TrxItemAction) -> Unit,
transactionState: TransactionUiState,
walletRestoringState: WalletRestoringState,
walletSnapshot: WalletSnapshot,
modifier: Modifier = Modifier,
) {
Column(
@ -150,9 +157,10 @@ private fun AccountMainContent(
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingUpLarge))
HistoryContainer(
onTransactionItemAction = onTransactionItemAction,
transactionState = transactionState,
walletRestoringState = walletRestoringState,
onTransactionItemAction = onTransactionItemAction,
walletSnapshot = walletSnapshot,
)
}
}

View File

@ -45,18 +45,22 @@ import cash.z.ecc.android.sdk.model.TransactionState
import cash.z.ecc.android.sdk.model.Zatoshi
import cash.z.ecc.android.sdk.model.toZecString
import co.electriccoin.zcash.ui.R
import co.electriccoin.zcash.ui.common.compose.SynchronizationStatus
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
import co.electriccoin.zcash.ui.design.component.CircularMidProgressIndicator
import co.electriccoin.zcash.ui.design.component.GradientSurface
import co.electriccoin.zcash.ui.design.component.StyledBalance
import co.electriccoin.zcash.ui.design.component.TextWithIcon
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
import co.electriccoin.zcash.ui.screen.account.HistoryTag
import co.electriccoin.zcash.ui.screen.account.fixture.TransactionUiFixture
import co.electriccoin.zcash.ui.screen.account.fixture.TransactionsFixture
import co.electriccoin.zcash.ui.screen.account.model.TransactionUi
import co.electriccoin.zcash.ui.screen.account.model.TransactionUiState
import co.electriccoin.zcash.ui.screen.account.model.TrxItemState
import co.electriccoin.zcash.ui.screen.balances.BalancesTag
import co.electriccoin.zcash.ui.screen.send.view.DEFAULT_LESS_THAN_FEE
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toPersistentList
@ -70,9 +74,10 @@ private fun ComposablePreview() {
ZcashTheme(forceDarkMode = false) {
GradientSurface {
HistoryContainer(
transactionState = TransactionUiState.Loading,
onTransactionItemAction = {},
walletRestoringState = WalletRestoringState.SYNCING
transactionState = TransactionUiState.Loading,
walletRestoringState = WalletRestoringState.SYNCING,
walletSnapshot = WalletSnapshotFixture.new()
)
}
}
@ -86,7 +91,8 @@ private fun ComposableHistoryListPreview() {
HistoryContainer(
transactionState = TransactionUiState.Done(transactions = TransactionsFixture.new()),
onTransactionItemAction = {},
walletRestoringState = WalletRestoringState.NONE
walletRestoringState = WalletRestoringState.RESTORING,
walletSnapshot = WalletSnapshotFixture.new()
)
}
}
@ -103,12 +109,13 @@ private val dateFormat: DateFormat by lazy {
@Composable
internal fun HistoryContainer(
transactionState: TransactionUiState,
onTransactionItemAction: (TrxItemAction) -> Unit,
transactionState: TransactionUiState,
walletRestoringState: WalletRestoringState,
walletSnapshot: WalletSnapshot,
modifier: Modifier = Modifier,
) {
Box(
Column(
modifier =
modifier
.then(
@ -117,6 +124,24 @@ internal fun HistoryContainer(
.background(ZcashTheme.colors.historyBackgroundColor)
)
) {
if (walletRestoringState == WalletRestoringState.RESTORING) {
Column(
modifier = Modifier.background(color = ZcashTheme.colors.historySyncingColor)
) {
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge))
// Do not show the app update information and the detailed sync status in the restoring status
// on Account screen
SynchronizationStatus(
isDetailedStatus = false,
isUpdateAvailable = false,
testTag = BalancesTag.STATUS,
walletSnapshot = walletSnapshot,
)
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingLarge))
}
}
when (transactionState) {
TransactionUiState.Loading -> {
LoadingTransactionHistory()

View File

@ -86,7 +86,7 @@ data class WalletDisplayValues(
}
Synchronizer.Status.STOPPED -> {
if (isDetailedStatus) {
statusText = context.getString(R.string.balances_status_stopped)
statusText = context.getString(R.string.balances_status_detailed_stopped)
} else {
statusText = context.getString(R.string.balances_status_syncing)
}

View File

@ -50,10 +50,10 @@ import androidx.compose.ui.unit.dp
import cash.z.ecc.android.sdk.model.FiatCurrencyConversionRateState
import cash.z.ecc.android.sdk.model.Zatoshi
import cash.z.ecc.android.sdk.model.toZecString
import cash.z.ecc.sdk.extension.toPercentageWithDecimal
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.SynchronizationStatus
import co.electriccoin.zcash.ui.common.model.WalletRestoringState
import co.electriccoin.zcash.ui.common.model.WalletSnapshot
import co.electriccoin.zcash.ui.common.model.changePendingBalance
@ -67,9 +67,9 @@ import co.electriccoin.zcash.ui.design.component.BodyWithFiatCurrencySymbol
import co.electriccoin.zcash.ui.design.component.CircularScreenProgressIndicator
import co.electriccoin.zcash.ui.design.component.CircularSmallProgressIndicator
import co.electriccoin.zcash.ui.design.component.GradientSurface
import co.electriccoin.zcash.ui.design.component.LinearProgressIndicator
import co.electriccoin.zcash.ui.design.component.PrimaryButton
import co.electriccoin.zcash.ui.design.component.Reference
import co.electriccoin.zcash.ui.design.component.Small
import co.electriccoin.zcash.ui.design.component.SmallTopAppBar
import co.electriccoin.zcash.ui.design.component.StyledBalance
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
@ -162,6 +162,7 @@ fun Balances(
start = ZcashTheme.dimens.screenHorizontalSpacingRegular,
end = ZcashTheme.dimens.screenHorizontalSpacingRegular
),
walletRestoringState = walletRestoringState
)
// Show shielding error popup
@ -245,6 +246,7 @@ private fun BalancesMainContent(
onShielding: () -> Unit,
walletSnapshot: WalletSnapshot,
shieldState: ShieldState,
walletRestoringState: WalletRestoringState,
modifier: Modifier = Modifier,
) {
Column(
@ -285,14 +287,30 @@ private fun BalancesMainContent(
walletSnapshot = walletSnapshot,
)
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
Spacer(modifier = Modifier.weight(1f, true))
SyncStatus(
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
if (walletRestoringState == WalletRestoringState.RESTORING) {
Small(
text = stringResource(id = R.string.balances_status_restoring_text),
textFontWeight = FontWeight.Medium,
color = ZcashTheme.colors.textFieldWarning,
textAlign = TextAlign.Center,
modifier =
Modifier
.fillMaxWidth()
.padding(horizontal = ZcashTheme.dimens.spacingDefault)
)
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
}
SynchronizationStatus(
walletSnapshot = walletSnapshot,
isUpdateAvailable = isUpdateAvailable,
isDetailedStatus = isDetailedStatus,
testTag = BalancesTag.STATUS
)
}
}
@ -609,51 +627,3 @@ fun PendingTransactionsRow(walletSnapshot: WalletSnapshot) {
}
}
}
@Composable
fun SyncStatus(
isUpdateAvailable: Boolean,
isDetailedStatus: Boolean,
walletSnapshot: WalletSnapshot,
) {
val walletDisplayValues =
WalletDisplayValues.getNextValues(
context = LocalContext.current,
walletSnapshot = walletSnapshot,
isUpdateAvailable = isUpdateAvailable,
isDetailedStatus = isDetailedStatus
)
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
if (walletDisplayValues.statusText.isNotEmpty()) {
BodySmall(
text = walletDisplayValues.statusText,
modifier = Modifier.testTag(BalancesTag.STATUS),
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingSmall))
}
BodySmall(
text =
stringResource(
id = R.string.balances_status_syncing_percentage,
walletSnapshot.progress.toPercentageWithDecimal()
),
textFontWeight = FontWeight.Black
)
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingSmall))
LinearProgressIndicator(
progress = walletSnapshot.progress.decimal,
modifier =
Modifier.padding(
horizontal = ZcashTheme.dimens.spacingUpLarge
)
)
}
}

View File

@ -23,7 +23,8 @@
<string name="balances_status_error_detailed" formatted="true">Error: <xliff:g id="error_type" example="Lost connection">%1$s</xliff:g></string>
<string name="balances_status_error_detailed_connection">Disconnected</string>
<string name="balances_status_error_detailed_unknown">Unknown cause</string>
<string name="balances_status_stopped">Synchronizer stopped</string>
<string name="balances_status_detailed_stopped">Synchronizer stopped</string>
<string name="balances_status_restoring_text">The restore process can take several hours on lower-powered devices, and even on powerful devices is likely to take more than an hour.</string>
<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>

View File

@ -3,4 +3,8 @@
<string name="home_tab_send">Send</string>
<string name="home_tab_receive">Receive</string>
<string name="home_tab_balances">Balances</string>
<string name="restoring_initial_dialog_title">Success</string>
<string name="restoring_initial_dialog_description">Your wallet has been successfully restored! During the initial sync, your funds cannot be spent or sent. Depending on the age of your wallet, it may take a few hours to fully sync.</string>
<string name="restoring_initial_dialog_positive_button">OK</string>
</resources>