Updated on 2026-08-14
This commit is contained in:
parent
afb2536da1
commit
423e125974
18 changed files with 28 additions and 396 deletions
|
|
@ -5,7 +5,6 @@ import com.tangem.common.*
|
|||
import com.tangem.common.core.TangemError
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.common.core.UserCodeRequestPolicy
|
||||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.models.Basic
|
||||
import com.tangem.core.navigation.AppScreen
|
||||
|
|
@ -19,7 +18,6 @@ import com.tangem.domain.common.util.cardTypesResolver
|
|||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.userwallets.UserWalletBuilder
|
||||
import com.tangem.domain.userwallets.UserWalletIdBuilder
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.legacy.asLockable
|
||||
import com.tangem.tap.*
|
||||
import com.tangem.tap.common.analytics.events.AnalyticsParam
|
||||
|
|
@ -28,8 +26,6 @@ import com.tangem.tap.common.extensions.*
|
|||
import com.tangem.tap.common.redux.AppDialog
|
||||
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.domain.userWalletList.di.provideRuntimeImplementation
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
import com.tangem.tap.features.onboarding.products.twins.redux.CreateTwinWalletMode
|
||||
import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction
|
||||
|
|
@ -371,49 +367,6 @@ class DetailsMiddleware {
|
|||
private suspend fun saveCurrentWallet(
|
||||
scanResponse: ScanResponse?,
|
||||
enableAccessCodesSaving: Boolean,
|
||||
): CompletionResult<Unit> {
|
||||
val featureToggles = store.inject(DaggerGraphState::userWalletsListManagerFeatureToggles)
|
||||
|
||||
return if (featureToggles.isGeneralManagerEnabled) {
|
||||
saveCurrentWalletByNewWay(scanResponse, enableAccessCodesSaving)
|
||||
} else {
|
||||
saveCurrentWalletByOldWay(scanResponse, enableAccessCodesSaving)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun saveCurrentWalletByOldWay(
|
||||
scanResponse: ScanResponse?,
|
||||
enableAccessCodesSaving: Boolean,
|
||||
): CompletionResult<Unit> {
|
||||
val userWallet = userWalletsListManager.selectedUserWalletSync
|
||||
?: scanResponse?.let { UserWalletBuilder(it).build() }
|
||||
?: return CompletionResult.Failure(
|
||||
error = TangemSdkError.ExceptionError(IllegalStateException("scanResponse is null")),
|
||||
)
|
||||
|
||||
updateUserWalletsListManager(enableUserWalletsSaving = true)
|
||||
|
||||
return userWalletsListManager.save(userWallet)
|
||||
.flatMap {
|
||||
if (enableAccessCodesSaving) {
|
||||
saveAccessCodes(scanResponse)
|
||||
} else {
|
||||
CompletionResult.Success(Unit)
|
||||
}
|
||||
}
|
||||
.doOnSuccess {
|
||||
Analytics.send(Settings.AppSettings.SaveWalletSwitcherChanged(AnalyticsParam.OnOffState.On))
|
||||
|
||||
store.inject(DaggerGraphState::walletsRepository).saveShouldSaveUserWallets(item = true)
|
||||
}
|
||||
.doOnFailure { error ->
|
||||
Timber.e(error, "Unable to save user wallet")
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun saveCurrentWalletByNewWay(
|
||||
scanResponse: ScanResponse?,
|
||||
enableAccessCodesSaving: Boolean,
|
||||
): CompletionResult<Unit> {
|
||||
store.inject(DaggerGraphState::walletsRepository).saveShouldSaveUserWallets(item = true)
|
||||
|
||||
|
|
@ -431,31 +384,6 @@ class DetailsMiddleware {
|
|||
}
|
||||
|
||||
private suspend fun deleteSavedWalletsAndAccessCodes(): CompletionResult<Unit> {
|
||||
val featureToggles = store.inject(DaggerGraphState::userWalletsListManagerFeatureToggles)
|
||||
|
||||
return if (featureToggles.isGeneralManagerEnabled) {
|
||||
deleteSavedWalletsAndAccessCodesByNewWay()
|
||||
} else {
|
||||
deleteSavedWalletsAndAccessCodesByOldWay()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun deleteSavedWalletsAndAccessCodesByOldWay(): CompletionResult<Unit> {
|
||||
return userWalletsListManager.clear()
|
||||
.doOnSuccess {
|
||||
Analytics.send(Settings.AppSettings.SaveWalletSwitcherChanged(AnalyticsParam.OnOffState.Off))
|
||||
deleteSavedAccessCodes()
|
||||
updateUserWalletsListManager(enableUserWalletsSaving = false)
|
||||
store.inject(DaggerGraphState::walletsRepository).saveShouldSaveUserWallets(item = false)
|
||||
|
||||
store.dispatchWithMain(NavigationAction.PopBackTo(AppScreen.Home))
|
||||
}
|
||||
.doOnFailure { error ->
|
||||
Timber.e(error, "Unable to delete saved wallets")
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun deleteSavedWalletsAndAccessCodesByNewWay(): CompletionResult<Unit> {
|
||||
Analytics.send(Settings.AppSettings.SaveWalletSwitcherChanged(AnalyticsParam.OnOffState.Off))
|
||||
|
||||
deleteSavedAccessCodes()
|
||||
|
|
@ -493,25 +421,6 @@ class DetailsMiddleware {
|
|||
Timber.e(error, "Unable to delete saved access codes")
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun updateUserWalletsListManager(enableUserWalletsSaving: Boolean) {
|
||||
val manager = if (enableUserWalletsSaving) {
|
||||
createBiometricsUserWalletsManager() ?: return
|
||||
} else {
|
||||
UserWalletsListManager.provideRuntimeImplementation()
|
||||
}
|
||||
|
||||
store.dispatchWithMain(GlobalAction.UpdateUserWalletsListManager(manager))
|
||||
}
|
||||
|
||||
private fun createBiometricsUserWalletsManager(): UserWalletsListManager? {
|
||||
val context = foregroundActivityObserver.foregroundActivity?.applicationContext.guard {
|
||||
Timber.e(IllegalStateException("No activities in foreground"))
|
||||
return null
|
||||
}
|
||||
|
||||
return UserWalletsListManager.provideBiometricImplementation(context)
|
||||
}
|
||||
}
|
||||
|
||||
class AccessCodeRecoveryMiddleware {
|
||||
|
|
|
|||
|
|
@ -90,12 +90,7 @@ object OnboardingHelper {
|
|||
),
|
||||
)
|
||||
|
||||
val toggles = store.inject(DaggerGraphState::userWalletsListManagerFeatureToggles)
|
||||
if (toggles.isGeneralManagerEnabled) {
|
||||
store.dispatchWithMain(SaveWalletAction.SaveWalletAfterBackup(hasBackupError))
|
||||
} else {
|
||||
store.dispatchWithMain(SaveWalletAction.Save)
|
||||
}
|
||||
store.dispatchWithMain(SaveWalletAction.SaveWalletAfterBackup(hasBackupError))
|
||||
}
|
||||
// When should not save user wallets but device has biometry and save wallet screen has not been shown,
|
||||
// then open save wallet screen
|
||||
|
|
|
|||
|
|
@ -562,7 +562,6 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
|
|||
)
|
||||
},
|
||||
)
|
||||
store.dispatchOnMain(GlobalAction.UpdateUserWalletsListManager(userWalletsListManager))
|
||||
}
|
||||
|
||||
val notActivatedCardIds = gatherCardIds(backupState, card).mapNotNull {
|
||||
|
|
|
|||
|
|
@ -11,13 +11,11 @@ internal sealed interface SaveWalletAction : Action {
|
|||
val backupCardsIds: Set<String>?,
|
||||
) : SaveWalletAction
|
||||
|
||||
data object Save : SaveWalletAction {
|
||||
data object AllowToUseBiometrics : SaveWalletAction {
|
||||
data object Success : SaveWalletAction
|
||||
data class Error(val error: TangemError) : SaveWalletAction
|
||||
}
|
||||
|
||||
data object AllowToUseBiometrics : SaveWalletAction
|
||||
|
||||
data object Dismiss : SaveWalletAction
|
||||
|
||||
data object CloseError : SaveWalletAction
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@ import com.tangem.core.analytics.Analytics
|
|||
import com.tangem.core.navigation.AppScreen
|
||||
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
|
||||
|
|
@ -19,8 +17,6 @@ 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.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
|
||||
|
|
@ -47,15 +43,14 @@ internal class SaveWalletMiddleware {
|
|||
|
||||
private fun handleAction(action: SaveWalletAction, state: SaveWalletState) {
|
||||
when (action) {
|
||||
is SaveWalletAction.Save -> saveWalletIfBiometricsEnrolled(state)
|
||||
is SaveWalletAction.AllowToUseBiometrics -> allowToUseBiometrics(state)
|
||||
is SaveWalletAction.EnrollBiometrics.Enroll -> enrollBiometrics()
|
||||
is SaveWalletAction.Dismiss -> dismiss(state)
|
||||
is SaveWalletAction.SaveWalletAfterBackup -> saveWalletAfterBackup(state, action.hasBackupError)
|
||||
is SaveWalletAction.Save.Success,
|
||||
is SaveWalletAction.AllowToUseBiometrics.Success,
|
||||
is SaveWalletAction.AllowToUseBiometrics.Error,
|
||||
is SaveWalletAction.ProvideBackupInfo,
|
||||
is SaveWalletAction.CloseError,
|
||||
is SaveWalletAction.Save.Error,
|
||||
is SaveWalletAction.EnrollBiometrics,
|
||||
is SaveWalletAction.EnrollBiometrics.Cancel,
|
||||
-> Unit
|
||||
|
|
@ -91,83 +86,6 @@ internal class SaveWalletMiddleware {
|
|||
store.dispatchOnMain(NavigationAction.OpenBiometricsSettings)
|
||||
}
|
||||
|
||||
private fun saveWalletIfBiometricsEnrolled(state: SaveWalletState) {
|
||||
if (tangemSdkManager.needEnrollBiometrics) {
|
||||
store.dispatchOnMain(SaveWalletAction.EnrollBiometrics)
|
||||
} else {
|
||||
saveWallet(state)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
* or from [SaveWalletState.backupInfo] if provided from
|
||||
* [com.tangem.tap.features.onboarding.OnboardingHelper.trySaveWalletAndNavigateToWalletScreen]
|
||||
*
|
||||
* If saved user's wallet was selected then pop back to [AppScreen.Wallet]
|
||||
* or navigate to [AppScreen.WalletSelector] otherwise
|
||||
*
|
||||
* TODO: Update that logic after onboarding and backup features refactoring
|
||||
* */
|
||||
private fun saveWallet(state: SaveWalletState) {
|
||||
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))
|
||||
} else {
|
||||
Analytics.send(MainScreen.EnableBiometrics(AnalyticsParam.OnOffState.On))
|
||||
}
|
||||
|
||||
scope.launch {
|
||||
val userWallet = userWalletsListManager.selectedUserWalletSync
|
||||
?: UserWalletBuilder(scanResponse)
|
||||
.backupCardsIds(state.backupInfo?.backupCardsIds)
|
||||
.build()
|
||||
?: return@launch
|
||||
|
||||
val featureToggles = store.inject(DaggerGraphState::userWalletsListManagerFeatureToggles)
|
||||
if (!featureToggles.isGeneralManagerEnabled) {
|
||||
provideLockableUserWalletsListManagerIfNot()
|
||||
}
|
||||
|
||||
val isFirstSavedWallet = !userWalletsListManager.hasUserWallets
|
||||
|
||||
saveAccessCodeIfNeeded(accessCode = state.backupInfo?.accessCode, cardsInWallet = userWallet.cardsInWallet)
|
||||
.flatMap {
|
||||
// Save wallet only at first time (SaveWalletBottomSheet).
|
||||
// Otherwise (Example, add new wallet in Details) userWalletsListManager.wallets subscribers will
|
||||
// receive useless updates.
|
||||
// See: OnboardingHelper.trySaveWalletAndNavigateToWalletScreen()
|
||||
if (isFirstSavedWallet) {
|
||||
userWalletsListManager.save(userWallet, canOverride = true)
|
||||
} else {
|
||||
CompletionResult.Success(Unit)
|
||||
}
|
||||
}
|
||||
.doOnFailure { error ->
|
||||
store.dispatchWithMain(SaveWalletAction.Save.Error(error))
|
||||
}
|
||||
.doOnSuccess {
|
||||
store.inject(DaggerGraphState::walletsRepository).saveShouldSaveUserWallets(item = true)
|
||||
|
||||
// Enable saving access codes only if this is the first time user save the wallet
|
||||
if (isFirstSavedWallet) {
|
||||
store.inject(DaggerGraphState::settingsRepository).setShouldSaveAccessCodes(value = true)
|
||||
|
||||
store.inject(DaggerGraphState::cardSdkConfigRepository).setAccessCodeRequestPolicy(
|
||||
isBiometricsRequestPolicy = userWallet.hasAccessCode,
|
||||
)
|
||||
}
|
||||
|
||||
store.dispatchOnMain(SaveWalletAction.Save.Success)
|
||||
store.navigateToWallet()
|
||||
}
|
||||
}.saveIn(saveWalletJobHolder)
|
||||
}
|
||||
|
||||
private fun allowToUseBiometrics(state: SaveWalletState) {
|
||||
if (tangemSdkManager.needEnrollBiometrics) {
|
||||
store.dispatchOnMain(SaveWalletAction.EnrollBiometrics)
|
||||
|
|
@ -189,7 +107,9 @@ internal class SaveWalletMiddleware {
|
|||
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)))
|
||||
store.dispatchWithMain(
|
||||
SaveWalletAction.AllowToUseBiometrics.Error(TangemSdkError.ExceptionError(error)),
|
||||
)
|
||||
return@launch
|
||||
}
|
||||
|
||||
|
|
@ -206,24 +126,10 @@ internal class SaveWalletMiddleware {
|
|||
isBiometricsRequestPolicy = userWallet.hasAccessCode,
|
||||
)
|
||||
|
||||
store.dispatchWithMain(SaveWalletAction.Save.Success)
|
||||
store.dispatchWithMain(SaveWalletAction.AllowToUseBiometrics.Success)
|
||||
store.dispatchWithMain(NavigationAction.PopBackTo(AppScreen.Wallet))
|
||||
}
|
||||
|
||||
private suspend fun provideLockableUserWalletsListManagerIfNot() {
|
||||
if (store.state.globalState.userWalletsListManager?.isLockable == true) return
|
||||
|
||||
val context = foregroundActivityObserver.foregroundActivity?.applicationContext.guard {
|
||||
val error = IllegalStateException("No activities in foreground")
|
||||
Timber.e(error)
|
||||
store.dispatchWithMain(SaveWalletAction.Save.Error(TangemSdkError.ExceptionError(error)))
|
||||
return
|
||||
}
|
||||
val manager = UserWalletsListManager.provideBiometricImplementation(context)
|
||||
|
||||
store.dispatchWithMain(GlobalAction.UpdateUserWalletsListManager(manager))
|
||||
}
|
||||
|
||||
private fun dismiss(state: SaveWalletState) {
|
||||
if (state.backupInfo != null) {
|
||||
// TODO: Remove after onboarding refactoring
|
||||
|
|
|
|||
|
|
@ -21,14 +21,13 @@ internal object SaveWalletReducer {
|
|||
backupCardsIds = action.backupCardsIds,
|
||||
),
|
||||
)
|
||||
is SaveWalletAction.Save,
|
||||
is SaveWalletAction.AllowToUseBiometrics,
|
||||
-> state.copy(isSaveInProgress = true)
|
||||
is SaveWalletAction.Save.Error -> state.copy(
|
||||
is SaveWalletAction.AllowToUseBiometrics.Error -> state.copy(
|
||||
error = action.error,
|
||||
isSaveInProgress = false,
|
||||
)
|
||||
is SaveWalletAction.Save.Success -> state.copy(
|
||||
is SaveWalletAction.AllowToUseBiometrics.Success -> state.copy(
|
||||
backupInfo = null,
|
||||
isSaveInProgress = false,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import androidx.lifecycle.viewModelScope
|
|||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.domain.settings.SetSaveWalletScreenShownUseCase
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManagerFeatureToggles
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent
|
||||
import com.tangem.tap.common.extensions.dispatchOnMain
|
||||
import com.tangem.tap.features.details.ui.cardsettings.TextReference
|
||||
|
|
@ -24,7 +23,6 @@ import javax.inject.Inject
|
|||
|
||||
@HiltViewModel
|
||||
internal class SaveWalletViewModel @Inject constructor(
|
||||
private val userWalletsListManagerFeatureToggles: UserWalletsListManagerFeatureToggles,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val setSaveWalletScreenShownUseCase: SetSaveWalletScreenShownUseCase,
|
||||
dispatchers: AppCoroutineDispatcherProvider,
|
||||
|
|
@ -43,12 +41,7 @@ internal class SaveWalletViewModel @Inject constructor(
|
|||
|
||||
fun saveWallet() {
|
||||
analyticsEventHandler.send(WalletScreenAnalyticsEvent.MainScreen.EnableBiometrics(AnalyticsParam.OnOffState.On))
|
||||
|
||||
if (userWalletsListManagerFeatureToggles.isGeneralManagerEnabled) {
|
||||
store.dispatch(SaveWalletAction.AllowToUseBiometrics)
|
||||
} else {
|
||||
store.dispatch(SaveWalletAction.Save)
|
||||
}
|
||||
store.dispatch(SaveWalletAction.AllowToUseBiometrics)
|
||||
}
|
||||
|
||||
fun cancelOrClose() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue