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/common/images/Picasso.kt b/app/src/main/java/com/tangem/tap/common/images/Picasso.kt index 7d2a956bde..9220859e8b 100644 --- a/app/src/main/java/com/tangem/tap/common/images/Picasso.kt +++ b/app/src/main/java/com/tangem/tap/common/images/Picasso.kt @@ -21,6 +21,7 @@ class PicassoHelper { .downloader(OkHttp3Downloader(getOkHttpForPicasso(application))) .build() picasso.isLoggingEnabled = BuildConfig.DEBUG + picasso.setIndicatorsEnabled(BuildConfig.DEBUG) Picasso.setSingletonInstance(picasso) } 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..3aa671c5c3 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 @@ -10,19 +10,14 @@ import com.tangem.operations.attestation.OnlineCardVerifier import com.tangem.tap.common.extensions.isPositive import com.tangem.tap.common.extensions.safeUpdate import com.tangem.tap.domain.TapError -import com.tangem.tap.domain.UrlBitmapLoader import com.tangem.tap.domain.extensions.getOrLoadCardArtworkUrl import com.tangem.tap.domain.tasks.product.ScanResponse import com.tangem.tap.features.wallet.models.hasPendingTransactions -import com.tangem.tap.features.wallet.redux.Artwork import com.tangem.tap.features.wallet.redux.Currency 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 /** [REDACTED_AUTHOR] @@ -35,24 +30,31 @@ class OnboardingManager( var cardInfo: Result? = null private set - suspend fun loadArtwork(): Artwork { - cardInfo = OnlineCardVerifier().getCardInfo(scanResponse.card.cardId, scanResponse.card.cardPublicKey) - return loadArtwork(scanResponse.card.getOrLoadCardArtworkUrl(cardInfo)) + suspend fun loadArtworkUrl(): String { + val cardInfo = cardInfo + ?: OnlineCardVerifier().getCardInfo(scanResponse.card.cardId, scanResponse.card.cardPublicKey) + this.cardInfo = cardInfo + return scanResponse.card.getOrLoadCardArtworkUrl(cardInfo) } - suspend fun loadArtwork(url: String): Artwork { - return withContext(Dispatchers.Main) { - suspendCoroutine { continuation -> - UrlBitmapLoader().loadBitmap(url) { - val result = when (it) { - is Result.Success -> Artwork(url, it.data) - is Result.Failure -> Artwork(url, null) - } - continuation.resume(result) - } - } - } - } +// suspend fun loadArtwork(): Artwork { +// cardInfo = OnlineCardVerifier().getCardInfo(scanResponse.card.cardId, scanResponse.card.cardPublicKey) +// return loadArtwork(scanResponse.card.getOrLoadCardArtworkUrl(cardInfo)) +// } +// +// suspend fun loadArtwork(url: String): Artwork { +// return withContext(Dispatchers.Main) { +// suspendCoroutine { continuation -> +// UrlBitmapLoader().loadBitmap(url) { +// val result = when (it) { +// is Result.Success -> Artwork(url, it.data) +// is Result.Failure -> Artwork(url, null) +// } +// continuation.resume(result) +// } +// } +// } +// } suspend fun updateBalance(walletManager: WalletManager): OnboardingWalletBalance { val balance = when (val result = walletManager.safeUpdate()) { @@ -76,7 +78,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..7eb8b3a5fc 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 @@ -10,6 +10,7 @@ import androidx.annotation.LayoutRes import androidx.constraintlayout.widget.ConstraintSet import androidx.core.view.isVisible import androidx.transition.TransitionManager +import com.squareup.picasso.Picasso import com.tangem.blockchain.common.Blockchain import com.tangem.tangem_sdk_new.extensions.fadeIn import com.tangem.tangem_sdk_new.extensions.fadeOut @@ -73,7 +74,12 @@ class OnboardingNoteFragment : BaseOnboardingFragment() { override fun newState(state: OnboardingNoteState) { if (activity == null) return - state.cardArtwork?.let { imv_front_card.swapToBitmapDrawable(it.artwork) } + Picasso.get() + .load(state.cardArtworkUrl) + .error(R.drawable.card_placeholder_black) + .placeholder(R.drawable.card_placeholder_black) + ?.into(imv_front_card) + pb_state.max = state.steps.size - 1 pb_state.progress = state.progress @@ -91,9 +97,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..5b377fd072 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 @@ -3,7 +3,6 @@ package com.tangem.tap.features.onboarding.products.note.redux import com.tangem.blockchain.common.WalletManager import com.tangem.tap.domain.TapError import com.tangem.tap.features.onboarding.OnboardingWalletBalance -import com.tangem.tap.features.wallet.redux.Artwork import org.rekotlin.Action /** @@ -17,7 +16,7 @@ sealed class OnboardingNoteAction : Action { object ShowAddressInfoDialog : OnboardingNoteAction() // from redux - class SetArtwork(val artwork: Artwork) : OnboardingNoteAction() + class SetArtworkUrl(val artworkUrl: String) : OnboardingNoteAction() data class SetWalletManager(val walletManager: WalletManager) : OnboardingNoteAction() object DetermineStepOfScreen : OnboardingNoteAction() object Done : OnboardingNoteAction() @@ -27,6 +26,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 125ba49fff..7565ff0c9b 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 @@ -9,6 +9,7 @@ import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction +import com.tangem.tap.domain.DELAY_SDK_DIALOG_CLOSE import com.tangem.tap.domain.TapError import com.tangem.tap.domain.extensions.hasWallets import com.tangem.tap.domain.extensions.makePrimaryWalletManager @@ -50,8 +51,8 @@ private fun handleNoteAction(action: Action, dispatch: DispatchFunction) { when (action) { is OnboardingNoteAction.LoadCardArtwork -> { scope.launch { - val artwork = onboardingManager.loadArtwork() - withMainContext { store.dispatch(OnboardingNoteAction.SetArtwork(artwork)) } + val artworkUrl = onboardingManager.loadArtworkUrl() + withMainContext { store.dispatch(OnboardingNoteAction.SetArtworkUrl(artworkUrl)) } } } is OnboardingNoteAction.DetermineStepOfScreen -> { @@ -69,7 +70,7 @@ private fun handleNoteAction(action: Action, dispatch: DispatchFunction) { } OnboardingNoteStep.Done -> { onboardingManager.activationFinished(card.cardId) - postUi(500) { store.dispatch(OnboardingNoteAction.Confetti.Show) } + postUi(DELAY_SDK_DIALOG_CLOSE) { store.dispatch(OnboardingNoteAction.Confetti.Show) } } } } @@ -117,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)) } } @@ -148,7 +150,7 @@ private fun handleNoteAction(action: Action, dispatch: DispatchFunction) { store.dispatch(GlobalAction.Onboarding.Stop) scope.launch { store.onCardScanned(scanResponse) - store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet)) + withMainContext { store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet)) } } } } 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..7626922560 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 @@ -17,8 +17,8 @@ private fun internalReduce(action: Action, appState: AppState): OnboardingNoteSt is GlobalAction.Onboarding.Start -> { state = OnboardingNoteState() } - is OnboardingNoteAction.SetArtwork -> { - state = state.copy(cardArtwork = action.artwork) + is OnboardingNoteAction.SetArtworkUrl -> { + state = state.copy(cardArtworkUrl = action.artworkUrl) } is OnboardingNoteAction.SetWalletManager -> { state = state.copy(walletManager = action.walletManager) @@ -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..5bc772fa3a 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 @@ -3,7 +3,6 @@ package com.tangem.tap.features.onboarding.products.note.redux import com.tangem.blockchain.common.WalletManager import com.tangem.tap.domain.TapError import com.tangem.tap.features.onboarding.OnboardingWalletBalance -import com.tangem.tap.features.wallet.redux.Artwork import org.rekotlin.StateType /** @@ -12,9 +11,10 @@ import org.rekotlin.StateType data class OnboardingNoteState( val walletManager: WalletManager? = null, // UI - val cardArtwork: Artwork? = null, + val cardArtworkUrl: String? = 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/otherCards/OnboardingOtherCardsFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/OnboardingOtherCardsFragment.kt index cdd2871e00..0072388bcb 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/OnboardingOtherCardsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/OnboardingOtherCardsFragment.kt @@ -7,12 +7,12 @@ import androidx.annotation.LayoutRes import androidx.constraintlayout.widget.ConstraintSet import androidx.core.view.isVisible import androidx.transition.TransitionManager +import com.squareup.picasso.Picasso import com.tangem.tap.common.extensions.getDrawableCompat import com.tangem.tap.common.redux.navigation.ShareElement import com.tangem.tap.common.transitions.InternalNoteLayoutTransition import com.tangem.tap.features.addBackPressHandler import com.tangem.tap.features.onboarding.products.BaseOnboardingFragment -import com.tangem.tap.features.onboarding.products.note.swapToBitmapDrawable import com.tangem.tap.features.onboarding.products.otherCards.redux.OnboardingOtherCardsAction import com.tangem.tap.features.onboarding.products.otherCards.redux.OnboardingOtherCardsState import com.tangem.tap.features.onboarding.products.otherCards.redux.OnboardingOtherCardsStep @@ -60,7 +60,12 @@ class OnboardingOtherCardsFragment : BaseOnboardingFragment { scope.launch { - val artwork = onboardingManager.loadArtwork() - withMainContext { store.dispatch(OnboardingOtherCardsAction.SetArtwork(artwork)) } + val artworkUrl = onboardingManager.loadArtworkUrl() + withMainContext { store.dispatch(OnboardingOtherCardsAction.SetArtworkUrl(artworkUrl)) } } } is OnboardingOtherCardsAction.DetermineStepOfScreen -> { @@ -58,7 +58,7 @@ private fun handleOtherCardsAction(action: Action, dispatch: DispatchFunction) { is OnboardingOtherCardsAction.SetStepOfScreen -> { if (action.step == OnboardingOtherCardsStep.Done) { onboardingManager.activationFinished(card.cardId) - postUi(500) { store.dispatch(OnboardingOtherCardsAction.Confetti.Show) } + postUi(200) { store.dispatch(OnboardingOtherCardsAction.Confetti.Show) } } } is OnboardingOtherCardsAction.CreateWallet -> { @@ -85,7 +85,7 @@ private fun handleOtherCardsAction(action: Action, dispatch: DispatchFunction) { store.dispatch(GlobalAction.Onboarding.Stop) scope.launch { store.onCardScanned(onboardingManager.scanResponse) - store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet)) + withMainContext { store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet)) } } } } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsReducer.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsReducer.kt index 129b7ea280..e8dc2ae111 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsReducer.kt @@ -17,8 +17,8 @@ private fun internalReduce(action: Action, appState: AppState): OnboardingOtherC is GlobalAction.Onboarding.Start -> { state = OnboardingOtherCardsState() } - is OnboardingOtherCardsAction.SetArtwork -> { - state = state.copy(cardArtwork = action.artwork) + is OnboardingOtherCardsAction.SetArtworkUrl -> { + state = state.copy(cardArtworkUrl = action.artworkUrl) } is OnboardingOtherCardsAction.SetStepOfScreen -> { if (action.step != state.currentStep && state.steps.contains(action.step)) { diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsState.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsState.kt index b306101506..f502350050 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsState.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsState.kt @@ -1,6 +1,5 @@ package com.tangem.tap.features.onboarding.products.otherCards.redux -import com.tangem.tap.features.wallet.redux.Artwork import org.rekotlin.StateType /** @@ -8,7 +7,7 @@ import org.rekotlin.StateType */ data class OnboardingOtherCardsState( // UI - val cardArtwork: Artwork? = null, + val cardArtworkUrl: String? = null, val showConfetti: Boolean = false, val currentStep: OnboardingOtherCardsStep = OnboardingOtherCardsStep.None, val steps: List = OnboardingOtherCardsStep.values().toList(), 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 1d18eb4dec..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 @@ -29,7 +29,10 @@ private fun internalReduce(action: Action, state: AppState): TwinCardsState { } } is TwinCardsAction.SetMode -> { - state = state.copy(mode = action.mode) + state = state.copy( + mode = action.mode, + userWasUnderstandIfWalletRecreate = false, + ) } is TwinCardsAction.SetStepOfScreen -> { state = state.copy(currentStep = action.step) @@ -52,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 dee8230f9f..81e11f7e47 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 @@ -77,18 +77,20 @@ class TwinsCardsFragment : BaseOnboardingFragment() { addBackPressHandler(this) reconfigureLayoutForTwins() - twinsWidget = TwinsCardWidget(LeapfrogWidget(cards_container)) { 250f } + twinsWidget = TwinsCardWidget(LeapfrogWidget(cards_container)) { 285f } btnRefreshBalanceWidget = RefreshBalanceWidget(onboarding_main_container) toolbar.title = getText(R.string.twins_recreate_toolbar) Picasso.get() .load(Artwork.TWIN_CARD_1) + .error(R.drawable.card_placeholder_black) .placeholder(R.drawable.card_placeholder_black) ?.into(imv_twin_front_card) Picasso.get() .load(Artwork.TWIN_CARD_2) + .error(R.drawable.card_placeholder_white) .placeholder(R.drawable.card_placeholder_white) ?.into(imv_twin_back_card) } @@ -114,11 +116,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 +138,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) { @@ -287,6 +288,7 @@ class TwinsCardsFragment : BaseOnboardingFragment() { store.dispatch(TwinCardsAction.TopUp) } + btn_alternative_action.isVisible = true btn_alternative_action.setText(R.string.onboarding_top_up_button_show_wallet_address) btn_alternative_action.setOnClickListener { store.dispatch(TwinCardsAction.ShowAddressInfoDialog) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt index 513627f250..9ec6e10f13 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt @@ -147,7 +147,7 @@ class WalletMiddleware { WalletAction.LoadArtwork(action.card, response.data.artwork?.id), GlobalAction.SetIfCardVerifiedOnline(response.data.passed) ) - actionList.forEach { store.dispatch(it) } + withMainContext { actionList.forEach { store.dispatch(it) } } } is Result.Failure -> { store.dispatchOnMain(GlobalAction.SetIfCardVerifiedOnline(false)) diff --git a/app/src/main/res/drawable/shape_circle_home_screen.xml b/app/src/main/res/drawable/shape_circle_home_screen.xml new file mode 100644 index 0000000000..6cc2f8cc4e --- /dev/null +++ b/app/src/main/res/drawable/shape_circle_home_screen.xml @@ -0,0 +1,14 @@ + + + + + + + diff --git a/app/src/main/res/layout/dialog_onboarding_address_info.xml b/app/src/main/res/layout/dialog_onboarding_address_info.xml index 92c780e969..a3c34a8f06 100644 --- a/app/src/main/res/layout/dialog_onboarding_address_info.xml +++ b/app/src/main/res/layout/dialog_onboarding_address_info.xml @@ -1,6 +1,7 @@ @@ -68,10 +69,12 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="middle" + android:fontFamily="sans-serif-medium" android:maxWidth="170dp" android:minWidth="120dp" android:singleLine="true" - android:text="addlkasLNXDLKNnkjkjhnjkjnljnnlsenn" /> + android:textSize="15sp" + tools:text="addlkasLNXDLKNnkjkjhnjkjnljnnlsenn" /> + android:layout_height="match_parent" + android:clipChildren="false"> + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/view_onboarding_progress.xml b/app/src/main/res/layout/view_onboarding_progress.xml index 8b2e151d1a..6dbac9141f 100644 --- a/app/src/main/res/layout/view_onboarding_progress.xml +++ b/app/src/main/res/layout/view_onboarding_progress.xml @@ -6,8 +6,8 @@ style="@style/Widget.AppCompat.ProgressBar.Horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginStart="32dp" - android:layout_marginTop="16dp" - android:layout_marginEnd="32dp" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:progressBackgroundTint="#401ACE80" android:progressTint="@color/accent" /> diff --git a/app/src/main/res/layout/view_onboarding_refresh_balance.xml b/app/src/main/res/layout/view_onboarding_refresh_balance.xml index c9bf3aacb2..88daba2ce2 100644 --- a/app/src/main/res/layout/view_onboarding_refresh_balance.xml +++ b/app/src/main/res/layout/view_onboarding_refresh_balance.xml @@ -4,7 +4,6 @@ android:id="@+id/btn_refresh_balance" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:background="?attr/selectableItemBackgroundBorderless" android:clickable="true" android:focusable="true"> diff --git a/app/src/main/res/layout/view_onboarding_tv_balance.xml b/app/src/main/res/layout/view_onboarding_tv_balance.xml index 6577933837..2825b6d930 100644 --- a/app/src/main/res/layout/view_onboarding_tv_balance.xml +++ b/app/src/main/res/layout/view_onboarding_tv_balance.xml @@ -14,15 +14,21 @@ android:layout_height="wrap_content" android:elevation="0dp" android:fontFamily="sans-serif-medium" + android:letterSpacing="0.036" android:text="@string/onboarding_balance_title" android:textAllCaps="true" android:textColor="#ABABAB" android:textSize="14sp" /> + + diff --git a/app/src/main/res/values/strings_untranslated.xml b/app/src/main/res/values/strings_untranslated.xml index cb9cdc7224..d34ea02c07 100644 --- a/app/src/main/res/values/strings_untranslated.xml +++ b/app/src/main/res/values/strings_untranslated.xml @@ -14,7 +14,7 @@ Tangem Twin One wallet. Two cards. - This one that you are holding in your handsand the other one with number #%s. + This one that you are holding in your hands and the other one with number #%s. Card %s of 2 @@ -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 + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index fe7f02a527..43173d1bad 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -90,12 +90,14 @@