diff --git a/app/src/main/java/com/tangem/tap/common/extensions/WalletManager.kt b/app/src/main/java/com/tangem/tap/common/extensions/WalletManager.kt index 8f7402ff1f..70a4fcc286 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/WalletManager.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/WalletManager.kt @@ -29,7 +29,7 @@ suspend fun WalletManager.safeUpdate(): Result = try { if (blockchain.isNoAccountError(exception) && amountToCreateAccount != null) { Result.Failure(TapError.WalletManagerUpdate.NoAccountError(amountToCreateAccount.toString())) } else { - val message = exception.localizedMessage ?: "Unknown exception during WalletManager update" + val message = exception.localizedMessage ?: "An error has occurred. Try later" Result.Failure(TapError.WalletManagerUpdate.InternalError(message)) } } diff --git a/app/src/main/java/com/tangem/tap/domain/TapErrors.kt b/app/src/main/java/com/tangem/tap/domain/TapErrors.kt index c84e3f0d29..f4b680ec9f 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapErrors.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapErrors.kt @@ -46,6 +46,8 @@ sealed class TapError( sealed class WalletManagerUpdate { class NoAccountError(amountToCreateAccount: String): CustomError(amountToCreateAccount) class InternalError(message: String): CustomError(message) + object BlockchainIsUnreachable: TapError(R.string.wallet_balance_blockchain_unreachable) + object BlockchainIsUnreachableTryLater: TapError(R.string.wallet_balance_blockchain_unreachable_try_later) } data class ValidateTransactionErrors( diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingManager.kt b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingManager.kt index 984f512d4f..60d3cc323f 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingManager.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingManager.kt @@ -20,6 +20,7 @@ import com.tangem.tap.features.wallet.redux.ProgressState import com.tangem.tap.persistence.UsedCardsPrefStorage import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import timber.log.Timber import java.math.BigDecimal import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine @@ -76,7 +77,10 @@ class OnboardingManager( when (error) { is TapError.WalletManagerUpdate.NoAccountError -> OnboardingWalletBalance.error(error) // NoInternetConnection, WalletManagerUpdate.InternalError - else -> OnboardingWalletBalance.criticalError(error) + else -> { + Timber.e(error.localizedMessage) + OnboardingWalletBalance.criticalError(TapError.WalletManagerUpdate.BlockchainIsUnreachableTryLater) + } } } } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt index b59e7ea667..96086474e5 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/OnboardingNoteFragment.kt @@ -91,9 +91,13 @@ class OnboardingNoteFragment : BaseOnboardingFragment() { private fun setBalance(state: OnboardingNoteState) { if (state.walletBalance.currency.blockchain == Blockchain.Unknown) return - val balanceValue = state.walletBalance.value.stripZeroPlainString() - val currency = state.walletBalance.currency.currencySymbol - tv_balance_value.text = "$balanceValue $currency" + if (state.balanceCriticalError == null) { + val balanceValue = state.walletBalance.value.stripZeroPlainString() + val currency = state.walletBalance.currency.currencySymbol + tv_balance_value.text = "$balanceValue $currency" + } else { + tv_balance_value.text = "–" + } } private fun setupNoneState(state: OnboardingNoteState) { diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteAction.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteAction.kt index 3a370e6c72..cce3d41924 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteAction.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteAction.kt @@ -27,6 +27,7 @@ sealed class OnboardingNoteAction : Action { sealed class Balance { object Update : OnboardingNoteAction() data class Set(val balance: OnboardingWalletBalance) : OnboardingNoteAction() + data class SetCriticalError(val error: TapError?) : OnboardingNoteAction() data class SetNonCriticalError(val error: TapError?) : OnboardingNoteAction() } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteMiddleware.kt index b182753729..c3af3a169a 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteMiddleware.kt @@ -118,10 +118,11 @@ private fun handleNoteAction(action: Action, dispatch: DispatchFunction) { scope.launch { val loadedBalance = onboardingManager.updateBalance(walletManager) - loadedBalance.criticalError?.let { store.dispatchErrorNotification(it) } delay(if (isLoadedBefore) 0 else 300) + loadedBalance.criticalError?.let { store.dispatchErrorNotification(it) } withMainContext { store.dispatch(OnboardingNoteAction.Balance.Set(loadedBalance)) + store.dispatch(OnboardingNoteAction.Balance.SetCriticalError(loadedBalance.criticalError)) store.dispatch(OnboardingNoteAction.Balance.SetNonCriticalError(loadedBalance.error)) } } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteReducer.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteReducer.kt index 260f41fc20..913dca781f 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteReducer.kt @@ -26,6 +26,9 @@ private fun internalReduce(action: Action, appState: AppState): OnboardingNoteSt is OnboardingNoteAction.Balance.Set -> { state = state.copy(walletBalance = action.balance) } + is OnboardingNoteAction.Balance.SetCriticalError -> { + state = state.copy(balanceCriticalError = action.error) + } is OnboardingNoteAction.Balance.SetNonCriticalError -> { state = state.copy(balanceNonCriticalError = action.error) } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteState.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteState.kt index 3cf07bea6b..c1967db335 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteState.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteState.kt @@ -15,6 +15,7 @@ data class OnboardingNoteState( val cardArtwork: Artwork? = null, val walletBalance: OnboardingWalletBalance = OnboardingWalletBalance.loading(), val balanceNonCriticalError: TapError? = null, + val balanceCriticalError: TapError? = null, val currentStep: OnboardingNoteStep = OnboardingNoteStep.None, val steps: List = OnboardingNoteStep.values().toList(), val showConfetti: Boolean = false, diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsAction.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsAction.kt index 7d48937c17..766930141a 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsAction.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsAction.kt @@ -4,6 +4,7 @@ import com.tangem.Message import com.tangem.blockchain.common.WalletManager import com.tangem.common.extensions.VoidCallback import com.tangem.tap.common.redux.StateDialog +import com.tangem.tap.domain.TapError import com.tangem.tap.domain.tasks.product.ScanResponse import com.tangem.tap.domain.twins.AssetReader import com.tangem.tap.domain.twins.TwinCardsManager @@ -55,6 +56,8 @@ sealed class TwinCardsAction : Action { sealed class Balance { object Update : TwinCardsAction() data class Set(val balance: OnboardingWalletBalance) : TwinCardsAction() + data class SetCriticalError(val error: TapError?) : TwinCardsAction() + data class SetNonCriticalError(val error: TapError?) : TwinCardsAction() } sealed class Confetti { diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt index 26fbfb104b..fc245c3db4 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt @@ -212,7 +212,11 @@ private fun handle(action: Action, dispatch: DispatchFunction) { val loadedBalance = onboardingManager?.updateBalance(walletManager) ?: return@launch loadedBalance.criticalError?.let { store.dispatchErrorNotification(it) } delay(if (isLoadedBefore) 0 else 300) - withMainContext { store.dispatch(TwinCardsAction.Balance.Set(loadedBalance)) } + withMainContext { + store.dispatch(TwinCardsAction.Balance.Set(loadedBalance)) + store.dispatch(TwinCardsAction.Balance.SetCriticalError(loadedBalance.criticalError)) + store.dispatch(TwinCardsAction.Balance.SetNonCriticalError(loadedBalance.error)) + } } } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsReducer.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsReducer.kt index 153f91e796..437213c588 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsReducer.kt @@ -55,6 +55,12 @@ private fun internalReduce(action: Action, state: AppState): TwinCardsState { is TwinCardsAction.Balance.Set -> { state = state.copy(walletBalance = action.balance) } + is TwinCardsAction.Balance.SetCriticalError -> { + state = state.copy(balanceCriticalError = action.error) + } + is TwinCardsAction.Balance.SetNonCriticalError -> { + state = state.copy(balanceNonCriticalError = action.error) + } is TwinCardsAction.Confetti.Show -> { state = state.copy(showConfetti = true) } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsState.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsState.kt index ac731df22a..22834a920e 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsState.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsState.kt @@ -1,6 +1,7 @@ package com.tangem.tap.features.onboarding.products.twins.redux import com.tangem.blockchain.common.WalletManager +import com.tangem.tap.domain.TapError import com.tangem.tap.domain.twins.TwinCardNumber import com.tangem.tap.domain.twins.TwinCardsManager import com.tangem.tap.features.onboarding.OnboardingWalletBalance @@ -22,6 +23,8 @@ data class TwinCardsState( val pairCardId: String? = null, // available after create\recreate wallets val walletManager: WalletManager? = null, val walletBalance: OnboardingWalletBalance = OnboardingWalletBalance.loading(), + val balanceNonCriticalError: TapError? = null, + val balanceCriticalError: TapError? = null, val showConfetti: Boolean = false, ) : StateType { diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt index 05c71f8c96..ccc015f2e6 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt @@ -114,11 +114,6 @@ class TwinsCardsFragment : BaseOnboardingFragment() { override fun newState(state: TwinCardsState) { if (activity == null) return -// toolbar.title = when (state.mode) { -// CreateTwinWalletMode.CreateWallet -> getText(R.string.wallet_button_create_wallet) -// CreateTwinWalletMode.RecreateWallet -> getText(R.string.twins_recreate_toolbar) -// } - pb_state.max = state.steps.size - 1 pb_state.progress = state.progress @@ -141,9 +136,13 @@ class TwinsCardsFragment : BaseOnboardingFragment() { private fun setBalance(state: TwinCardsState) { if (state.walletBalance.currency.blockchain == Blockchain.Unknown) return - val balanceValue = state.walletBalance.value.stripZeroPlainString() - val currency = state.walletBalance.currency.currencySymbol - tv_balance_value.text = "$balanceValue $currency" + if (state.balanceCriticalError == null) { + val balanceValue = state.walletBalance.value.stripZeroPlainString() + val currency = state.walletBalance.currency.currencySymbol + tv_balance_value.text = "$balanceValue $currency" + } else { + tv_balance_value.text = "–" + } } private fun setupWelcomeOnlyState(state: TwinCardsState) { diff --git a/app/src/main/res/values/strings_untranslated.xml b/app/src/main/res/values/strings_untranslated.xml index d1ac99cf9c..d34ea02c07 100644 --- a/app/src/main/res/values/strings_untranslated.xml +++ b/app/src/main/res/values/strings_untranslated.xml @@ -194,5 +194,7 @@ If the process of re-creating the wallet gets interrupted in any way, you’ll have to start over. Internal error: can\'t create wallet manager + Blockchain is unreachable. Try later +