From 35f4f97408d1325dca93b2ac4306d58ba2173fb4 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 23 Mar 2026 16:08:03 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../com/tangem/tap/common/DialogManager.kt | 19 ----- .../com/tangem/tap/common/redux/AppDialog.kt | 9 --- .../com/tangem/tap/common/redux/AppState.kt | 2 - .../products/wallet/redux/BackupDialog.kt | 14 ---- .../products/wallet/redux/BackupMiddleware.kt | 63 --------------- .../wallet/redux/OnboardingWalletAction.kt | 19 ----- .../dialogs/ConfirmDiscardingBackupDialog.kt | 29 ------- .../ui/dialogs/UnfinishedBackupFoundDialog.kt | 33 -------- .../component/impl/DefaultRoutingComponent.kt | 77 ++++++++++++++++++- 9 files changed, 73 insertions(+), 192 deletions(-) delete mode 100644 app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/BackupDialog.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/BackupMiddleware.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/ConfirmDiscardingBackupDialog.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/UnfinishedBackupFoundDialog.kt diff --git a/app/src/main/java/com/tangem/tap/common/DialogManager.kt b/app/src/main/java/com/tangem/tap/common/DialogManager.kt index c863320c2a..c3a367a894 100644 --- a/app/src/main/java/com/tangem/tap/common/DialogManager.kt +++ b/app/src/main/java/com/tangem/tap/common/DialogManager.kt @@ -7,12 +7,8 @@ import com.tangem.tap.common.redux.AppDialog import com.tangem.tap.common.redux.global.GlobalState import com.tangem.tap.common.ui.ScanFailsDialog import com.tangem.tap.common.ui.SimpleAlertDialog -import com.tangem.tap.common.ui.SimpleCancelableAlertDialog import com.tangem.tap.common.ui.SimpleOkDialog import com.tangem.tap.features.onboarding.OnboardingDialog -import com.tangem.tap.features.onboarding.products.wallet.redux.BackupDialog -import com.tangem.tap.features.onboarding.products.wallet.ui.dialogs.ConfirmDiscardingBackupDialog -import com.tangem.tap.features.onboarding.products.wallet.ui.dialogs.UnfinishedBackupFoundDialog import com.tangem.tap.features.onboarding.products.wallet.ui.dialogs.WalletActivationErrorDialog import com.tangem.tap.features.onboarding.products.wallet.ui.dialogs.WalletAlreadyWasUsedDialog import com.tangem.tap.store @@ -60,14 +56,6 @@ class DialogManager : StoreSubscriber { context = context, ) is OnboardingDialog.WalletActivationError -> WalletActivationErrorDialog.create(context, state.dialog) - is BackupDialog.UnfinishedBackupFound -> UnfinishedBackupFoundDialog.create( - context = context, - scanResponse = state.dialog.scanResponse, - ) - is BackupDialog.ConfirmDiscardingBackup -> ConfirmDiscardingBackupDialog.create( - context = context, - unfinishedBackupScanResponse = state.dialog.scanResponse, - ) is AppDialog.TokensAreLinkedDialog -> SimpleAlertDialog.create( title = context.getString(state.dialog.titleRes, state.dialog.currencySymbol), message = context.getString( @@ -84,13 +72,6 @@ class DialogManager : StoreSubscriber { onSupport = state.dialog.onSupportClick, onCancel = state.dialog.onCancel, ) - is AppDialog.RemoveWalletDialog -> SimpleCancelableAlertDialog.create( - title = context.getString(state.dialog.titleRes, state.dialog.currencyTitle), - messageRes = state.dialog.messageRes, - context = context, - primaryButtonRes = state.dialog.primaryButtonRes, - primaryButtonAction = state.dialog.onOk, - ) else -> null } dialog?.show() diff --git a/app/src/main/java/com/tangem/tap/common/redux/AppDialog.kt b/app/src/main/java/com/tangem/tap/common/redux/AppDialog.kt index 8c9f98ebdd..69ef67c88a 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/AppDialog.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/AppDialog.kt @@ -15,15 +15,6 @@ sealed class AppDialog : StateDialog { val onOk: VoidCallback? = null, ) : AppDialog() - data class RemoveWalletDialog( - val currencyTitle: String, - val onOk: () -> Unit, - ) : AppDialog() { - val messageRes: Int = R.string.token_details_hide_alert_message - val titleRes: Int = R.string.token_details_hide_alert_title - val primaryButtonRes: Int = R.string.token_details_hide_alert_hide - } - data class TokensAreLinkedDialog( val currencyTitle: String, val currencySymbol: String, diff --git a/app/src/main/java/com/tangem/tap/common/redux/AppState.kt b/app/src/main/java/com/tangem/tap/common/redux/AppState.kt index ae347d0807..89851458ac 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/AppState.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/AppState.kt @@ -5,7 +5,6 @@ import com.tangem.tap.common.redux.global.GlobalState import com.tangem.tap.common.redux.legacy.LegacyMiddleware import com.tangem.tap.features.details.redux.DetailsMiddleware import com.tangem.tap.features.details.redux.DetailsState -import com.tangem.tap.features.onboarding.products.wallet.redux.BackupMiddleware import com.tangem.tap.proxy.redux.DaggerGraphMiddleware import com.tangem.tap.proxy.redux.DaggerGraphState import org.rekotlin.Middleware @@ -23,7 +22,6 @@ data class AppState( logMiddleware, GlobalMiddleware.handler, DetailsMiddleware().detailsMiddleware, - BackupMiddleware().backupMiddleware, LockUserWalletsTimerMiddleware().middleware, AccessCodeRequestPolicyMiddleware().middleware, DaggerGraphMiddleware.daggerGraphMiddleware, diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/BackupDialog.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/BackupDialog.kt deleted file mode 100644 index ef465fad15..0000000000 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/BackupDialog.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.tangem.tap.features.onboarding.products.wallet.redux - -import com.tangem.domain.models.scan.ScanResponse -import com.tangem.domain.redux.StateDialog - -sealed class BackupDialog : StateDialog { - data class UnfinishedBackupFound( - val scanResponse: ScanResponse? = null, - ) : BackupDialog() - - data class ConfirmDiscardingBackup( - val scanResponse: ScanResponse? = null, - ) : BackupDialog() -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/BackupMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/BackupMiddleware.kt deleted file mode 100644 index e0e8bd6b12..0000000000 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/BackupMiddleware.kt +++ /dev/null @@ -1,63 +0,0 @@ -package com.tangem.tap.features.onboarding.products.wallet.redux - -import com.tangem.common.routing.AppRoute -import com.tangem.core.analytics.Analytics -import com.tangem.tap.backupService -import com.tangem.tap.common.analytics.events.Onboarding.Finished -import com.tangem.tap.common.extensions.dispatchNavigationAction -import com.tangem.tap.common.extensions.inject -import com.tangem.tap.common.redux.AppState -import com.tangem.tap.features.demo.DemoHelper -import com.tangem.tap.mainScope -import com.tangem.tap.proxy.redux.DaggerGraphState -import com.tangem.tap.store -import kotlinx.coroutines.launch -import org.rekotlin.Middleware - -@Suppress("MemberNameEqualsClassName") -class BackupMiddleware { - val backupMiddleware: Middleware = { dispatch, state -> - { next -> - { action -> - if (action is BackupAction) handleBackupAction(state, action) - next(action) - } - } - } -} - -@Suppress("LongMethod", "ComplexMethod", "MagicNumber") -private fun handleBackupAction(appState: () -> AppState?, action: BackupAction) { - if (DemoHelper.tryHandle(appState)) return - - when (action) { - is BackupAction.DiscardBackup -> { - backupService.discardSavedBackup() - } - is BackupAction.DiscardSavedBackup -> { - mainScope.launch { - backupService.discardSavedBackup() - - val onboardingRepository = store.inject(DaggerGraphState::onboardingRepository) - val cardRepository = store.inject(DaggerGraphState::cardRepository) - val unfinishedBackup = onboardingRepository.getUnfinishedFinalizeOnboarding() ?: return@launch - - cardRepository.finishCardActivation(unfinishedBackup.card.cardId) - onboardingRepository.clearUnfinishedFinalizeOnboarding() - Analytics.send(Finished()) - } - } - is BackupAction.ResumeFoundUnfinishedBackup -> { - if (action.unfinishedBackupScanResponse != null) { - store.dispatchNavigationAction { - replaceAll( - AppRoute.Onboarding( - scanResponse = action.unfinishedBackupScanResponse, - mode = AppRoute.Onboarding.Mode.ContinueFinalize, - ), - ) - } - } - } - } -} \ No newline at end of file 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 deleted file mode 100644 index db39ad8c56..0000000000 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.tangem.tap.features.onboarding.products.wallet.redux - -import com.tangem.domain.models.scan.ScanResponse -import com.tangem.domain.models.wallet.UserWalletId -import org.rekotlin.Action - -sealed class OnboardingWalletAction : Action { - data class WalletSaved(val userWalletId: UserWalletId) : OnboardingWalletAction() -} - -sealed class BackupAction : Action { - - data object DiscardBackup : BackupAction() - data object DiscardSavedBackup : BackupAction() - - data class ResumeFoundUnfinishedBackup( - val unfinishedBackupScanResponse: ScanResponse?, - ) : BackupAction() -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/ConfirmDiscardingBackupDialog.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/ConfirmDiscardingBackupDialog.kt deleted file mode 100644 index 9f5257bd04..0000000000 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/ConfirmDiscardingBackupDialog.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.tangem.tap.features.onboarding.products.wallet.ui.dialogs - -import android.content.Context -import androidx.appcompat.app.AlertDialog -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import com.tangem.domain.models.scan.ScanResponse -import com.tangem.tap.common.redux.global.GlobalAction -import com.tangem.tap.features.onboarding.products.wallet.redux.BackupAction -import com.tangem.tap.store -import com.tangem.wallet.R - -object ConfirmDiscardingBackupDialog { - fun create(context: Context, unfinishedBackupScanResponse: ScanResponse? = null): AlertDialog { - return MaterialAlertDialogBuilder(context, R.style.CustomMaterialDialog).apply { - setTitle(R.string.welcome_interrupted_backup_discard_title) - setMessage(R.string.welcome_interrupted_backup_discard_message) - setPositiveButton(R.string.welcome_interrupted_backup_discard_resume) { _, _ -> - store.dispatch(BackupAction.ResumeFoundUnfinishedBackup(unfinishedBackupScanResponse)) - } - setNegativeButton(R.string.welcome_interrupted_backup_discard_discard) { _, _ -> - store.dispatch(BackupAction.DiscardSavedBackup) - } - setOnDismissListener { - store.dispatch(GlobalAction.HideDialog) - } - setCancelable(false) - }.create() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/UnfinishedBackupFoundDialog.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/UnfinishedBackupFoundDialog.kt deleted file mode 100644 index df8cc61880..0000000000 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/UnfinishedBackupFoundDialog.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.tangem.tap.features.onboarding.products.wallet.ui.dialogs - -import android.content.Context -import androidx.appcompat.app.AlertDialog -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import com.tangem.core.analytics.Analytics -import com.tangem.domain.models.scan.ScanResponse -import com.tangem.features.onboarding.v2.common.analytics.OnboardingEvent -import com.tangem.tap.common.redux.global.GlobalAction -import com.tangem.tap.features.onboarding.products.wallet.redux.BackupAction -import com.tangem.tap.features.onboarding.products.wallet.redux.BackupDialog -import com.tangem.tap.store -import com.tangem.wallet.R - -object UnfinishedBackupFoundDialog { - fun create(context: Context, scanResponse: ScanResponse? = null): AlertDialog { - return MaterialAlertDialogBuilder(context, R.style.CustomMaterialDialog).apply { - setTitle(R.string.common_warning) - setMessage(R.string.welcome_interrupted_backup_alert_message) - setPositiveButton(R.string.welcome_interrupted_backup_alert_resume) { _, _ -> - Analytics.send(OnboardingEvent.Backup.ResumeInterruptedBackup()) - store.dispatch(GlobalAction.HideDialog) - store.dispatch(BackupAction.ResumeFoundUnfinishedBackup(scanResponse)) - } - setNegativeButton(R.string.welcome_interrupted_backup_alert_discard) { _, _ -> - Analytics.send(OnboardingEvent.Backup.CancelInterruptedBackup()) - store.dispatch(GlobalAction.HideDialog) - store.dispatch(GlobalAction.ShowDialog(BackupDialog.ConfirmDiscardingBackup(scanResponse))) - } - setCancelable(false) - }.create() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/routing/component/impl/DefaultRoutingComponent.kt b/app/src/main/java/com/tangem/tap/routing/component/impl/DefaultRoutingComponent.kt index a4cdba0883..fb71667669 100644 --- a/app/src/main/java/com/tangem/tap/routing/component/impl/DefaultRoutingComponent.kt +++ b/app/src/main/java/com/tangem/tap/routing/component/impl/DefaultRoutingComponent.kt @@ -23,20 +23,25 @@ import com.tangem.core.decompose.navigation.getOrCreateTyped import com.tangem.core.ui.UiDependencies import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resourceReference +import com.tangem.core.ui.message.DialogMessage +import com.tangem.core.ui.message.EventMessageAction import com.tangem.core.ui.message.SnackbarMessage import com.tangem.domain.card.repository.CardRepository import com.tangem.domain.common.wallets.UserWalletsListRepository +import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.models.wallet.isLocked import com.tangem.domain.onboarding.repository.OnboardingRepository import com.tangem.features.hotwallet.HotAccessCodeRequestComponent import com.tangem.features.hotwallet.accesscoderequest.proxy.HotWalletPasswordRequesterProxy +import com.tangem.features.onboarding.v2.common.analytics.OnboardingEvent import com.tangem.features.walletconnect.components.WcRoutingComponent import com.tangem.hot.sdk.TangemHotSdk import com.tangem.hot.sdk.android.create +import com.tangem.sdk.api.BackupServiceHolder import com.tangem.tap.common.SnackbarHandler -import com.tangem.tap.common.redux.global.GlobalAction +import com.tangem.tap.common.analytics.events.Onboarding +import com.tangem.tap.features.demo.DemoHelper import com.tangem.tap.features.hot.TangemHotSDKProxy -import com.tangem.tap.features.onboarding.products.wallet.redux.BackupDialog import com.tangem.tap.features.root.RootDetectedWarningComponent import com.tangem.tap.routing.RootContent import com.tangem.tap.routing.component.RoutingComponent @@ -46,6 +51,7 @@ import com.tangem.tap.routing.utils.ChildFactory import com.tangem.tap.routing.utils.DeepLinkFactory import com.tangem.tap.store import com.tangem.utils.logging.TangemLogger +import com.tangem.wallet.R import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -71,6 +77,7 @@ internal class DefaultRoutingComponent @AssistedInject constructor( private val trackingContextProxy: TrackingContextProxy, private val analyticsEventHandler: AnalyticsEventHandler, private val analyticsExceptionHandler: AnalyticsExceptionHandler, + private val backupServiceHolder: BackupServiceHolder, ) : RoutingComponent, AppComponentContext by context, SnackbarHandler { @@ -251,9 +258,71 @@ internal class DefaultRoutingComponent @AssistedInject constructor( } private fun checkForUnfinishedBackup() { + if (DemoHelper.tryHandle { store.state }) return componentScope.launch(dispatchers.main) { - val onboardingScanResponse = onboardingRepository.getUnfinishedFinalizeOnboarding() ?: return@launch - store.dispatch(GlobalAction.ShowDialog(BackupDialog.UnfinishedBackupFound(onboardingScanResponse))) + val scanResponse = onboardingRepository.getUnfinishedFinalizeOnboarding() ?: return@launch + messageSender.send(unfinishedBackupFoundDialog(scanResponse)) + } + } + + private fun unfinishedBackupFoundDialog(scanResponse: ScanResponse): DialogMessage = DialogMessage( + title = resourceReference(R.string.common_warning), + message = resourceReference(R.string.welcome_interrupted_backup_alert_message), + isDismissable = false, + firstActionBuilder = { + EventMessageAction( + title = resourceReference(R.string.welcome_interrupted_backup_alert_resume), + onClick = { + analyticsEventHandler.send(OnboardingEvent.Backup.ResumeInterruptedBackup()) + resumeUnfinishedBackup(scanResponse) + }, + ) + }, + secondActionBuilder = { + EventMessageAction( + title = resourceReference(R.string.welcome_interrupted_backup_alert_discard), + onClick = { + analyticsEventHandler.send(OnboardingEvent.Backup.CancelInterruptedBackup()) + messageSender.send(confirmDiscardingBackupDialog(scanResponse)) + }, + ) + }, + ) + + private fun confirmDiscardingBackupDialog(scanResponse: ScanResponse): DialogMessage = DialogMessage( + title = resourceReference(R.string.welcome_interrupted_backup_discard_title), + message = resourceReference(R.string.welcome_interrupted_backup_discard_message), + isDismissable = false, + firstActionBuilder = { + EventMessageAction( + title = resourceReference(R.string.welcome_interrupted_backup_discard_resume), + onClick = { resumeUnfinishedBackup(scanResponse) }, + ) + }, + secondActionBuilder = { + EventMessageAction( + title = resourceReference(R.string.welcome_interrupted_backup_discard_discard), + onClick = { discardSavedBackup() }, + ) + }, + ) + + private fun resumeUnfinishedBackup(scanResponse: ScanResponse) { + router.replaceAll( + AppRoute.Onboarding( + scanResponse = scanResponse, + mode = AppRoute.Onboarding.Mode.ContinueFinalize, + ), + ) + } + + private fun discardSavedBackup() { + componentScope.launch(dispatchers.main) { + backupServiceHolder.backupService.get()?.discardSavedBackup() + val unfinishedBackup = onboardingRepository.getUnfinishedFinalizeOnboarding() ?: return@launch + cardRepository.finishCardActivation(unfinishedBackup.card.cardId) + onboardingRepository.clearUnfinishedFinalizeOnboarding() + analyticsEventHandler.send(Onboarding.Finished()) } }