diff --git a/app/src/main/java/com/tangem/tap/common/extensions/BackupService.kt b/app/src/main/java/com/tangem/tap/common/extensions/BackupService.kt new file mode 100644 index 0000000000..90610b1620 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/common/extensions/BackupService.kt @@ -0,0 +1,13 @@ +package com.tangem.tap.common.extensions + +import com.tangem.domain.common.SaltPayWorkaround +import com.tangem.operations.backup.BackupService + +/** +[REDACTED_AUTHOR] + */ +fun BackupService.primaryCardIsSaltPay(): Boolean { + return primaryCardId?.slice(0..3)?.let { + SaltPayWorkaround.isVisaBatchId(it) + } ?: false +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt b/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt index 487362e5c1..839c7a3828 100644 --- a/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt @@ -16,7 +16,6 @@ import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.features.home.compose.StoriesScreen import com.tangem.tap.features.home.redux.HomeAction import com.tangem.tap.features.home.redux.HomeState -import com.tangem.tap.features.onboarding.products.wallet.redux.BackupAction import com.tangem.tap.features.tokens.redux.TokensAction import com.tangem.tap.store import org.rekotlin.StoreSubscriber @@ -38,7 +37,6 @@ class HomeFragment : Fragment(), StoreSubscriber { ): View? { val context = container?.context ?: return null - store.dispatch(BackupAction.CheckForUnfinishedBackup) composeView = ComposeView(context).apply { setContent { AppCompatTheme { diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt index 66016aef08..0a276dff4f 100644 --- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt +++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt @@ -4,14 +4,14 @@ import com.tangem.tap.common.entities.IndeterminateProgressButton import org.rekotlin.Action sealed class HomeAction : Action { + + object Init : HomeAction() + data class ShouldScanCardOnResume(val shouldScanCard: Boolean) : HomeAction() + // from ui object ReadCard : HomeAction() data class ScanInProgress(val scanInProgress: Boolean) : HomeAction() data class GoToShop(val userCountryCode: String?) : HomeAction() - // internal - data class ShouldScanCardOnResume(val shouldScanCard: Boolean) : HomeAction() - object Init : HomeAction() - data class ChangeScanCardButtonState(val state: IndeterminateProgressButton) : HomeAction() } diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt index ef916d18c7..e7be6e2145 100644 --- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt @@ -31,6 +31,7 @@ import com.tangem.tap.features.onboarding.OnboardingHelper import com.tangem.tap.features.onboarding.OnboardingSaltPayHelper import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsStep +import com.tangem.tap.features.onboarding.products.wallet.redux.BackupAction import com.tangem.tap.features.onboarding.products.wallet.saltPay.SaltPayExceptionHandler import com.tangem.tap.features.onboarding.products.wallet.saltPay.redux.OnboardingSaltPayAction import com.tangem.tap.features.onboarding.products.wallet.saltPay.redux.OnboardingSaltPayState @@ -68,6 +69,7 @@ private fun handleHomeAction(appState: () -> AppState?, action: Action, dispatch store.dispatch(GlobalAction.RestoreAppCurrency) store.dispatch(GlobalAction.ExchangeManager.Init) store.dispatch(GlobalAction.FetchUserCountry) + store.dispatch(BackupAction.CheckForUnfinishedBackup) } is HomeAction.ShouldScanCardOnResume -> { if (action.shouldScanCard) { @@ -78,9 +80,17 @@ private fun handleHomeAction(appState: () -> AppState?, action: Action, dispatch is HomeAction.ReadCard -> { changeButtonState(ButtonState.PROGRESS) val scanCardAction = GlobalAction.ScanCard( - onSuccess = { + onSuccess = { scanResponse -> store.dispatch(HomeAction.ScanInProgress(false)) - checkForDisclaimer(it, ::onScanSuccess) + checkForUnfinishedBackupForSaltPay( + scanResponse = scanResponse, + nextHandler = { + showDisclaimerIfNeed( + scanResponse = scanResponse, + nextHandler = ::onScanSuccess, + ) + }, + ) }, onFailure = ::onScanFailure, ) @@ -100,18 +110,35 @@ private fun handleHomeAction(appState: () -> AppState?, action: Action, dispatch } } -private fun checkForDisclaimer(scanResponse: ScanResponse, onDisclaimerAccepted: (ScanResponse) -> Unit) { +/** + * It checks only the SaltPay cards. To check for unfinished backups for the standard Wallet cards + * see BackupAction.CheckForUnfinishedBackup + * If user touches card other than Visa SaltPay - show dialog and block next processing + */ +private fun checkForUnfinishedBackupForSaltPay(scanResponse: ScanResponse, nextHandler: (ScanResponse) -> Unit) { + if (BackupAction.hasSaltPayUnfinishedBackup()) { + if (scanResponse.isSaltPayVisa()) { + nextHandler(scanResponse) + } else { + showSaltPayTapVisaLogoCardDialog() + } + } else { + nextHandler(scanResponse) + } +} + +private fun showDisclaimerIfNeed(scanResponse: ScanResponse, nextHandler: (ScanResponse) -> Unit) { val disclaimerType = DisclaimerType.get(scanResponse) store.dispatch(DisclaimerAction.SetDisclaimerType(disclaimerType)) if (disclaimerType.isAccepted()) { - onDisclaimerAccepted((scanResponse)) + nextHandler((scanResponse)) } else { changeButtonState(ButtonState.ENABLED) store.dispatch( DisclaimerAction.Show { changeButtonState(ButtonState.PROGRESS) - onDisclaimerAccepted(scanResponse) + nextHandler(scanResponse) }, ) } @@ -156,12 +183,7 @@ private fun onScanSuccess(scanResponse: ScanResponse) { } else { if (scanResponse.card.backupStatus?.isActive == false) { changeButtonState(ButtonState.ENABLED) - store.dispatchDialogShow( - AppDialog.SimpleOkDialogRes( - headerId = R.string.saltpay_error_empty_backup_title, - messageId = R.string.saltpay_error_empty_backup_message, - ), - ) + showSaltPayTapVisaLogoCardDialog() } else { navigateTo(AppScreen.Wallet, null) scope.launch { store.onCardScanned(scanResponse) } @@ -184,6 +206,15 @@ private fun onScanSuccess(scanResponse: ScanResponse) { } } +private fun showSaltPayTapVisaLogoCardDialog() { + store.dispatchDialogShow( + AppDialog.SimpleOkDialogRes( + headerId = R.string.saltpay_error_empty_backup_title, + messageId = R.string.saltpay_error_empty_backup_message, + ), + ) +} + private fun onScanFailure(error: TangemError) { store.dispatch(HomeAction.ScanInProgress(false)) changeButtonState(ButtonState.ENABLED) diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt index 885f57fa99..0de2a90471 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt @@ -1,6 +1,8 @@ package com.tangem.tap.features.onboarding.products.wallet.redux import android.graphics.Bitmap +import com.tangem.tap.backupService +import com.tangem.tap.common.extensions.primaryCardIsSaltPay import org.rekotlin.Action sealed class OnboardingWalletAction : Action { @@ -69,4 +71,10 @@ sealed class BackupAction : Action { object DiscardBackup : BackupAction() object DiscardSavedBackup : BackupAction() object ResumeFoundUnfinishedBackup : BackupAction() + + companion object { + fun hasSaltPayUnfinishedBackup(): Boolean { + return backupService.hasIncompletedBackup && backupService.primaryCardIsSaltPay() + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt index 148b1061a5..397eaf9a9e 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt @@ -4,13 +4,13 @@ import com.tangem.blockchain.common.Blockchain import com.tangem.common.CompletionResult import com.tangem.common.card.Card import com.tangem.common.extensions.ifNotNull -import com.tangem.domain.common.SaltPayWorkaround import com.tangem.domain.common.ScanResponse import com.tangem.domain.common.extensions.withMainContext import com.tangem.operations.backup.BackupService import com.tangem.tap.backupService import com.tangem.tap.common.extensions.dispatchDialogShow import com.tangem.tap.common.extensions.dispatchOnMain +import com.tangem.tap.common.extensions.primaryCardIsSaltPay import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.common.redux.navigation.AppScreen @@ -344,12 +344,6 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction) } } -private fun BackupService.primaryCardIsSaltPay(): Boolean { - return primaryCardId?.slice(0..3)?.let { - SaltPayWorkaround.isVisaBatchId(it) - } ?: false -} - /** * SaltPay state maybe not initialized if backup resumed from ResumeFoundUnfinishedBackup action */ @@ -358,7 +352,6 @@ private fun initSaltPayOnBackupFinishedIfNeeded( onboardingWalletState: OnboardingWalletState, ) { if (onboardingWalletState.isSaltPay && onboardingWalletState.onboardingSaltPayState == null) { - //TODO: SaltPay: scanResponse if (scanResponse == null) throw IllegalArgumentException() val (manager, config) = OnboardingSaltPayState.initDependency(scanResponse)