Updated on 2026-08-14

This commit is contained in:
Tangem 2024-10-04 17:29:01 +05:00
parent 7228c72553
commit 5b60d94e60
29 changed files with 1034 additions and 110 deletions

View file

@ -12,6 +12,7 @@ import com.tangem.common.extensions.toMapKey
import com.tangem.crypto.hdWallet.DerivationPath
import com.tangem.data.common.currency.getNetwork
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.card.BackendId
import com.tangem.domain.card.repository.DerivationsRepository
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.domain.tokens.model.CryptoCurrency
@ -73,15 +74,15 @@ internal class DefaultDerivationsRepository(
override suspend fun hasMissedDerivations(
userWalletId: UserWalletId,
networksWithDerivationPath: Map<Network.ID, String?>,
networksWithDerivationPath: Map<BackendId, String?>,
): Boolean {
val userWallet = userWalletsStore.getSyncOrNull(userWalletId) ?: error("User wallet not found")
val derivations = MissedDerivationsFinder(scanResponse = userWallet.scanResponse)
.findByNetworks(
networksWithDerivationPath.mapNotNull { (networkId, extraDerivationPath) ->
networksWithDerivationPath.mapNotNull { (backendId, extraDerivationPath) ->
getNetwork(
blockchain = Blockchain.fromNetworkId(networkId.value) ?: return@mapNotNull null,
blockchain = Blockchain.fromNetworkId(backendId) ?: return@mapNotNull null,
extraDerivationPath = extraDerivationPath,
scanResponse = userWallet.scanResponse,
)

View file

@ -23,6 +23,7 @@ import com.tangem.tap.common.extensions.*
import com.tangem.tap.common.redux.AppDialog
import com.tangem.tap.common.redux.global.GlobalState
import com.tangem.tap.features.demo.DemoHelper
import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletAction
import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE
import com.tangem.tap.features.saveWallet.redux.SaveWalletAction
import com.tangem.tap.mainScope
@ -82,6 +83,56 @@ object OnboardingHelper {
}
}
fun saveWallet(
scanResponse: ScanResponse,
accessCode: String? = null,
backupCardsIds: List<String>? = null,
hasBackupError: Boolean = false,
) {
Analytics.setContext(scanResponse)
scope.launch {
val settingsRepository = store.inject(DaggerGraphState::settingsRepository)
when {
// When should save user wallets, then save card without navigate to save wallet screen
store.inject(DaggerGraphState::walletsRepository).shouldSaveUserWalletsSync() -> {
store.dispatchWithMain(
SaveWalletAction.ProvideBackupInfo(
scanResponse = scanResponse,
accessCode = accessCode,
backupCardsIds = backupCardsIds?.toSet(),
),
)
store.dispatchWithMain(
SaveWalletAction.SaveWalletAfterBackup(
hasBackupError = hasBackupError,
shouldNavigateToWallet = false,
),
)
}
// When should not save user wallets but device has biometry and save wallet screen has not been shown,
// then open save wallet screen
tangemSdkManager.checkCanUseBiometry() && settingsRepository.shouldShowSaveUserWalletScreen() -> {
proceedWithScanResponse(scanResponse, backupCardsIds, hasBackupError)
delay(timeMillis = 1_200)
store.dispatchOnMain(
SaveWalletAction.ProvideBackupInfo(
scanResponse = scanResponse,
accessCode = accessCode,
backupCardsIds = backupCardsIds?.toSet(),
),
)
}
// If device has no biometry and save wallet screen has been shown, then go through old scenario
else -> {
proceedWithScanResponse(scanResponse, backupCardsIds, hasBackupError)
}
}
}
}
fun trySaveWalletAndNavigateToWalletScreen(
scanResponse: ScanResponse,
accessCode: String? = null,
@ -103,7 +154,12 @@ object OnboardingHelper {
),
)
store.dispatchWithMain(SaveWalletAction.SaveWalletAfterBackup(hasBackupError))
store.dispatchWithMain(
SaveWalletAction.SaveWalletAfterBackup(
hasBackupError = hasBackupError,
shouldNavigateToWallet = true,
),
)
}
// When should not save user wallets but device has biometry and save wallet screen has not been shown,
// then open save wallet screen
@ -200,6 +256,7 @@ object OnboardingHelper {
}
.doOnSuccess {
mainScope.launch { store.onUserWalletSelected(userWallet) }
store.dispatch(OnboardingWalletAction.WalletSaved(userWallet.walletId))
}
}
}

View file

@ -2,6 +2,7 @@ package com.tangem.tap.features.onboarding.products.wallet.redux
import android.net.Uri
import com.tangem.common.CompletionResult
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.feature.onboarding.data.model.CreateWalletResponse
import com.tangem.feature.onboarding.presentation.wallet2.analytics.SeedPhraseSource
import com.tangem.tap.domain.tasks.product.CreateProductWalletTaskResponse
@ -28,6 +29,8 @@ sealed class OnboardingWalletAction : Action {
class SetThirdCardArtworkUrl(val artworkUri: Uri?) : OnboardingWalletAction()
data object OnBackPressed : OnboardingWalletAction()
data class WalletSaved(val userWalletId: UserWalletId) : OnboardingWalletAction()
}
sealed class OnboardingWallet2Action : OnboardingWalletAction() {
@ -89,6 +92,8 @@ sealed class BackupAction : Action {
data class FinishBackup(val withAnalytics: Boolean = true) : BackupAction()
data class BackupFinished(val userWalletId: UserWalletId?) : BackupAction()
data object DiscardBackup : BackupAction()
data object DiscardSavedBackup : BackupAction()
data object ResumeFoundUnfinishedBackup : BackupAction()

View file

@ -5,7 +5,6 @@ import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.tangem.common.CompletionResult
import com.tangem.common.card.Card
import com.tangem.common.core.TangemSdkError
import com.tangem.common.extensions.guard
import com.tangem.common.extensions.ifNotNull
import com.tangem.common.extensions.toHexString
import com.tangem.common.routing.AppRoute
@ -19,6 +18,7 @@ import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.domain.wallets.builder.UserWalletBuilder
import com.tangem.domain.wallets.models.Artwork
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.feature.onboarding.data.model.CreateWalletResponse
import com.tangem.feature.onboarding.presentation.wallet2.analytics.SeedPhraseSource
import com.tangem.feature.wallet.presentation.wallet.domain.BackupValidator
@ -164,16 +164,7 @@ private fun handleWalletAction(action: Action) {
}
is OnboardingWalletAction.FinishOnboarding -> {
store.dispatch(GlobalAction.Onboarding.Stop)
if (scanResponse == null) {
action.scope.launch {
readCard { newScanResponse ->
handleFinishOnboardind(newScanResponse)
}
}
} else {
handleFinishOnboardind(scanResponse)
}
navigateToWalletScreen()
}
is OnboardingWalletAction.ResumeBackup -> {
val newAction = when (val backupState = backupService.currentState) {
@ -197,10 +188,10 @@ private fun handleWalletAction(action: Action) {
}
}
private fun handleFinishOnboardind(scanResponse: ScanResponse) {
private fun handleFinishBackup(scanResponse: ScanResponse) {
val backupState = store.state.onboardingWalletState.backupState
val updatedScanResponse = updateScanResponseAfterBackup(scanResponse, backupState)
OnboardingHelper.trySaveWalletAndNavigateToWalletScreen(
OnboardingHelper.saveWallet(
scanResponse = updatedScanResponse,
accessCode = backupState.accessCode,
backupCardsIds = backupState.backupCardIds,
@ -208,7 +199,18 @@ private fun handleFinishOnboardind(scanResponse: ScanResponse) {
)
}
private suspend fun readCard(onSuccess: (ScanResponse) -> Unit) {
private fun navigateToWalletScreen() {
mainScope.launch {
val settingsRepository = store.inject(DaggerGraphState::settingsRepository)
store.dispatchNavigationAction { replaceAll(AppRoute.Wallet) }
if (tangemSdkManager.checkCanUseBiometry() && settingsRepository.shouldShowSaveUserWalletScreen()) {
delay(timeMillis = 1_800)
store.dispatchNavigationAction { push(AppRoute.SaveWallet) }
}
}
}
private suspend fun readCard(onSuccess: suspend (ScanResponse) -> Unit) {
val shouldSaveAccessCodes = store.inject(DaggerGraphState::settingsRepository).shouldSaveAccessCodes()
store.inject(DaggerGraphState::cardSdkConfigRepository).setAccessCodeRequestPolicy(
@ -403,7 +405,7 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
val onboardingWalletState = appState()?.onboardingWalletState ?: return
val backupState = onboardingWalletState.backupState
val scanResponse = globalState.onboardingState.onboardingManager?.scanResponse
var scanResponse = globalState.onboardingState.onboardingManager?.scanResponse
val card = scanResponse?.card
when (action) {
@ -573,6 +575,15 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
cardIds = gatherCardIds(backupState, card),
)
}
if (scanResponse == null) {
scope.launch {
readCard { newScanResponse ->
handleFinishBackup(newScanResponse)
}
}
} else {
handleFinishBackup(scanResponse)
}
}
is BackupAction.FinishBackup -> {
scope.launch {
@ -580,28 +591,31 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
Analytics.send(Onboarding.Backup.Finished(backupState.backupCardsNumber))
}
var userWallet: UserWallet? = null
if (scanResponse != null) {
val walletNameGenerateUseCase = store.inject(DaggerGraphState::generateWalletNameUseCase)
val userWallet = UserWalletBuilder(scanResponse, walletNameGenerateUseCase)
.backupCardsIds(backupState.backupCardIds.toSet())
.build()
.guard {
Timber.e("User wallet not created")
return@launch
}
userWallet = createUserWallet(
scanResponse = requireNotNull(value = scanResponse, lazyMessage = { "ScanResponse is null" }),
backupState = backupState,
)
val userWalletsListManager = store.inject(DaggerGraphState::generalUserWalletsListManager)
userWalletsListManager.update(
userWalletId = userWallet.walletId,
update = { wallet ->
wallet.copy(
scanResponse = updateScanResponseAfterBackup(
scanResponse = wallet.scanResponse,
backupState = backupState,
userWalletsListManager.save(
userWallet = userWallet.copy(
scanResponse = updateScanResponseAfterBackup(
scanResponse = requireNotNull(
value = scanResponse,
lazyMessage = { "ScanResponse is null" },
),
)
},
backupState = backupState,
),
),
canOverride = true,
)
} else {
readCard { newScanResponse ->
scanResponse = newScanResponse
userWallet = createUserWallet(newScanResponse, backupState)
}
}
val notActivatedCardIds = gatherCardIds(backupState, card).mapNotNull {
@ -613,11 +627,18 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
}
// All cardIds may already be activated if the backup was skipped before.
if (notActivatedCardIds.isEmpty()) return@launch
if (notActivatedCardIds.isEmpty()) {
delay(1000)
store.dispatch(BackupAction.BackupFinished(userWallet?.walletId))
return@launch
}
Analytics.send(Onboarding.Finished())
store.state.globalState.onboardingState.onboardingManager?.finishActivation(notActivatedCardIds)
handleFinishBackup(requireNotNull(scanResponse))
delay(1000)
store.dispatch(BackupAction.BackupFinished(userWalletId = userWallet?.walletId))
}
}
@ -629,6 +650,16 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
}
}
private suspend fun createUserWallet(scanResponse: ScanResponse, backupState: BackupState): UserWallet {
val walletNameGenerateUseCase = store.inject(DaggerGraphState::generateWalletNameUseCase)
return requireNotNull(
value = UserWalletBuilder(scanResponse, walletNameGenerateUseCase)
.backupCardsIds(backupState.backupCardIds.toSet())
.build(),
lazyMessage = { "User wallet not created" },
)
}
fun updateArtworks(addedBackupCardsCount: Int, card: Card) {
mainScope.launch {
withIOContext {

View file

@ -1,6 +1,7 @@
package com.tangem.tap.features.onboarding.products.wallet.redux
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.redux.OnboardingManageTokensAction
import com.tangem.tap.backupService
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
@ -10,12 +11,23 @@ object OnboardingWalletReducer {
fun reduce(action: Action, state: AppState): OnboardingWalletState = internalReduce(action, state)
}
@Suppress("CyclomaticComplexMethod")
private fun internalReduce(action: Action, appState: AppState): OnboardingWalletState {
val state = appState.onboardingWalletState
return when (action) {
is GlobalAction.Onboarding -> ReducerForGlobalAction.reduce(action, state)
is BackupAction -> state.copy(backupState = BackupReducer.reduce(action, state.backupState))
is BackupAction.BackupFinished -> {
state.copy(
step = if (action.userWalletId != null) {
OnboardingWalletStep.ManageTokens
} else {
OnboardingWalletStep.Done
},
userWalletId = action.userWalletId,
)
}
is BackupAction -> state.copy(backupState = BackupReducer.reduce(action = action, state = state.backupState))
is OnboardingWallet2Action -> OnboardingWallet2Reducer.reduce(action, state)
is OnboardingWalletAction.GetToCreateWalletStep -> state.copy(
step = OnboardingWalletStep.CreateWallet,
@ -36,6 +48,11 @@ private fun internalReduce(action: Action, appState: AppState): OnboardingWallet
walletImages = state.walletImages.copy(thirdCardImage = action.artworkUri),
)
}
is OnboardingManageTokensAction.CurrenciesSaved -> state.copy(step = OnboardingWalletStep.Done)
is OnboardingWalletAction.WalletSaved -> state.copy(
step = OnboardingWalletStep.ManageTokens,
userWalletId = action.userWalletId,
)
is OnboardingWalletAction.Done -> state.copy(step = OnboardingWalletStep.Done)
else -> state
}

View file

@ -3,6 +3,7 @@ package com.tangem.tap.features.onboarding.products.wallet.redux
import android.graphics.Bitmap
import android.net.Uri
import com.tangem.domain.redux.StateDialog
import com.tangem.domain.wallets.models.UserWalletId
import org.rekotlin.StateType
/**
@ -15,18 +16,19 @@ data class OnboardingWalletState(
val walletImages: WalletImages = WalletImages(),
val showConfetti: Boolean = false,
val isRingOnboarding: Boolean = false,
val userWalletId: UserWalletId? = null,
) : StateType {
@Suppress("MagicNumber")
fun getMaxProgress(): Int {
val baseProgress = 6
val baseProgress = 7
return getWallet2Progress() + baseProgress
}
@Suppress("ComplexMethod", "MagicNumber")
fun getProgressStep(): Int {
val progressByStep = when (step) {
OnboardingWalletStep.CreateWallet -> 1
OnboardingWalletStep.CreateWallet, OnboardingWalletStep.None -> 1
OnboardingWalletStep.Backup -> {
when (backupState.backupStep) {
BackupStep.InitBackup -> 2
@ -36,11 +38,11 @@ data class OnboardingWalletState(
BackupStep.ReenterAccessCode -> 4
BackupStep.SetAccessCode -> 4
BackupStep.WritePrimaryCard, is BackupStep.WriteBackupCard -> 5
BackupStep.Finished -> getMaxProgress()
BackupStep.Finished -> 6
}
}
OnboardingWalletStep.ManageTokens -> 6
OnboardingWalletStep.Done -> getMaxProgress()
else -> 1
}
return getWallet2Progress() + progressByStep
@ -60,7 +62,7 @@ data class OnboardingWallet2State(
)
enum class OnboardingWalletStep {
None, CreateWallet, Backup, Done
None, CreateWallet, Backup, ManageTokens, Done
}
data class BackupState(

View file

@ -3,6 +3,8 @@ package com.tangem.tap.features.onboarding.products.wallet.ui
import android.content.res.ColorStateList
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
@ -10,12 +12,16 @@ import android.view.WindowManager
import android.widget.FrameLayout
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import androidx.core.view.MenuProvider
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.transition.TransitionManager
import by.kirich1409.viewbindingdelegate.viewBinding
import coil.load
import com.arkivanov.decompose.defaultComponentContext
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.tabs.TabLayoutMediator
import com.tangem.common.CardIdFormatter
@ -25,15 +31,22 @@ import com.tangem.common.routing.AppRoute
import com.tangem.core.analytics.Analytics
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.Basic
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.context.childByContext
import com.tangem.core.decompose.di.RootAppComponentContext
import com.tangem.core.ui.extensions.setStatusBarColor
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.windowsize.rememberWindowSize
import com.tangem.datasource.utils.isNullOrEmpty
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.feedback.models.FeedbackEmailType
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.feature.onboarding.data.model.CreateWalletResponse
import com.tangem.feature.onboarding.presentation.wallet2.analytics.SeedPhraseSource
import com.tangem.feature.onboarding.presentation.wallet2.viewmodel.SeedPhraseMediator
import com.tangem.feature.onboarding.presentation.wallet2.viewmodel.SeedPhraseRouter
import com.tangem.feature.onboarding.presentation.wallet2.viewmodel.SeedPhraseViewModel
import com.tangem.features.managetokens.component.OnboardingManageTokensComponent
import com.tangem.sdk.ui.widget.leapfrogWidget.LeapfrogWidget
import com.tangem.sdk.ui.widget.leapfrogWidget.PropertyCalculator
import com.tangem.tap.common.analytics.events.Onboarding
@ -56,6 +69,7 @@ import com.tangem.wallet.databinding.ViewOnboardingProgressBinding
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import org.rekotlin.StoreSubscriber
import javax.inject.Inject
@Suppress("LargeClass", "MagicNumber")
@AndroidEntryPoint
@ -64,10 +78,20 @@ class OnboardingWalletFragment :
StoreSubscriber<OnboardingWalletState>,
FragmentOnBackPressedHandler {
@Inject
internal lateinit var onboardingManageTokensComponentFactory: OnboardingManageTokensComponent.Factory
@Inject
@RootAppComponentContext
internal lateinit var rootComponentContext: AppComponentContext
private var onboardingManageTokensComponent: OnboardingManageTokensComponent? = null
internal val binding: FragmentOnboardingWalletBinding by viewBinding(FragmentOnboardingWalletBinding::bind)
internal val pbBinding: ViewOnboardingProgressBinding by viewBinding(ViewOnboardingProgressBinding::bind)
internal val bindingSeedPhrase: LayoutOnboardingSeedPhraseBinding by lazy { binding.onboardingSeedPhraseContainer }
private val bindingManageTokens by lazy { binding.onboardingManageTokensContainer }
private val canSkipBackup by lazy { arguments?.getBoolean(AppRoute.OnboardingWallet.CAN_SKIP_BACKUP_KEY) ?: true }
@ -173,26 +197,28 @@ class OnboardingWalletFragment :
override fun onStop() {
super.onStop()
onboardingManageTokensComponent = null
store.unsubscribe(this)
}
override fun newState(state: OnboardingWalletState) {
if (activity == null || view == null) return
Handler(Looper.getMainLooper()).post {
animator.updateBackupState(state.backupState)
requireActivity().invalidateOptionsMenu()
animator.updateBackupState(state.backupState)
requireActivity().invalidateOptionsMenu()
pbBinding.pbState.max = state.getMaxProgress()
pbBinding.pbState.progress = state.getProgressStep()
pbBinding.pbState.max = state.getMaxProgress()
pbBinding.pbState.progress = state.getProgressStep()
when {
state.wallet2State != null -> {
seedPhraseStateHandler.newState(this, state, seedPhraseViewModel)
updateWalletImagesState(state.walletImages)
}
else -> {
updateWalletImagesState(state.walletImages)
handleOnboardingStep(state)
when {
state.wallet2State != null -> {
seedPhraseStateHandler.newState(this, state, seedPhraseViewModel)
updateWalletImagesState(state.walletImages)
}
else -> {
updateWalletImagesState(state.walletImages)
handleOnboardingStep(state)
}
}
}
}
@ -220,14 +246,53 @@ class OnboardingWalletFragment :
internal fun handleOnboardingStep(state: OnboardingWalletState) {
when (state.step) {
OnboardingWalletStep.CreateWallet -> setupCreateWalletState()
OnboardingWalletStep.Backup -> setBackupState(
state = state.backupState,
)
OnboardingWalletStep.Backup -> setBackupState(state = state.backupState)
OnboardingWalletStep.ManageTokens -> setManageTokensState(requireNotNull(state.userWalletId))
OnboardingWalletStep.Done -> showSuccess()
else -> {}
}
}
private fun initializeOnboardingManageTokensComponent(userWalletId: UserWalletId) {
val componentContext = rootComponentContext.childByContext(
componentContext = defaultComponentContext(onBackPressedDispatcher = null),
)
onboardingManageTokensComponent = onboardingManageTokensComponentFactory.create(
context = componentContext,
params = OnboardingManageTokensComponent.Params(userWalletId = userWalletId),
)
}
private fun setManageTokensState(userWalletId: UserWalletId) {
with(binding) {
tvHeader.show()
tvBody.show()
viewPagerBackupInfo.hide()
tabLayoutBackupInfo.hide()
onboardingWalletContainer.show()
layoutButtonsCommon.btnWalletAlternativeAction.hide()
onboardingWalletContainer.hide()
toolbar.title = getText(R.string.onboarding_add_tokens)
}
pbBinding.pbState.show()
bindingSeedPhrase.onboardingSeedPhraseContainer.hide()
if (onboardingManageTokensComponent == null) {
initializeOnboardingManageTokensComponent(userWalletId)
}
with(bindingManageTokens) {
onboardingManageTokensContainer.hide()
onboardingManageTokensContainer.show()
onboardingManageTokensContainer.setContent {
TangemTheme(
isDark = isSystemInDarkTheme(),
windowSize = rememberWindowSize(activity = requireActivity()),
) {
onboardingManageTokensComponent?.Content(modifier = Modifier.fillMaxSize())
}
}
}
}
private fun setupCreateWalletState() = with(binding) {
layoutButtonsCommon.btnWalletMainAction.setText(R.string.onboarding_create_wallet_button_create_wallet)
layoutButtonsCommon.btnWalletMainAction.setIconResource(R.drawable.ic_tangem_24)
@ -256,7 +321,10 @@ class OnboardingWalletFragment :
BackupStep.ReenterAccessCode -> showReenterAccessCode(state)
is BackupStep.WritePrimaryCard -> showWritePrimaryCard(state)
is BackupStep.WriteBackupCard -> showWriteBackupCard(state)
BackupStep.Finished -> showSuccess()
BackupStep.Finished -> {
// don't need to navigate here"
// showSuccess()
}
}
}
@ -454,6 +522,8 @@ class OnboardingWalletFragment :
tvBody.show()
viewPagerBackupInfo.hide()
tabLayoutBackupInfo.hide()
onboardingWalletContainer.show()
bindingManageTokens.onboardingManageTokensContainer.hide()
tvBody.text = getText(R.string.onboarding_subtitle_success_tangem_wallet_onboarding)
layoutButtonsCommon.btnWalletMainAction.text = getText(R.string.onboarding_button_continue_wallet)

View file

@ -24,5 +24,8 @@ internal sealed interface SaveWalletAction : Action {
data object Cancel : SaveWalletAction
}
data class SaveWalletAfterBackup(val hasBackupError: Boolean) : SaveWalletAction
data class SaveWalletAfterBackup(
val hasBackupError: Boolean,
val shouldNavigateToWallet: Boolean,
) : SaveWalletAction
}

View file

@ -16,6 +16,7 @@ import com.tangem.tap.common.extensions.dispatchWithMain
import com.tangem.tap.common.extensions.inject
import com.tangem.tap.common.extensions.onUserWalletSelected
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletAction
import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.utils.coroutines.JobHolder
import com.tangem.utils.coroutines.saveIn
@ -44,7 +45,11 @@ internal class SaveWalletMiddleware {
is SaveWalletAction.AllowToUseBiometrics -> allowToUseBiometrics(state)
is SaveWalletAction.EnrollBiometrics.Enroll -> enrollBiometrics()
is SaveWalletAction.Dismiss -> dismiss(state)
is SaveWalletAction.SaveWalletAfterBackup -> saveWalletAfterBackup(state, action.hasBackupError)
is SaveWalletAction.SaveWalletAfterBackup -> saveWalletAfterBackup(
state = state,
hasBackupError = action.hasBackupError,
shouldNavigateToWallet = action.shouldNavigateToWallet,
)
is SaveWalletAction.AllowToUseBiometrics.Success,
is SaveWalletAction.AllowToUseBiometrics.Error,
is SaveWalletAction.ProvideBackupInfo,
@ -55,7 +60,11 @@ internal class SaveWalletMiddleware {
}
}
private fun saveWalletAfterBackup(state: SaveWalletState, hasBackupError: Boolean) {
private fun saveWalletAfterBackup(
state: SaveWalletState,
hasBackupError: Boolean,
shouldNavigateToWallet: Boolean,
) {
scope.launch {
val backupInfo = state.backupInfo ?: error("Backup info is null")
@ -77,8 +86,13 @@ internal class SaveWalletMiddleware {
.doOnFailure { error ->
Timber.e(error, "Unable to save user wallet")
}
.doOnSuccess { mainScope.launch { store.onUserWalletSelected(userWallet) } }
.doOnResult { navigateToWallet() }
.doOnSuccess {
mainScope.launch { store.onUserWalletSelected(userWallet) }
if (!shouldNavigateToWallet) {
store.dispatch(OnboardingWalletAction.WalletSaved(userWallet.walletId))
}
}
.doOnResult { if (shouldNavigateToWallet) navigateToWallet() }
}
}