Updated on 2026-08-14
This commit is contained in:
parent
3cd82a1782
commit
e84ef9a182
4 changed files with 81 additions and 53 deletions
|
|
@ -122,34 +122,38 @@ internal class GeneralUserWalletsListManager(
|
|||
appPreferencesStore.get(key = PreferencesKeys.SAVE_USER_WALLETS_KEY, default = false)
|
||||
.distinctUntilChanged()
|
||||
.onEach { shouldSaveUserWallets ->
|
||||
val manager = if (shouldSaveUserWallets) {
|
||||
biometricUserWalletsListManager.copyFrom(runtimeUserWalletsListManager)
|
||||
val possibleManager = if (shouldSaveUserWallets) {
|
||||
biometricUserWalletsListManager
|
||||
} else {
|
||||
runtimeUserWalletsListManager.copyFrom(biometricUserWalletsListManager)
|
||||
runtimeUserWalletsListManager
|
||||
}
|
||||
|
||||
Timber.d("Switch to ${manager::class.java.simpleName}")
|
||||
if (possibleManager == implementation.value) {
|
||||
error("${possibleManager::class.simpleName}} is already selected")
|
||||
}
|
||||
|
||||
implementation.value = manager
|
||||
Timber.d("Switch to ${possibleManager::class.simpleName}")
|
||||
|
||||
clearOldManager(manager)
|
||||
val previousManager = implementation.value
|
||||
implementation.value = copySelectedUserWallet(
|
||||
sourceManager = previousManager,
|
||||
destinationManager = possibleManager,
|
||||
)
|
||||
|
||||
previousManager.clear()
|
||||
}
|
||||
.flowOn(dispatchers.io)
|
||||
.launchIn(applicationScope)
|
||||
}
|
||||
|
||||
/** Copy data from [old] manager */
|
||||
private suspend fun UserWalletsListManager.copyFrom(old: UserWalletsListManager): UserWalletsListManager {
|
||||
old.selectedUserWalletSync?.let { this.save(it) }
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
private suspend fun clearOldManager(current: UserWalletsListManager) {
|
||||
if (current == biometricUserWalletsListManager) {
|
||||
runtimeUserWalletsListManager.clear()
|
||||
} else {
|
||||
biometricUserWalletsListManager.clear()
|
||||
private suspend fun copySelectedUserWallet(
|
||||
sourceManager: UserWalletsListManager,
|
||||
destinationManager: UserWalletsListManager,
|
||||
): UserWalletsListManager {
|
||||
sourceManager.selectedUserWalletSync?.let { selectedWallet ->
|
||||
destinationManager.save(selectedWallet, canOverride = true)
|
||||
}
|
||||
|
||||
return destinationManager
|
||||
}
|
||||
}
|
||||
|
|
@ -87,7 +87,13 @@ object OnboardingHelper {
|
|||
backupCardsIds = backupCardsIds?.toSet(),
|
||||
),
|
||||
)
|
||||
store.dispatchOnMain(SaveWalletAction.Save)
|
||||
|
||||
val toggles = store.inject(DaggerGraphState::userWalletsListManagerFeatureToggles)
|
||||
if (toggles.isGeneralManagerEnabled) {
|
||||
store.dispatchOnMain(SaveWalletAction.AllowToUseBiometrics)
|
||||
} else {
|
||||
store.dispatchOnMain(SaveWalletAction.Save)
|
||||
}
|
||||
}
|
||||
// When should not save user wallets but device has biometry and save wallet screen has not been shown,
|
||||
// then open save wallet screen
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import com.tangem.core.navigation.NavigationAction
|
|||
import com.tangem.domain.userwallets.UserWalletBuilder
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.legacy.isLockable
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.tap.*
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
import com.tangem.tap.common.analytics.events.MainScreen
|
||||
|
|
@ -23,11 +24,16 @@ import com.tangem.tap.common.redux.AppState
|
|||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.domain.userWalletList.di.provideBiometricImplementation
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
import com.tangem.utils.coroutines.JobHolder
|
||||
import com.tangem.utils.coroutines.saveIn
|
||||
import kotlinx.coroutines.launch
|
||||
import org.rekotlin.Middleware
|
||||
import timber.log.Timber
|
||||
|
||||
internal class SaveWalletMiddleware {
|
||||
|
||||
private val saveWalletJobHolder = JobHolder()
|
||||
|
||||
val middleware: Middleware<AppState> = { _, stateProvider ->
|
||||
{ next ->
|
||||
{ action ->
|
||||
|
|
@ -99,9 +105,7 @@ internal class SaveWalletMiddleware {
|
|||
?: return@launch
|
||||
|
||||
val featureToggles = store.inject(DaggerGraphState::userWalletsListManagerFeatureToggles)
|
||||
if (featureToggles.isGeneralManagerEnabled) {
|
||||
store.inject(DaggerGraphState::walletsRepository).saveShouldSaveUserWallets(item = true)
|
||||
} else {
|
||||
if (!featureToggles.isGeneralManagerEnabled) {
|
||||
provideLockableUserWalletsListManagerIfNot()
|
||||
}
|
||||
|
||||
|
|
@ -143,7 +147,7 @@ internal class SaveWalletMiddleware {
|
|||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}.saveIn(saveWalletJobHolder)
|
||||
}
|
||||
|
||||
private fun allowToUseBiometrics(state: SaveWalletState) {
|
||||
|
|
@ -152,10 +156,6 @@ internal class SaveWalletMiddleware {
|
|||
return
|
||||
}
|
||||
|
||||
val scanResponse = state.backupInfo?.scanResponse
|
||||
?: store.state.globalState.scanResponse
|
||||
?: return
|
||||
|
||||
if (state.backupInfo != null) {
|
||||
// TODO: Remove after onboarding refactoring
|
||||
Analytics.send(Onboarding.EnableBiometrics(AnalyticsParam.OnOffState.On))
|
||||
|
|
@ -164,31 +164,49 @@ internal class SaveWalletMiddleware {
|
|||
}
|
||||
|
||||
scope.launch {
|
||||
val userWallet = userWalletsListManager.selectedUserWalletSync
|
||||
?: UserWalletBuilder(scanResponse)
|
||||
.backupCardsIds(state.backupInfo?.backupCardsIds)
|
||||
.build()
|
||||
?: return@launch
|
||||
val backupInfo = state.backupInfo
|
||||
val userWalletFromBackup = backupInfo?.scanResponse
|
||||
?.let(::UserWalletBuilder)
|
||||
?.backupCardsIds(backupInfo.backupCardsIds)
|
||||
?.build()
|
||||
|
||||
store.inject(DaggerGraphState::walletsRepository).saveShouldSaveUserWallets(item = true)
|
||||
if (userWalletFromBackup != null) {
|
||||
userWalletsListManager.save(userWalletFromBackup, canOverride = true)
|
||||
.flatMap { saveAccessCodeIfNeeded(backupInfo.accessCode, userWalletFromBackup.cardsInWallet) }
|
||||
.doOnFailure {
|
||||
Timber.e(it, "Unable to save user wallet")
|
||||
|
||||
saveAccessCodeIfNeeded(accessCode = state.backupInfo?.accessCode, cardsInWallet = userWallet.cardsInWallet)
|
||||
.flatMap {
|
||||
userWalletsListManager.save(userWallet, canOverride = true)
|
||||
}
|
||||
.doOnFailure { error ->
|
||||
store.dispatchWithMain(SaveWalletAction.Save.Error(error))
|
||||
}
|
||||
.doOnSuccess {
|
||||
preferencesStorage.shouldSaveAccessCodes = true
|
||||
store.inject(DaggerGraphState::cardSdkConfigRepository).setAccessCodeRequestPolicy(
|
||||
isBiometricsRequestPolicy = userWallet.hasAccessCode,
|
||||
)
|
||||
store.dispatchWithMain(SaveWalletAction.Save.Error(it))
|
||||
}
|
||||
.doOnSuccess {
|
||||
handleSavingSuccess(userWalletFromBackup)
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
|
||||
store.dispatchOnMain(SaveWalletAction.Save.Success)
|
||||
store.dispatchOnMain(NavigationAction.PopBackTo(AppScreen.Wallet))
|
||||
* because it will be automatically saved on UserWalletsListManager switch
|
||||
* */
|
||||
val selectedUserWallet = userWalletsListManager.selectedUserWalletSync.guard {
|
||||
val error = IllegalStateException("No selected user wallet")
|
||||
Timber.e(error, "Unable to save user wallet")
|
||||
store.dispatchWithMain(SaveWalletAction.Save.Error(TangemSdkError.ExceptionError(error)))
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
|
||||
handleSavingSuccess(selectedUserWallet)
|
||||
}
|
||||
}.saveIn(saveWalletJobHolder)
|
||||
}
|
||||
|
||||
private suspend fun handleSavingSuccess(userWallet: UserWallet) {
|
||||
store.inject(DaggerGraphState::walletsRepository).saveShouldSaveUserWallets(item = true)
|
||||
preferencesStorage.shouldSaveAccessCodes = true
|
||||
store.inject(DaggerGraphState::cardSdkConfigRepository).setAccessCodeRequestPolicy(
|
||||
isBiometricsRequestPolicy = userWallet.hasAccessCode,
|
||||
)
|
||||
|
||||
store.dispatchWithMain(SaveWalletAction.Save.Success)
|
||||
store.dispatchWithMain(NavigationAction.PopBackTo(AppScreen.Wallet))
|
||||
}
|
||||
|
||||
private suspend fun provideLockableUserWalletsListManagerIfNot() {
|
||||
|
|
@ -223,15 +241,15 @@ internal class SaveWalletMiddleware {
|
|||
cardsInWallet: Set<String>,
|
||||
): CompletionResult<Unit> {
|
||||
return when {
|
||||
accessCode != null -> {
|
||||
accessCode.isNullOrBlank() -> {
|
||||
CompletionResult.Success(Unit)
|
||||
}
|
||||
else -> {
|
||||
tangemSdkManager.saveAccessCode(
|
||||
accessCode = accessCode,
|
||||
cardsIds = cardsInWallet,
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
CompletionResult.Success(Unit)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue