diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/GeneralUserWalletsListManager.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/GeneralUserWalletsListManager.kt index e0e160a524..79e30fec1f 100644 --- a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/GeneralUserWalletsListManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/GeneralUserWalletsListManager.kt @@ -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 } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt index fd59efff07..70c575c06d 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt @@ -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 diff --git a/app/src/main/java/com/tangem/tap/features/saveWallet/redux/SaveWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/saveWallet/redux/SaveWalletMiddleware.kt index 344a0909de..8193fd9e0e 100644 --- a/app/src/main/java/com/tangem/tap/features/saveWallet/redux/SaveWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/saveWallet/redux/SaveWalletMiddleware.kt @@ -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 = { _, 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, ): CompletionResult { return when { - accessCode != null -> { + accessCode.isNullOrBlank() -> { + CompletionResult.Success(Unit) + } + else -> { tangemSdkManager.saveAccessCode( accessCode = accessCode, cardsIds = cardsInWallet, ) } - else -> { - CompletionResult.Success(Unit) - } } } } \ No newline at end of file diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml index b92767f469..64ca08576f 100644 --- a/gradle/dependencies.toml +++ b/gradle/dependencies.toml @@ -87,7 +87,7 @@ web3j = "4.10.1" # region Tangem tangemBlockchainSdk = "release-app_5.8-536" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds -tangemCardSdk = "release-app_5.8-336" +tangemCardSdk = "release-app_5.8-338" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^ # endregion Tangem