Updated on 2026-08-14
This commit is contained in:
parent
e43f438c1a
commit
35f4f97408
9 changed files with 73 additions and 192 deletions
|
|
@ -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<GlobalState> {
|
|||
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<GlobalState> {
|
|||
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()
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
@ -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<AppState> = { 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,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue