diff --git a/core/ui/src/main/java/com/tangem/core/ui/message/EventMessage.kt b/core/ui/src/main/java/com/tangem/core/ui/message/EventMessage.kt index 173b9d2094..3da6b245e1 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/message/EventMessage.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/message/EventMessage.kt @@ -246,7 +246,8 @@ data class EventMessageAction( * * @param onClick The action to perform when the button is clicked. By default, it dismisses the message. * */ - fun cancelAction(onClick: () -> Unit = onDismissRequest) = EventMessageAction( + fun cancelAction(isWarning: Boolean = false, onClick: () -> Unit = onDismissRequest) = EventMessageAction( + isWarning = isWarning, title = resourceReference(id = R.string.common_cancel), onClick = onClick, ) diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/DefaultUpgradeWalletComponent.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/DefaultUpgradeWalletComponent.kt index 3775021494..dd8b450432 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/DefaultUpgradeWalletComponent.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/DefaultUpgradeWalletComponent.kt @@ -28,6 +28,7 @@ internal class DefaultUpgradeWalletComponent @AssistedInject constructor( private val resetCardsComponent = resetCardsComponentFactory.create( context = child("ResetCardsComponent"), params = ResetCardsComponent.Params( + source = ResetCardsComponent.Params.Source.Upgrade, callbacks = model.resetCardsComponentCallbacks, ), ) diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/UpgradeWalletModel.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/UpgradeWalletModel.kt index dcaa94647a..9b177bc926 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/UpgradeWalletModel.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/UpgradeWalletModel.kt @@ -202,7 +202,7 @@ internal class UpgradeWalletModel @Inject constructor( } override fun onComplete() { - setLoading(false) + scanCard() } } } \ No newline at end of file diff --git a/features/onboarding-v2/api/src/main/kotlin/com/tangem/features/onboarding/v2/util/ResetCardsComponent.kt b/features/onboarding-v2/api/src/main/kotlin/com/tangem/features/onboarding/v2/util/ResetCardsComponent.kt index bd3a3203e2..6524a947c0 100644 --- a/features/onboarding-v2/api/src/main/kotlin/com/tangem/features/onboarding/v2/util/ResetCardsComponent.kt +++ b/features/onboarding-v2/api/src/main/kotlin/com/tangem/features/onboarding/v2/util/ResetCardsComponent.kt @@ -8,8 +8,13 @@ interface ResetCardsComponent { fun startResetCardsFlow(createdUserWallet: UserWallet.Cold) data class Params( + val source: Source, val callbacks: ModelCallbacks, - ) + ) { + enum class Source { + Upgrade, Onboarding, + } + } interface ModelCallbacks { fun onCancel() diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/finalize/MultiWalletFinalizeComponent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/finalize/MultiWalletFinalizeComponent.kt index 824770dc83..5bb2626fe5 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/finalize/MultiWalletFinalizeComponent.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/finalize/MultiWalletFinalizeComponent.kt @@ -36,6 +36,7 @@ internal class MultiWalletFinalizeComponent( private val resetCardsComponent = resetCardsComponentFactory.create( context = child("ResetCardsComponent"), params = ResetCardsComponent.Params( + source = ResetCardsComponent.Params.Source.Onboarding, callbacks = model.resetCardsModelCallbacks, ), ) diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/util/impl/model/ResetCardsModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/util/impl/model/ResetCardsModel.kt index 5a89688e94..ac0415702a 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/util/impl/model/ResetCardsModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/util/impl/model/ResetCardsModel.kt @@ -1,6 +1,5 @@ package com.tangem.features.onboarding.v2.util.impl.model -import com.tangem.common.CompletionResult import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer @@ -8,12 +7,13 @@ import com.tangem.core.decompose.ui.UiMessageSender import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.message.DialogMessage import com.tangem.core.ui.message.EventMessageAction +import com.tangem.domain.card.ResetCardUseCase +import com.tangem.domain.card.ResetCardUserCodeParams import com.tangem.domain.card.common.util.getBackupCardsCount import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId import com.tangem.features.onboarding.v2.impl.R import com.tangem.features.onboarding.v2.util.ResetCardsComponent -import com.tangem.sdk.api.TangemSdkManager import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.coroutines.JobHolder import com.tangem.utils.coroutines.saveIn @@ -26,7 +26,7 @@ import kotlin.coroutines.resume internal class ResetCardsModel @Inject constructor( paramsContainer: ParamsContainer, override val dispatchers: CoroutineDispatcherProvider, - private val tangemSdkManager: TangemSdkManager, + private val resetCardUseCase: ResetCardUseCase, private val uiMessageSender: UiMessageSender, ) : Model() { @@ -41,14 +41,19 @@ internal class ResetCardsModel @Inject constructor( } private suspend fun startFullResetFlow(createdUserWallet: UserWallet.Cold) { + val userCodeParams = ResetCardUserCodeParams( + isAccessCodeSet = createdUserWallet.scanResponse.card.isAccessCodeSet, + isPasscodeSet = createdUserWallet.scanResponse.card.isPasscodeSet, + ) + suspendCancellableCoroutine { continuation -> uiMessageSender.send( DialogMessage.invoke( title = resourceReference(R.string.reset_cards_dialog_first_title), - isDismissable = false, + isDismissable = true, message = resourceReference(R.string.reset_cards_dialog_first_description), firstActionBuilder = { - cancelAction { + cancelAction(isWarning = true) { callbacks.onCancel() onDismissRequest() continuation.resume(Unit) @@ -57,13 +62,13 @@ internal class ResetCardsModel @Inject constructor( secondActionBuilder = { EventMessageAction( title = resourceReference(R.string.card_settings_action_sheet_reset), - isWarning = true, + isWarning = false, onClick = { modelScope.launch { - repeatUntilTrue { resetPrimaryCard(createdUserWallet) } + repeatUntilTrue { resetPrimaryCard(createdUserWallet, userCodeParams) } continuation.resume(Unit) onDismissRequest() - startResetBackupCardsFlow(createdUserWallet) + startResetBackupCardsFlow(createdUserWallet, userCodeParams) } }, ) @@ -74,7 +79,10 @@ internal class ResetCardsModel @Inject constructor( } } - private suspend fun startResetBackupCardsFlow(createdUserWallet: UserWallet.Cold) { + private suspend fun startResetBackupCardsFlow( + createdUserWallet: UserWallet.Cold, + userCodeParams: ResetCardUserCodeParams, + ) { val backupCardsCount = createdUserWallet.scanResponse.getBackupCardsCount() ?: 0 if (backupCardsCount == 0) { @@ -82,6 +90,8 @@ internal class ResetCardsModel @Inject constructor( return } + var canceled = false + repeat(backupCardsCount) { index -> suspendCancellableCoroutine { continuation -> uiMessageSender.send( @@ -90,23 +100,43 @@ internal class ResetCardsModel @Inject constructor( isDismissable = false, message = resourceReference(R.string.reset_cards_dialog_next_device_description), firstActionBuilder = { - cancelAction { - callbacks.onCancel() + cancelAction(isWarning = true) { onDismissRequest() - continuation.resume(Unit) + recommendResetAgain( + onCancel = { + canceled = true + callbacks.onCancel() + continuation.resume(Unit) + }, + onReset = onReset@{ + modelScope.launch { + repeatUntilTrue { + resetBackupCard( + cardNumber = index + 2, + params = userCodeParams, + userWalletId = createdUserWallet.walletId, + ) + } + this@onReset.onDismissRequest() + continuation.resume(Unit) + } + }, + ) } }, secondActionBuilder = { EventMessageAction( title = resourceReference(R.string.card_settings_action_sheet_reset), - isWarning = true, onClick = { modelScope.launch { - repeatUntilTrue { resetBackupCard(index + 1, createdUserWallet.walletId) } - onDismissRequest() - if (index == backupCardsCount - 1) { - completeResetFlow() + repeatUntilTrue { + resetBackupCard( + cardNumber = index + 2, + params = userCodeParams, + userWalletId = createdUserWallet.walletId, + ) } + onDismissRequest() continuation.resume(Unit) } }, @@ -116,7 +146,35 @@ internal class ResetCardsModel @Inject constructor( ), ) } + + if (canceled) return } + + completeResetFlow() + } + + private fun recommendResetAgain(onCancel: () -> Unit, onReset: EventMessageAction.BuilderScope.() -> Unit) { + uiMessageSender.send( + DialogMessage.invoke( + title = resourceReference(R.string.card_reset_alert_incomplete_title), + isDismissable = false, + message = resourceReference(R.string.card_reset_alert_incomplete_message), + firstActionBuilder = { + cancelAction(isWarning = true) { + onCancel() + onDismissRequest() + } + }, + secondActionBuilder = { + EventMessageAction( + title = resourceReference(R.string.card_settings_action_sheet_reset), + onClick = { + onReset() + }, + ) + }, + ), + ) } private suspend fun completeResetFlow() { @@ -125,10 +183,20 @@ internal class ResetCardsModel @Inject constructor( DialogMessage.invoke( title = resourceReference(R.string.card_settings_completed_reset_alert_title), isDismissable = false, - message = resourceReference(R.string.reset_cards_dialog_complete_description), + message = when (params.source) { + ResetCardsComponent.Params.Source.Upgrade -> + resourceReference(R.string.card_reset_alert_finish_message) + ResetCardsComponent.Params.Source.Onboarding -> + resourceReference(R.string.card_settings_completed_reset_alert_message) + }, firstActionBuilder = { EventMessageAction( - title = resourceReference(R.string.common_done), + title = when (params.source) { + ResetCardsComponent.Params.Source.Upgrade -> + resourceReference(R.string.card_reset_alert_finish_ok_button) + ResetCardsComponent.Params.Source.Onboarding -> + resourceReference(R.string.common_done) + }, onClick = { modelScope.launch { onDismissRequest() @@ -144,26 +212,30 @@ internal class ResetCardsModel @Inject constructor( } } - private suspend fun resetPrimaryCard(createdUserWallet: UserWallet.Cold): Boolean { + private suspend fun resetPrimaryCard( + createdUserWallet: UserWallet.Cold, + params: ResetCardUserCodeParams, + ): Boolean { val scanResponse = createdUserWallet.scanResponse - val result = tangemSdkManager.resetToFactorySettings( + val result = resetCardUseCase.invoke( cardId = scanResponse.card.cardId, - allowsRequestAccessCodeFromRepository = true, + params = params, ) - return when (result) { - is CompletionResult.Failure -> false - is CompletionResult.Success -> true - } + return result.isRight() } - private suspend fun resetBackupCard(cardIndex: Int, userWalletId: UserWalletId): Boolean { - val result = tangemSdkManager.resetBackupCard(cardIndex, userWalletId) - return when (result) { - is CompletionResult.Failure -> false - is CompletionResult.Success -> true - } + private suspend fun resetBackupCard( + cardNumber: Int, + params: ResetCardUserCodeParams, + userWalletId: UserWalletId, + ): Boolean { + return resetCardUseCase.invoke( + cardNumber = cardNumber, + params, + userWalletId, + ).isRight() } private inline fun repeatUntilTrue(action: () -> Boolean) {