From f626613f806cf842bd185d1dc6a3e932293a6e10 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 30 Jan 2026 19:33:43 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../com/tangem/tap/ApplicationEntryPoint.kt | 6 - .../java/com/tangem/tap/LockTimerWorker.kt | 14 +- .../com/tangem/tap/LockUserWalletsTimer.kt | 50 +- .../main/java/com/tangem/tap/MainActivity.kt | 10 - .../java/com/tangem/tap/TangemApplication.kt | 9 - .../com/tangem/tap/common/redux/AppReducer.kt | 2 - .../com/tangem/tap/common/redux/AppState.kt | 4 - .../common/redux/legacy/LegacyMiddleware.kt | 19 +- .../tap/data/RuntimeUserWalletsStore.kt | 39 -- .../tap/di/data/UserWalletsStoreModule.kt | 15 +- .../tangem/tap/di/domain/CardDomainModule.kt | 14 +- .../tap/di/domain/CardLegacyDomainModule.kt | 10 +- .../tap/di/domain/MarketsDomainModule.kt | 6 - .../tap/di/domain/WalletsDomainModule.kt | 140 +----- .../di/UserWalletsListManagerModule.kt | 80 +--- .../BiometricUserWalletsListManager.kt | 434 ------------------ .../GeneralUserWalletsListManager.kt | 203 -------- .../RuntimeUserWalletsListManager.kt | 115 ----- .../BiometricFailReasonConverter.kt | 39 -- .../BiometricUserWalletsKeysRepository.kt | 207 --------- .../tap/domain/userWalletList/utils/Mapper.kt | 2 - .../details/redux/DetailsMiddleware.kt | 125 +---- .../features/details/redux/DetailsReducer.kt | 20 - .../features/details/redux/DetailsState.kt | 8 +- .../appsettings/AppSettingsDialogsFactory.kt | 20 - .../ui/appsettings/AppSettingsItemsFactory.kt | 16 - .../ui/appsettings/AppSettingsScreen.kt | 1 - .../components/SettingsAlertDialog.kt | 6 +- .../ui/appsettings/model/AppSettingsModel.kt | 101 +--- .../ui/resetcard/model/ResetCardModel.kt | 16 +- .../component/DefaultWelcomeComponent.kt | 36 -- .../welcome/component/WelcomeComponent.kt | 14 - .../component/impl/PreviewWelcomeComponent.kt | 20 - .../features/welcome/di/ComponentModule.kt | 18 - .../tap/features/welcome/di/ModelModule.kt | 20 - .../features/welcome/model/WelcomeModel.kt | 140 ------ .../features/welcome/redux/WelcomeAction.kt | 22 - .../welcome/redux/WelcomeMiddleware.kt | 164 ------- .../features/welcome/redux/WelcomeReducer.kt | 36 -- .../features/welcome/redux/WelcomeState.kt | 10 - .../features/welcome/ui/WelcomeScreenState.kt | 15 - .../welcome/ui/components/WarningDialog.kt | 136 ------ .../welcome/ui/components/WelcomeScreen.kt | 101 ---- .../ui/components/WelcomeScreenContent.kt | 113 ----- .../features/welcome/ui/model/WarningModel.kt | 16 - .../tap/network/auth/DefaultAuthProvider.kt | 15 +- .../tangem/tap/network/auth/di/AuthModule.kt | 12 +- .../tap/proxy/redux/DaggerGraphState.kt | 4 - .../component/impl/DefaultRoutingComponent.kt | 22 +- .../tangem/tap/routing/utils/ChildFactory.kt | 23 +- .../BiometricUserWalletsListManagerTest.kt | 216 --------- .../configs/feature_toggles_config.json | 8 - .../feedback/DefaultFeedbackRepository.kt | 16 +- .../tangem/data/feedback/di/FeedbackModule.kt | 6 - .../pay/DefaultTangemPayEligibilityManager.kt | 16 +- .../repository/DefaultOnboardingRepository.kt | 12 +- .../data/wallets/DefaultWalletsRepository.kt | 20 +- ...FilterAvailableNetworksForWalletUseCase.kt | 15 +- .../DefaultUserWalletsSyncDelegate.kt | 45 +- .../wallets/legacy/UserWalletsListError.kt | 42 -- .../UserWalletsListManagerExtensions.kt | 56 --- .../wallets/models/UnlockWalletsError.kt | 12 - .../wallets/repository/WalletsRepository.kt | 9 - .../wallets/usecase/DeleteWalletUseCase.kt | 22 +- .../usecase/GenerateWalletNameUseCase.kt | 13 +- .../usecase/GetSavedWalletsCountUseCase.kt | 22 +- .../usecase/GetSelectedWalletSyncUseCase.kt | 17 +- .../usecase/GetSelectedWalletUseCase.kt | 17 +- .../wallets/usecase/GetUserWalletUseCase.kt | 15 +- .../wallets/usecase/GetWalletNamesUseCase.kt | 11 +- ...letsForAutomaticallyPushEnablingUseCase.kt | 10 +- .../wallets/usecase/GetWalletsUseCase.kt | 17 +- .../wallets/usecase/IsNeedToBackupUseCase.kt | 11 +- .../usecase/IsWalletAlreadySavedUseCase.kt | 18 +- .../wallets/usecase/SaveWalletUseCase.kt | 70 +-- .../wallets/usecase/SelectWalletUseCase.kt | 26 +- .../ShouldSaveUserWalletsSyncUseCase.kt | 9 - .../usecase/ShouldSaveUserWalletsUseCase.kt | 9 - .../wallets/usecase/UnlockWalletsUseCase.kt | 45 -- .../wallets/usecase/UpdateWalletUseCase.kt | 40 +- .../GetSavedWalletsCountUseCaseTest.kt | 141 ------ .../biometry/impl/model/AskBiometryModel.kt | 29 +- .../CreateWalletStartModel.kt | 3 - .../entity/CreateWalletStartUM.kt | 1 - .../ui/CreateWalletStartContent.kt | 123 +++-- .../preview/PreviewDetailsComponent.kt | 2 - .../features/details/model/DetailsModel.kt | 24 +- .../details/model/UserWalletListModel.kt | 79 ++-- .../features/details/utils/UserWalletSaver.kt | 10 +- .../home/impl/DefaultHomeComponent.kt | 8 +- .../features/home/impl/model/HomeModel.kt | 14 +- .../com/tangem/features/home/impl/ui/Home.kt | 23 +- .../home/impl/ui/compose/StoriesScreen.kt | 271 ----------- .../hotwallet/HotWalletFeatureToggles.kt | 2 - .../DefaultHotWalletFeatureToggles.kt | 8 +- .../hotwallet/di/HotWalletFeatureModule.kt | 13 +- .../hotwallet/di/MnemonicRepositoryModule.kt | 18 + .../entry/impl/model/OnboardingEntryModel.kt | 28 +- .../utils/WalletCardItemDelegate.kt | 24 +- .../wallet/child/wallet/model/WalletModel.kt | 73 ++- .../model/intents/WalletCardClickIntents.kt | 76 --- .../intents/WalletContentClickIntents.kt | 36 +- .../intents/WalletWarningsClickIntents.kt | 82 +--- .../domain/WalletNameMigrationUseCase.kt | 32 +- .../implementors/MultiWalletContentLoader.kt | 11 - .../MultiWalletContentLoaderFactory.kt | 6 - .../MultiWalletContentLoaderV2.kt | 10 - .../implementors/SingleWalletContentLoader.kt | 10 - .../SingleWalletContentLoaderFactory.kt | 6 - .../SingleWalletContentLoaderV2.kt | 10 - .../SingleWalletWithTokenContentLoader.kt | 15 +- ...ngleWalletWithTokenContentLoaderFactory.kt | 6 - .../SingleWalletWithTokenContentLoaderV2.kt | 15 +- .../wallet/state/model/WalletAlertState.kt | 7 - .../SetWalletCardDropDownItemsTransformer.kt | 73 --- .../state/utils/WalletLoadingStateFactory.kt | 47 +- .../WalletDropDownItemsSubscriber.kt | 45 -- .../welcome/impl/model/WelcomeModel.kt | 2 +- 118 files changed, 391 insertions(+), 4505 deletions(-) delete mode 100644 app/src/main/java/com/tangem/tap/data/RuntimeUserWalletsStore.kt delete mode 100644 app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt delete mode 100644 app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/GeneralUserWalletsListManager.kt delete mode 100644 app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/RuntimeUserWalletsListManager.kt delete mode 100644 app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/BiometricFailReasonConverter.kt delete mode 100644 app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/BiometricUserWalletsKeysRepository.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/welcome/component/DefaultWelcomeComponent.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/welcome/component/WelcomeComponent.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/welcome/component/impl/PreviewWelcomeComponent.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/welcome/di/ComponentModule.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/welcome/di/ModelModule.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/welcome/model/WelcomeModel.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeAction.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeReducer.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeState.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeScreenState.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/welcome/ui/components/WarningDialog.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/welcome/ui/components/WelcomeScreen.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/welcome/ui/components/WelcomeScreenContent.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/welcome/ui/model/WarningModel.kt delete mode 100644 app/src/test/kotlin/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManagerTest.kt delete mode 100644 domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/UserWalletsListError.kt delete mode 100644 domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/UserWalletsListManagerExtensions.kt delete mode 100644 domain/wallets/src/main/java/com/tangem/domain/wallets/models/UnlockWalletsError.kt delete mode 100644 domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/ShouldSaveUserWalletsSyncUseCase.kt delete mode 100644 domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/ShouldSaveUserWalletsUseCase.kt delete mode 100644 domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/UnlockWalletsUseCase.kt delete mode 100644 domain/wallets/src/test/java/com/tangem/domain/wallets/usecase/GetSavedWalletsCountUseCaseTest.kt delete mode 100644 features/home/impl/src/main/kotlin/com/tangem/features/home/impl/ui/compose/StoriesScreen.kt create mode 100644 features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/di/MnemonicRepositoryModule.kt delete mode 100644 features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetWalletCardDropDownItemsTransformer.kt delete mode 100644 features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/WalletDropDownItemsSubscriber.kt diff --git a/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt b/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt index c40ccb2d5a..97f825c6ba 100644 --- a/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt +++ b/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt @@ -40,9 +40,7 @@ import com.tangem.domain.settings.repositories.SettingsRepository import com.tangem.domain.walletconnect.usecase.initialize.WcInitializeUseCase import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.builder.ColdUserWalletBuilder -import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.repository.WalletsRepository -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles import com.tangem.hot.sdk.TangemHotSdk import com.tangem.tap.common.analytics.handlers.BlockchainExceptionHandler @@ -92,8 +90,6 @@ interface ApplicationEntryPoint { fun getOneTimeEventFilter(): OneTimeEventFilter - fun getGeneralUserWalletsListManager(): UserWalletsListManager - fun getWasTwinsOnboardingShownUseCase(): WasTwinsOnboardingShownUseCase fun getSaveTwinsOnboardingShownUseCase(): SaveTwinsOnboardingShownUseCase @@ -151,8 +147,6 @@ interface ApplicationEntryPoint { fun getTangemHotSdk(): TangemHotSdk - fun getHotWalletFeatureToggles(): HotWalletFeatureToggles - fun getWcInitializeUseCase(): WcInitializeUseCase fun getTrackingContextProxy(): TrackingContextProxy diff --git a/app/src/main/java/com/tangem/tap/LockTimerWorker.kt b/app/src/main/java/com/tangem/tap/LockTimerWorker.kt index 85497cc56b..62c9fa652d 100644 --- a/app/src/main/java/com/tangem/tap/LockTimerWorker.kt +++ b/app/src/main/java/com/tangem/tap/LockTimerWorker.kt @@ -6,9 +6,6 @@ import androidx.work.CoroutineWorker import androidx.work.WorkerParameters import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.settings.repositories.SettingsRepository -import com.tangem.domain.wallets.legacy.UserWalletsListManager -import com.tangem.domain.wallets.legacy.asLockable -import com.tangem.features.hotwallet.HotWalletFeatureToggles import dagger.assisted.Assisted import dagger.assisted.AssistedInject import timber.log.Timber @@ -18,21 +15,12 @@ class LockTimerWorker @AssistedInject constructor( @Assisted context: Context, @Assisted params: WorkerParameters, private val settingsRepository: SettingsRepository, - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, ) : CoroutineWorker(context, params) { override suspend fun doWork(): Result { Timber.i("onStart job") - if (hotWalletFeatureToggles.isHotWalletEnabled) { - userWalletsListRepository.lockAllWallets() - .onRight { - settingsRepository.setShouldOpenWelcomeScreenOnResume(value = true) - } - } else { - val userWalletsListManagerLockable = userWalletsListManager.asLockable() ?: return Result.failure() - userWalletsListManagerLockable.lock() + userWalletsListRepository.lockAllWallets().onRight { settingsRepository.setShouldOpenWelcomeScreenOnResume(value = true) } Timber.i("onStart job complete") diff --git a/app/src/main/java/com/tangem/tap/LockUserWalletsTimer.kt b/app/src/main/java/com/tangem/tap/LockUserWalletsTimer.kt index 32ea789431..809f2808bc 100644 --- a/app/src/main/java/com/tangem/tap/LockUserWalletsTimer.kt +++ b/app/src/main/java/com/tangem/tap/LockUserWalletsTimer.kt @@ -9,10 +9,7 @@ import androidx.work.WorkManager import com.tangem.common.routing.AppRoute import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.settings.repositories.SettingsRepository -import com.tangem.domain.wallets.legacy.UserWalletsListManager -import com.tangem.domain.wallets.legacy.asLockable import com.tangem.domain.wallets.usecase.ClearAllHotWalletContextualUnlockUseCase -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.tap.LockTimerWorker.Companion.TAG import com.tangem.tap.common.extensions.dispatchNavigationAction import kotlinx.coroutines.CoroutineScope @@ -22,16 +19,13 @@ import kotlinx.coroutines.launch import timber.log.Timber import java.util.concurrent.TimeUnit import kotlin.time.Duration -import kotlin.time.Duration.Companion.minutes @Suppress("LongParameterList") internal class LockUserWalletsTimer( private val context: Context, private val settingsRepository: SettingsRepository, private val duration: Duration = with(Duration) { 5.minutes }, - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, private val coroutineScope: CoroutineScope, private val clearAllHotWalletContextualUnlockUseCase: ClearAllHotWalletContextualUnlockUseCase, ) : LifecycleOwner by context as LifecycleOwner, @@ -59,9 +53,7 @@ internal class LockUserWalletsTimer( ) if (shouldOpenWelcomeScreenOnResume) { - if (hotWalletFeatureToggles.isHotWalletEnabled) { - clearAllHotWalletContextualUnlockUseCase.invoke() - } + clearAllHotWalletContextualUnlockUseCase.invoke() store.dispatchNavigationAction { replaceAll(AppRoute.Welcome()) } settingsRepository.setShouldOpenWelcomeScreenOnResume(value = false) } @@ -115,38 +107,18 @@ internal class LockUserWalletsTimer( * This job used only when app is foreground when background use [JobScheduler] */ private fun createDelayJob(): Job = coroutineScope.launch { - val startTime = System.currentTimeMillis() - delay(duration) - if (hotWalletFeatureToggles.isHotWalletEnabled) { - val userWallets = userWalletsListRepository.userWalletsSync() - if (userWallets.isNotEmpty()) { - userWalletsListRepository.lockAllWallets() - .onLeft { - start() - } - .onRight { - clearAllHotWalletContextualUnlockUseCase.invoke() - store.dispatchNavigationAction { replaceAll(AppRoute.Welcome()) } - } - } - } else { - val userWalletsListManager = userWalletsListManager.asLockable() ?: return@launch - - if (userWalletsListManager.hasUserWallets) { - val currentTime = System.currentTimeMillis() - - Timber.i( - """ - Finished - |- Millis passed: ${currentTime - startTime} - """.trimIndent(), - ) - - userWalletsListManager.lock() - store.dispatchNavigationAction { replaceAll(AppRoute.Welcome()) } - } + val userWallets = userWalletsListRepository.userWalletsSync() + if (userWallets.isNotEmpty()) { + userWalletsListRepository.lockAllWallets() + .onLeft { + start() + } + .onRight { + clearAllHotWalletContextualUnlockUseCase.invoke() + store.dispatchNavigationAction { replaceAll(AppRoute.Welcome()) } + } } } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index 076a21b682..cf540d0ec0 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -43,9 +43,7 @@ import com.tangem.domain.settings.SetGoogleServicesAvailabilityUseCase import com.tangem.domain.settings.ShouldInitiallyAskPermissionUseCase import com.tangem.domain.settings.repositories.SettingsRepository import com.tangem.domain.staking.SendUnsubmittedHashesUseCase -import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.usecase.ClearAllHotWalletContextualUnlockUseCase -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.features.tangempay.TangemPayFeatureToggles import com.tangem.features.tester.api.TesterMenuLauncher import com.tangem.google.GoogleServicesHelper @@ -114,9 +112,6 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder { @Inject lateinit var analyticsEventsHandler: AnalyticsEventHandler - @Inject - lateinit var userWalletsListManager: UserWalletsListManager - @Inject @RootAppComponentContext internal lateinit var rootComponentContext: AppComponentContext @@ -163,9 +158,6 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder { @Inject internal lateinit var userWalletsListRepository: UserWalletsListRepository - @Inject - internal lateinit var hotWalletFeatureToggles: HotWalletFeatureToggles - @Inject internal lateinit var clearAllHotWalletContextualUnlockUseCase: ClearAllHotWalletContextualUnlockUseCase @@ -258,10 +250,8 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder { lockUserWalletsTimer = LockUserWalletsTimer( context = this, settingsRepository = settingsRepository, - userWalletsListManager = userWalletsListManager, coroutineScope = mainScope, userWalletsListRepository = userWalletsListRepository, - hotWalletFeatureToggles = hotWalletFeatureToggles, clearAllHotWalletContextualUnlockUseCase = clearAllHotWalletContextualUnlockUseCase, ) diff --git a/app/src/main/java/com/tangem/tap/TangemApplication.kt b/app/src/main/java/com/tangem/tap/TangemApplication.kt index 6b59b1b8b2..a22cc0dd22 100644 --- a/app/src/main/java/com/tangem/tap/TangemApplication.kt +++ b/app/src/main/java/com/tangem/tap/TangemApplication.kt @@ -58,7 +58,6 @@ import com.tangem.domain.onboarding.repository.OnboardingRepository import com.tangem.domain.settings.repositories.SettingsRepository import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.builder.ColdUserWalletBuilder -import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles import com.tangem.operations.attestation.api.TangemApiServiceSettings @@ -146,9 +145,6 @@ open class TangemApplication : Application(), ImageLoaderFactory, Configuration. private val oneTimeEventFilter: OneTimeEventFilter get() = entryPoint.getOneTimeEventFilter() - private val generalUserWalletsListManager: UserWalletsListManager - get() = entryPoint.getGeneralUserWalletsListManager() - private val wasTwinsOnboardingShownUseCase: WasTwinsOnboardingShownUseCase get() = entryPoint.getWasTwinsOnboardingShownUseCase() @@ -238,9 +234,6 @@ open class TangemApplication : Application(), ImageLoaderFactory, Configuration. private val tangemHotSdk get() = entryPoint.getTangemHotSdk() - private val hotWalletFeatureToggles - get() = entryPoint.getHotWalletFeatureToggles() - private val wcInitializeUseCase get() = entryPoint.getWcInitializeUseCase() @@ -382,7 +375,6 @@ open class TangemApplication : Application(), ImageLoaderFactory, Configuration. appThemeModeRepository = appThemeModeRepository, balanceHidingRepository = balanceHidingRepository, walletsRepository = walletsRepository, - generalUserWalletsListManager = generalUserWalletsListManager, wasTwinsOnboardingShownUseCase = wasTwinsOnboardingShownUseCase, saveTwinsOnboardingShownUseCase = saveTwinsOnboardingShownUseCase, cardRepository = cardRepository, @@ -407,7 +399,6 @@ open class TangemApplication : Application(), ImageLoaderFactory, Configuration. userTokensResponseStore = userTokensResponseStore, userWalletsListRepository = userWalletsListRepository, tangemHotSdk = tangemHotSdk, - hotWalletFeatureToggles = hotWalletFeatureToggles, trackingContextProxy = trackingContextProxy, ), ), diff --git a/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt b/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt index 65315fc4cd..bc16aae955 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt @@ -2,7 +2,6 @@ package com.tangem.tap.common.redux import com.tangem.tap.common.redux.global.globalReducer import com.tangem.tap.features.details.redux.DetailsReducer -import com.tangem.tap.features.welcome.redux.WelcomeReducer import com.tangem.tap.proxy.redux.DaggerGraphReducer import org.rekotlin.Action @@ -12,7 +11,6 @@ fun appReducer(action: Action, state: AppState): AppState { return AppState( globalState = globalReducer(action, state), detailsState = DetailsReducer.reduce(action, state), - welcomeState = WelcomeReducer.reduce(action, state), daggerGraphState = DaggerGraphReducer.reduce(action, state), ) } diff --git a/app/src/main/java/com/tangem/tap/common/redux/AppState.kt b/app/src/main/java/com/tangem/tap/common/redux/AppState.kt index 7c3065b0f4..b43504d06c 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/AppState.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/AppState.kt @@ -7,8 +7,6 @@ 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.features.wallet.redux.middlewares.TradeCryptoMiddleware -import com.tangem.tap.features.welcome.redux.WelcomeMiddleware -import com.tangem.tap.features.welcome.redux.WelcomeState import com.tangem.tap.proxy.redux.DaggerGraphMiddleware import com.tangem.tap.proxy.redux.DaggerGraphState import org.rekotlin.Middleware @@ -17,7 +15,6 @@ import org.rekotlin.StateType data class AppState( val globalState: GlobalState = GlobalState(), val detailsState: DetailsState = DetailsState(), - val welcomeState: WelcomeState = WelcomeState(), val daggerGraphState: DaggerGraphState = DaggerGraphState(), ) : StateType { @@ -28,7 +25,6 @@ data class AppState( GlobalMiddleware.handler, DetailsMiddleware().detailsMiddleware, BackupMiddleware().backupMiddleware, - WelcomeMiddleware().middleware, LockUserWalletsTimerMiddleware().middleware, AccessCodeRequestPolicyMiddleware().middleware, DaggerGraphMiddleware.daggerGraphMiddleware, diff --git a/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt b/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt index c847cb4a50..aee323386c 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt @@ -27,8 +27,6 @@ internal object LegacyMiddleware { { action -> when (action) { is LegacyAction.PrepareDetailsScreen -> { - val walletsRepository = store.inject(DaggerGraphState::walletsRepository) - selectedUserWallet() .distinctUntilChanged { old, new -> if (old is UserWallet.Cold && new is UserWallet.Cold) { @@ -39,9 +37,7 @@ internal object LegacyMiddleware { } } .onEach { selectedUserWallet -> - val initializedAppSettingsStateContent = initializeAppSettingsState( - shouldSaveUserWallets = walletsRepository.shouldSaveUserWalletsSync(), - ) + val initializedAppSettingsStateContent = initializeAppSettingsState() store.dispatchWithMain( DetailsAction.PrepareScreen( scanResponse = (selectedUserWallet as? UserWallet.Cold)?.scanResponse, @@ -60,24 +56,15 @@ internal object LegacyMiddleware { } private fun selectedUserWallet(): Flow { - val hotWalletFeatureToggles = store.inject(DaggerGraphState::hotWalletFeatureToggles) - return if (hotWalletFeatureToggles.isHotWalletEnabled) { - store.inject(DaggerGraphState::userWalletsListRepository).selectedUserWallet.filterNotNull() - } else { - val userWalletsListManager = store.inject(DaggerGraphState::generalUserWalletsListManager) - userWalletsListManager.selectedUserWallet - } + return store.inject(DaggerGraphState::userWalletsListRepository).selectedUserWallet.filterNotNull() } /** * LEGACY: We need to initialize [AppSettingsState] async to avoid drawing blocking * previously it was initialized in runBlocking and blocked details screen */ - private suspend fun initializeAppSettingsState(shouldSaveUserWallets: Boolean): AppSettingsState { + private suspend fun initializeAppSettingsState(): AppSettingsState { return AppSettingsState( - isBiometricsAvailable = tangemSdkManager.checkCanUseBiometry(), - saveWallets = shouldSaveUserWallets, - saveAccessCodes = store.inject(DaggerGraphState::settingsRepository).shouldSaveAccessCodes(), selectedAppCurrency = store.state.globalState.appCurrency, selectedThemeMode = store.inject(DaggerGraphState::appThemeModeRepository).getAppThemeMode().firstOrNull() ?: AppThemeMode.DEFAULT, diff --git a/app/src/main/java/com/tangem/tap/data/RuntimeUserWalletsStore.kt b/app/src/main/java/com/tangem/tap/data/RuntimeUserWalletsStore.kt deleted file mode 100644 index d0fd68250c..0000000000 --- a/app/src/main/java/com/tangem/tap/data/RuntimeUserWalletsStore.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.tangem.tap.data - -import com.tangem.common.CompletionResult -import com.tangem.datasource.local.userwallet.UserWalletsStore -import com.tangem.domain.models.wallet.UserWallet -import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.domain.wallets.legacy.UserWalletsListManager -import kotlinx.coroutines.flow.Flow - -// FIXME: Workaround, remove it once the normal UserWalletsStore has been implemented -// [REDACTED_JIRA] -internal class RuntimeUserWalletsStore( - private val userWalletsListManager: UserWalletsListManager, -) : UserWalletsStore { - - override val selectedUserWalletOrNull: UserWallet? - get() = userWalletsListManager.selectedUserWalletSync - - override val userWallets: Flow> - get() = userWalletsListManager.userWallets - - override val userWalletsSync: List - get() = userWalletsListManager.userWalletsSync - - override fun getSyncOrNull(key: UserWalletId): UserWallet? { - return userWalletsListManager.userWalletsSync.firstOrNull { it.walletId == key } - } - - override fun getSyncStrict(key: UserWalletId): UserWallet { - return requireNotNull(getSyncOrNull(key)) { "Unable to find user wallet with provided ID: $key" } - } - - override suspend fun update( - userWalletId: UserWalletId, - update: suspend (UserWallet) -> UserWallet, - ): CompletionResult { - return userWalletsListManager.update(userWalletId, update) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/di/data/UserWalletsStoreModule.kt b/app/src/main/java/com/tangem/tap/di/data/UserWalletsStoreModule.kt index f08b09fb11..8b9dae8020 100644 --- a/app/src/main/java/com/tangem/tap/di/data/UserWalletsStoreModule.kt +++ b/app/src/main/java/com/tangem/tap/di/data/UserWalletsStoreModule.kt @@ -2,9 +2,6 @@ package com.tangem.tap.di.data import com.tangem.datasource.local.userwallet.UserWalletsStore import com.tangem.domain.common.wallets.UserWalletsListRepository -import com.tangem.domain.wallets.legacy.UserWalletsListManager -import com.tangem.features.hotwallet.HotWalletFeatureToggles -import com.tangem.tap.data.RuntimeUserWalletsStore import com.tangem.tap.data.UserWalletsStoreRepositoryProxy import dagger.Module import dagger.Provides @@ -18,15 +15,7 @@ internal object UserWalletsStoreModule { @Provides @Singleton - fun provideUserWalletsStore( - userWalletsListManager: UserWalletsListManager, - userWalletsListRepository: UserWalletsListRepository, - hotWalletFeatureToggles: HotWalletFeatureToggles, - ): UserWalletsStore { - return if (hotWalletFeatureToggles.isHotWalletEnabled) { - UserWalletsStoreRepositoryProxy(userWalletsListRepository) - } else { - RuntimeUserWalletsStore(userWalletsListManager = userWalletsListManager) - } + fun provideUserWalletsStore(userWalletsListRepository: UserWalletsListRepository): UserWalletsStore { + return UserWalletsStoreRepositoryProxy(userWalletsListRepository) } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/di/domain/CardDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/CardDomainModule.kt index 8c0d2628db..7f99ec03db 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/CardDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/CardDomainModule.kt @@ -9,9 +9,7 @@ import com.tangem.domain.demo.IsDemoCardUseCase import com.tangem.domain.demo.models.DemoConfig import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.derivations.DerivationsRepository -import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.usecase.* -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.sdk.api.TangemSdkManager import com.tangem.tap.domain.card.DefaultDeleteSavedAccessCodesUseCase import com.tangem.tap.domain.card.DefaultResetCardUseCase @@ -42,16 +40,8 @@ internal object CardDomainModule { } @Provides - fun provideIsNeedToBackupUseCase( - userWalletsListManager: UserWalletsListManager, - userWalletsListRepository: UserWalletsListRepository, - hotWalletFeatureToggles: HotWalletFeatureToggles, - ): IsNeedToBackupUseCase { - return IsNeedToBackupUseCase( - userWalletsListManager = userWalletsListManager, - userWalletsListRepository = userWalletsListRepository, - useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled, - ) + fun provideIsNeedToBackupUseCase(userWalletsListRepository: UserWalletsListRepository): IsNeedToBackupUseCase { + return IsNeedToBackupUseCase(userWalletsListRepository = userWalletsListRepository) } @Provides diff --git a/app/src/main/java/com/tangem/tap/di/domain/CardLegacyDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/CardLegacyDomainModule.kt index b84ebc02b6..db3b9aa4e2 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/CardLegacyDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/CardLegacyDomainModule.kt @@ -3,9 +3,7 @@ package com.tangem.tap.di.domain import com.tangem.core.configtoggle.feature.FeatureTogglesManager import com.tangem.domain.card.ScanCardProcessor import com.tangem.domain.common.wallets.UserWalletsListRepository -import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.tap.domain.scanCard.CardScanningFeatureToggles import com.tangem.tap.domain.scanCard.DefaultScanCardProcessor import com.tangem.tap.domain.scanCard.LegacyScanProcessor @@ -34,14 +32,8 @@ internal object CardLegacyDomainModule { @Provides @Singleton fun providesWalletNameGenerateUseCase( - userWalletsListManager: UserWalletsListManager, userWalletsListRepository: UserWalletsListRepository, - hotWalletFeatureToggles: HotWalletFeatureToggles, ): GenerateWalletNameUseCase { - return GenerateWalletNameUseCase( - userWalletsListManager = userWalletsListManager, - userWalletsListRepository = userWalletsListRepository, - useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled, - ) + return GenerateWalletNameUseCase(userWalletsListRepository = userWalletsListRepository) } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/di/domain/MarketsDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/MarketsDomainModule.kt index e56953ffdc..d96861be6a 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/MarketsDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/MarketsDomainModule.kt @@ -13,8 +13,6 @@ import com.tangem.domain.staking.multi.MultiStakingBalanceFetcher import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.derivations.DerivationsRepository -import com.tangem.domain.wallets.legacy.UserWalletsListManager -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.Module import dagger.Provides @@ -107,15 +105,11 @@ object MarketsDomainModule { @Provides @Singleton fun provideFilterNetworksUseCase( - userWalletsListManager: UserWalletsListManager, userWalletsListRepository: UserWalletsListRepository, - hotWalletFeatureToggles: HotWalletFeatureToggles, excludedBlockchains: ExcludedBlockchains, ): FilterAvailableNetworksForWalletUseCase { return FilterAvailableNetworksForWalletUseCase( - userWalletsListManager = userWalletsListManager, userWalletsListRepository = userWalletsListRepository, - shouldUseNewRepository = hotWalletFeatureToggles.isHotWalletEnabled, excludedBlockchains = excludedBlockchains, ) } diff --git a/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt index 52533057f0..1b3b29d84b 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/WalletsDomainModule.kt @@ -12,7 +12,6 @@ import com.tangem.domain.wallets.delegate.DefaultUserWalletsSyncDelegate import com.tangem.domain.wallets.delegate.UserWalletsSyncDelegate import com.tangem.domain.wallets.derivations.DerivationsRepository import com.tangem.domain.wallets.hot.HotWalletAccessor -import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.repository.WalletNamesMigrationRepository import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.domain.wallets.usecase.* @@ -21,7 +20,6 @@ import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase import com.tangem.domain.yield.supply.usecase.YieldSupplyApyUpdateUseCase import com.tangem.feature.wallet.presentation.wallet.domain.IsWalletNFTEnabledSyncUseCase import com.tangem.feature.wallet.presentation.wallet.domain.WalletNameMigrationUseCase -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.operations.attestation.CardArtworksProvider import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.Module @@ -37,119 +35,69 @@ internal object WalletsDomainModule { @Provides fun providesUserWalletsSyncDelegate( - userWalletsListManager: UserWalletsListManager, userWalletsListRepository: UserWalletsListRepository, - hotWalletFeatureToggles: HotWalletFeatureToggles, - dispatchers: CoroutineDispatcherProvider, ): UserWalletsSyncDelegate { - return DefaultUserWalletsSyncDelegate( - userWalletsListManager = userWalletsListManager, - userWalletsListRepository = userWalletsListRepository, - useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled, - dispatchers = dispatchers, - ) + return DefaultUserWalletsSyncDelegate(userWalletsListRepository = userWalletsListRepository) } @Provides @Singleton - fun providesGetWalletsUseCase( - userWalletsListManager: UserWalletsListManager, - userWalletsListRepository: UserWalletsListRepository, - hotWalletFeatureToggles: HotWalletFeatureToggles, - ): GetWalletsUseCase { - return GetWalletsUseCase( - userWalletsListManager = userWalletsListManager, - userWalletsListRepository = userWalletsListRepository, - useNewListRepository = hotWalletFeatureToggles.isHotWalletEnabled, - ) + fun providesGetWalletsUseCase(userWalletsListRepository: UserWalletsListRepository): GetWalletsUseCase { + return GetWalletsUseCase(userWalletsListRepository = userWalletsListRepository) } @Provides @Singleton fun providesWalletNameMigrationUseCase( - userWalletsListManager: UserWalletsListManager, walletNamesMigrationRepository: WalletNamesMigrationRepository, userWalletsListRepository: UserWalletsListRepository, - hotWalletFeatureToggles: HotWalletFeatureToggles, ): WalletNameMigrationUseCase { return WalletNameMigrationUseCase( - userWalletsListManager = userWalletsListManager, walletNamesMigrationRepository = walletNamesMigrationRepository, userWalletsListRepository = userWalletsListRepository, - useNewListRepository = hotWalletFeatureToggles.isHotWalletEnabled, ) } @Provides @Singleton - fun providesGetUserWalletUseCase( - userWalletsListManager: UserWalletsListManager, - userWalletsListRepository: UserWalletsListRepository, - hotWalletFeatureToggles: HotWalletFeatureToggles, - ): GetUserWalletUseCase { - return GetUserWalletUseCase( - userWalletsListManager = userWalletsListManager, - userWalletsListRepository = userWalletsListRepository, - useNewListRepository = hotWalletFeatureToggles.isHotWalletEnabled, - ) + fun providesGetUserWalletUseCase(userWalletsListRepository: UserWalletsListRepository): GetUserWalletUseCase { + return GetUserWalletUseCase(userWalletsListRepository = userWalletsListRepository) } @Provides @Singleton fun providesGetSelectedWalletSyncUseCase( - userWalletsListManager: UserWalletsListManager, userWalletsListRepository: UserWalletsListRepository, - hotWalletFeatureToggles: HotWalletFeatureToggles, ): GetSelectedWalletSyncUseCase { - return GetSelectedWalletSyncUseCase( - userWalletsListManager = userWalletsListManager, - userWalletsListRepository = userWalletsListRepository, - useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled, - ) + return GetSelectedWalletSyncUseCase(userWalletsListRepository = userWalletsListRepository) } @Provides @Singleton fun providesGetSelectedWalletUseCase( - userWalletsListManager: UserWalletsListManager, userWalletsListRepository: UserWalletsListRepository, - hotWalletFeatureToggles: HotWalletFeatureToggles, ): GetSelectedWalletUseCase { - return GetSelectedWalletUseCase( - userWalletsListManager = userWalletsListManager, - userWalletsListRepository = userWalletsListRepository, - useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled, - ) + return GetSelectedWalletUseCase(userWalletsListRepository = userWalletsListRepository) } @Provides @Singleton fun providesSaveWalletUseCase( - userWalletsListManager: UserWalletsListManager, userWalletsListRepository: UserWalletsListRepository, - hotWalletFeatureToggles: HotWalletFeatureToggles, walletsRepository: WalletsRepository, ): SaveWalletUseCase { return SaveWalletUseCase( - userWalletsListManager = userWalletsListManager, userWalletsListRepository = userWalletsListRepository, walletsRepository = walletsRepository, - useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled, ) } @Provides @Singleton fun providesIsWalletAlreadySavedUseCase( - userWalletsListManager: UserWalletsListManager, userWalletsListRepository: UserWalletsListRepository, - hotWalletFeatureToggles: HotWalletFeatureToggles, ): IsWalletAlreadySavedUseCase { - return IsWalletAlreadySavedUseCase( - userWalletsListManager = userWalletsListManager, - userWalletsListRepository = userWalletsListRepository, - useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled, - ) + return IsWalletAlreadySavedUseCase(userWalletsListRepository = userWalletsListRepository) } @Provides @@ -164,12 +112,6 @@ internal object WalletsDomainModule { return GetExploreUrlUseCase(walletsManagersFacade = walletsManagersFacade) } - @Provides - @Singleton - fun providesUnlockWalletsUseCase(userWalletsListManager: UserWalletsListManager): UnlockWalletsUseCase { - return UnlockWalletsUseCase(userWalletsListManager = userWalletsListManager) - } - @Provides @Singleton fun providesUnlockWalletUseCase( @@ -197,31 +139,19 @@ internal object WalletsDomainModule { @Provides @Singleton fun providesSelectWalletUseCase( - userWalletsListManager: UserWalletsListManager, userWalletsListRepository: UserWalletsListRepository, - hotWalletFeatureToggles: HotWalletFeatureToggles, reduxStateHolder: ReduxStateHolder, ): SelectWalletUseCase { return SelectWalletUseCase( - userWalletsListManager = userWalletsListManager, userWalletsListRepository = userWalletsListRepository, - useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled, reduxStateHolder = reduxStateHolder, ) } @Provides @Singleton - fun providesUpdateWalletUseCase( - userWalletsListManager: UserWalletsListManager, - userWalletsListRepository: UserWalletsListRepository, - hotWalletFeatureToggles: HotWalletFeatureToggles, - ): UpdateWalletUseCase { - return UpdateWalletUseCase( - userWalletsListManager = userWalletsListManager, - userWalletsListRepository = userWalletsListRepository, - useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled, - ) + fun providesUpdateWalletUseCase(userWalletsListRepository: UserWalletsListRepository): UpdateWalletUseCase { + return UpdateWalletUseCase(userWalletsListRepository = userWalletsListRepository) } @Provides @@ -238,44 +168,14 @@ internal object WalletsDomainModule { @Provides @Singleton - fun providesGetWalletsSyncUseCase( - userWalletsListManager: UserWalletsListManager, - userWalletsListRepository: UserWalletsListRepository, - hotWalletFeatureToggles: HotWalletFeatureToggles, - ): GetWalletNamesUseCase { - return GetWalletNamesUseCase( - userWalletsListManager = userWalletsListManager, - userWalletsListRepository = userWalletsListRepository, - useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled, - ) + fun providesGetWalletsSyncUseCase(userWalletsListRepository: UserWalletsListRepository): GetWalletNamesUseCase { + return GetWalletNamesUseCase(userWalletsListRepository = userWalletsListRepository) } @Provides @Singleton - fun providesDeleteWalletUseCase( - userWalletsListManager: UserWalletsListManager, - userWalletsListRepository: UserWalletsListRepository, - hotWalletFeatureToggles: HotWalletFeatureToggles, - ): DeleteWalletUseCase { - return DeleteWalletUseCase( - userWalletsListManager = userWalletsListManager, - userWalletsListRepository = userWalletsListRepository, - useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled, - ) - } - - @Provides - @Singleton - fun providesShouldSaveUserWalletsSyncUseCase( - walletsRepository: WalletsRepository, - ): ShouldSaveUserWalletsSyncUseCase { - return ShouldSaveUserWalletsSyncUseCase(walletsRepository = walletsRepository) - } - - @Provides - @Singleton - fun providesShouldSaveUserWalletsUseCase(walletsRepository: WalletsRepository): ShouldSaveUserWalletsUseCase { - return ShouldSaveUserWalletsUseCase(walletsRepository = walletsRepository) + fun providesDeleteWalletUseCase(userWalletsListRepository: UserWalletsListRepository): DeleteWalletUseCase { + return DeleteWalletUseCase(userWalletsListRepository = userWalletsListRepository) } @Provides @@ -347,15 +247,9 @@ internal object WalletsDomainModule { @Provides @Singleton fun providesGetSavedWalletChangesIdUseCase( - userWalletsListManager: UserWalletsListManager, userWalletsListRepository: UserWalletsListRepository, - hotWalletFeatureToggles: HotWalletFeatureToggles, ): GetSavedWalletsCountUseCase { - return GetSavedWalletsCountUseCase( - userWalletsListManager = userWalletsListManager, - userWalletsListRepository = userWalletsListRepository, - useNewRepository = hotWalletFeatureToggles.isHotWalletEnabled, - ) + return GetSavedWalletsCountUseCase(userWalletsListRepository = userWalletsListRepository) } @Provides @@ -479,15 +373,11 @@ internal object WalletsDomainModule { @Provides @Singleton fun provideGetWalletsForAutomaticallyPushEnablingUseCase( - userWalletsListManager: UserWalletsListManager, userWalletsListRepository: UserWalletsListRepository, - hotWalletFeatureToggles: HotWalletFeatureToggles, dispatcherProvider: CoroutineDispatcherProvider, ): GetWalletsForAutomaticallyPushEnablingUseCase { return GetWalletsForAutomaticallyPushEnablingUseCase( - userWalletsListManager = userWalletsListManager, userWalletsListRepository = userWalletsListRepository, - shouldUseNewListRepository = hotWalletFeatureToggles.isHotWalletEnabled, dispatchers = dispatcherProvider, ) } diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/di/UserWalletsListManagerModule.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/di/UserWalletsListManagerModule.kt index 1c3cfc1d98..3571b8a63c 100644 --- a/app/src/main/java/com/tangem/tap/domain/userWalletList/di/UserWalletsListManagerModule.kt +++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/di/UserWalletsListManagerModule.kt @@ -16,19 +16,14 @@ import com.tangem.domain.visa.model.VisaActivationRemoteState import com.tangem.domain.visa.model.VisaCardActivationStatus import com.tangem.domain.wallets.hot.HotWalletAccessCodeAttemptsRepository import com.tangem.domain.wallets.hot.HotWalletPasswordRequester -import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.hot.sdk.TangemHotSdk import com.tangem.sdk.storage.AndroidSecureStorage import com.tangem.sdk.storage.AndroidSecureStorageV2 import com.tangem.sdk.storage.createEncryptedSharedPreferences -import com.tangem.tap.domain.userWalletList.implementation.BiometricUserWalletsListManager -import com.tangem.tap.domain.userWalletList.implementation.GeneralUserWalletsListManager -import com.tangem.tap.domain.userWalletList.implementation.RuntimeUserWalletsListManager import com.tangem.tap.domain.userWalletList.repository.DefaultUserWalletsListRepository import com.tangem.tap.domain.userWalletList.repository.DelegatedKeystoreManager import com.tangem.tap.domain.userWalletList.repository.UserWalletEncryptionKeysRepository import com.tangem.tap.domain.userWalletList.repository.UserWalletsKeysStoreDecorator -import com.tangem.tap.domain.userWalletList.repository.implementation.BiometricUserWalletsKeysRepository import com.tangem.tap.domain.userWalletList.repository.implementation.DefaultSelectedUserWalletRepository import com.tangem.tap.domain.userWalletList.repository.implementation.DefaultUserWalletsPublicInformationRepository import com.tangem.tap.domain.userWalletList.repository.implementation.DefaultUserWalletsSensitiveInformationRepository @@ -47,77 +42,6 @@ import javax.inject.Singleton @InstallIn(SingletonComponent::class) internal object UserWalletsListManagerModule { - @Provides - @Singleton - @Deprecated("Use UserWalletsListRepository instead") - fun provideGeneralUserWalletsListManager( - @ApplicationContext applicationContext: Context, - appPreferencesStore: AppPreferencesStore, - dispatchers: CoroutineDispatcherProvider, - analyticsEventHandler: AnalyticsEventHandler, - ): UserWalletsListManager { - return GeneralUserWalletsListManager( - runtimeUserWalletsListManager = RuntimeUserWalletsListManager(), - biometricUserWalletsListManager = createBiometricUserWalletsListManager( - applicationContext = applicationContext, - analyticsEventHandler = analyticsEventHandler, - dispatchers = dispatchers, - ), - appPreferencesStore = appPreferencesStore, - dispatchers = dispatchers, - ) - } - - @Deprecated("Use UserWalletsListRepository instead") - private fun createBiometricUserWalletsListManager( - applicationContext: Context, - analyticsEventHandler: AnalyticsEventHandler, - dispatchers: CoroutineDispatcherProvider, - ): UserWalletsListManager { - val moshi = buildMoshi() - val secureStorage = buildSecureStorage(applicationContext = applicationContext) - - val authenticatedStorage = AuthenticatedStorage( - secureStorage = UserWalletsKeysStoreDecorator( - featureStorage = secureStorage, - cardSdkStorageProvider = Provider { tangemSdkManager.secureStorage }, - ), - keystoreManager = DelegatedKeystoreManager( - keystoreManagerProvider = Provider { tangemSdkManager.keystoreManager }, - ), - ) - - val keysRepository = BiometricUserWalletsKeysRepository( - moshi = moshi, - secureStorage = secureStorage, - authenticatedStorage = authenticatedStorage, - analyticsEventHandler = analyticsEventHandler, - ) - - val publicInformationRepository = DefaultUserWalletsPublicInformationRepository( - moshi = moshi, - secureStorage = secureStorage, - ) - - val sensitiveInformationRepository = DefaultUserWalletsSensitiveInformationRepository( - moshi = moshi, - secureStorage = secureStorage, - ) - - val selectedUserWalletRepository = DefaultSelectedUserWalletRepository( - secureStorage = secureStorage, - dispatchers = dispatchers, - ) - - return BiometricUserWalletsListManager( - keysRepository = keysRepository, - publicInformationRepository = publicInformationRepository, - sensitiveInformationRepository = sensitiveInformationRepository, - selectedUserWalletRepository = selectedUserWalletRepository, - dispatcherProvider = dispatchers, - ) - } - @Provides @Singleton fun provideUserWalletsListRepository( @@ -183,7 +107,7 @@ internal object UserWalletsListManagerModule { ) } - fun buildMoshi(): Moshi { + private fun buildMoshi(): Moshi { return Moshi.Builder() .add(WalletDerivedKeysMapAdapter()) .add(ScanResponseDerivedKeysMapAdapter()) @@ -200,7 +124,7 @@ internal object UserWalletsListManagerModule { .build() } - fun buildSecureStorage(@ApplicationContext applicationContext: Context): SecureStorage { + private fun buildSecureStorage(@ApplicationContext applicationContext: Context): SecureStorage { return AndroidSecureStorage( preferences = SecureStorage.createEncryptedSharedPreferences( context = applicationContext, diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt deleted file mode 100644 index 8183415675..0000000000 --- a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt +++ /dev/null @@ -1,434 +0,0 @@ -package com.tangem.tap.domain.userWalletList.implementation - -import com.tangem.common.* -import com.tangem.domain.models.wallet.UserWallet -import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.domain.models.wallet.isLocked -import com.tangem.domain.wallets.legacy.UserWalletsListError -import com.tangem.domain.wallets.legacy.UserWalletsListManager -import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType -import com.tangem.tap.domain.userWalletList.model.UserWalletEncryptionKey -import com.tangem.tap.domain.userWalletList.repository.SelectedUserWalletRepository -import com.tangem.tap.domain.userWalletList.repository.UserWalletsKeysRepository -import com.tangem.tap.domain.userWalletList.repository.UserWalletsPublicInformationRepository -import com.tangem.tap.domain.userWalletList.repository.UserWalletsSensitiveInformationRepository -import com.tangem.tap.domain.userWalletList.utils.encryptionKey -import com.tangem.tap.domain.userWalletList.utils.lockAll -import com.tangem.tap.domain.userWalletList.utils.toUserWallets -import com.tangem.tap.domain.userWalletList.utils.updateWith -import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.flow.* -import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock -import kotlinx.coroutines.withContext -import timber.log.Timber - -@Suppress("LargeClass") -@OptIn(ExperimentalCoroutinesApi::class) -internal class BiometricUserWalletsListManager( - private val keysRepository: UserWalletsKeysRepository, - private val publicInformationRepository: UserWalletsPublicInformationRepository, - private val sensitiveInformationRepository: UserWalletsSensitiveInformationRepository, - private val selectedUserWalletRepository: SelectedUserWalletRepository, - private val dispatcherProvider: CoroutineDispatcherProvider, -) : UserWalletsListManager.Lockable { - private val state = MutableStateFlow(State()) - - private var hasSavedWallets: Boolean? = null - private val savedWalletMutex = Mutex() - - override val isLockable: Boolean = true - - override val userWallets: Flow> - get() = state - .mapLatest { it.userWallets } - .distinctUntilChanged() - - override val userWalletsSync: List - get() = state.value.userWallets - - @Deprecated("You should provide the selected wallet via routing parameters due to the scalability of the features") - override val selectedUserWallet: Flow - get() = state - .mapLatest { state -> - findSelectedUserWallet(state.userWallets) - } - .filterNotNull() - .distinctUntilChanged() - - @Deprecated("You should provide the selected wallet via routing parameters due to the scalability of the features") - override val selectedUserWalletSync: UserWallet? - get() = findSelectedUserWallet() - - override val lockedState: Flow - get() = state - .mapLatest { it.isLocked } - .distinctUntilChanged() - - override val isLocked: Boolean - get() = state.value.isLocked - - override val hasUserWallets: Boolean - get() { - return runBlocking { - // workaround to avoid calling hasSavedEncryptionKeys many times because of performance - savedWalletMutex.withLock { - Timber.i("Checking if user has saved wallets") - val hasSavedWalletsLocal = hasSavedWallets - if (hasSavedWalletsLocal == null || !hasSavedWalletsLocal) { - val hasKeys = keysRepository.hasSavedEncryptionKeys() - hasSavedWallets = hasKeys - hasKeys - } else { - Timber.i("User has saved wallets (from cache)") - true - } - } - } - } - - override val walletsCount: Int - get() = state.value.userWallets.size - - override val savedWalletsCount: Flow - get() = state - .mapLatest { walletsCount } - .distinctUntilChanged() - - override suspend fun unlock(type: UnlockType): CompletionResult { - return withContext(dispatcherProvider.io) { - unlockAndSetSelectedUserWallet(type) - .mapFailure { error -> - Timber.e(error, "Unable to unlock user wallets") - if (error is UserWalletsListError) { - error - } else { - UserWalletsListError.UnableToUnlockUserWallets(error) - } - } - .map { selectedUserWallet -> - if (selectedUserWallet == null || selectedUserWallet.isLocked) { - Timber.e("Unable to find selected user wallet") - throw UserWalletsListError.NoUserWalletSelected - } else { - selectedUserWallet - } - } - } - } - - override fun lock() { - state.update { prevState -> - prevState.copy( - encryptionKeys = emptyList(), - userWallets = prevState.userWallets.lockAll(), - isLocked = true, - ) - } - } - - override suspend fun select(userWalletId: UserWalletId): CompletionResult = catching { - if (state.value.selectedUserWalletId == userWalletId) { - return@catching requireNotNull(findSelectedUserWallet()) { - "Wallet is not found" - } - } - - selectedUserWalletRepository.set(userWalletId) - - val newState = state.updateAndGet { prevState -> - prevState.copy( - selectedUserWalletId = userWalletId, - ) - } - - newState.userWallets.first { it.walletId == userWalletId } - } - - override suspend fun save(userWallet: UserWallet, canOverride: Boolean): CompletionResult { - return withContext(dispatcherProvider.io) { - if (canOverride) { - saveInternal(userWallet, changeSelectedUserWallet = true, canOverridePublicInfo = false) - } else { - val isWalletSaved = state.value.userWallets - .any { - it.walletId == userWallet.walletId - } - - if (isWalletSaved) { - CompletionResult.Failure(UserWalletsListError.WalletAlreadySaved) - } else { - saveInternal(userWallet, changeSelectedUserWallet = true, canOverridePublicInfo = false) - } - } - } - } - - override suspend fun update( - userWalletId: UserWalletId, - update: suspend (UserWallet) -> UserWallet, - ): CompletionResult { - return withContext(dispatcherProvider.io) { - get(userWalletId) - .map { storedUserWallet -> - update(storedUserWallet) - } - .flatMap { updatedUserWallet -> - saveInternal(updatedUserWallet, changeSelectedUserWallet = false, canOverridePublicInfo = true) - } - .flatMap { - get(userWalletId) - } - } - } - - override suspend fun delete(userWalletIds: List): CompletionResult { - val idsToRemove = state.value.userWallets - .takeIf { it.isNotEmpty() } - ?.filter { it.walletId in userWalletIds } - ?.map { it.walletId } - - if (idsToRemove.isNullOrEmpty()) { - return CompletionResult.Success(Unit) - } - - if (idsToRemove.size == state.value.userWallets.size) { - return clear() - } - - return withContext(dispatcherProvider.io) { - sensitiveInformationRepository.delete(idsToRemove) - .flatMap { publicInformationRepository.delete(idsToRemove) } - .map { keysRepository.delete(idsToRemove) } - .map { - state.update { prevState -> - val remainingWallets = prevState.userWallets.filter { it.walletId !in idsToRemove } - - val isSelectedWalletDeleted = prevState.selectedUserWalletId in idsToRemove - val newSelectedUserWallet = findOrSetSelectedWallet( - prevSelectedWalletId = prevState.selectedUserWalletId, - prevSelectedWalletIndex = prevState.userWallets.indexOfFirst { - it.walletId == prevState.selectedUserWalletId - }, - userWallets = remainingWallets, - ignorePrevSelectedWallet = isSelectedWalletDeleted, - ) - - prevState.copy( - encryptionKeys = prevState.encryptionKeys.filter { it.walletId !in idsToRemove }, - userWallets = remainingWallets, - isLocked = remainingWallets.any { it.isLocked }, - selectedUserWalletId = newSelectedUserWallet?.walletId, - ) - } - } - } - } - - override suspend fun clear(): CompletionResult { - savedWalletMutex.withLock { - hasSavedWallets = null - } - return withContext(dispatcherProvider.io) { - sensitiveInformationRepository.clear() - .flatMap { publicInformationRepository.clear() } - .map { - keysRepository.clear() - selectedUserWalletRepository.set(null) - state.value = State() - } - } - } - - override suspend fun get(userWalletId: UserWalletId): CompletionResult { - return catching { - state.value.userWallets.first { it.walletId == userWalletId } - } - } - - private suspend fun saveInternal( - userWallet: UserWallet, - changeSelectedUserWallet: Boolean, - canOverridePublicInfo: Boolean, - ): CompletionResult { - val encryptionKey = userWallet.encryptionKey - ?.let { UserWalletEncryptionKey(userWallet.walletId, it) } - ?: return CompletionResult.Success(Unit) // No encryption key, no need to save - - return keysRepository.save(encryptionKey) - .flatMap { sensitiveInformationRepository.save(userWallet, encryptionKey = encryptionKey.encryptionKey) } - .flatMap { publicInformationRepository.save(userWallet, canOverridePublicInfo) } - .flatMap { - loadUserWallets( - encryptionKeys = state.value.encryptionKeys - .plus(encryptionKey) - .distinctBy(UserWalletEncryptionKey::walletId), - ) - } - .doOnSuccess { loadedState -> - if (changeSelectedUserWallet) { - selectedUserWalletRepository.set(userWallet.walletId) - - state.value = loadedState.copy( - selectedUserWalletId = userWallet.walletId, - ) - } else { - state.value = loadedState - } - } - .map { /* Type erasing */ } - } - - private suspend fun unlockAndSetSelectedUserWallet(type: UnlockType): CompletionResult { - return keysRepository.getAll() - .flatMap { encryptionKeys -> - loadUserWallets( - encryptionKeys = state.value.encryptionKeys - .plus(encryptionKeys) - .distinctBy(UserWalletEncryptionKey::walletId), - ) - } - .map { loadedState -> - when (type) { - UnlockType.ALL -> { - if (loadedState.isLocked) { - Timber.e("Some user wallets remain locked") - - state.value = loadedState - - throw UserWalletsListError.NotAllUserWalletsUnlocked - } else { - val prevState = state.value - - val selectedWallet = findOrSetSelectedWallet( - prevSelectedWalletId = prevState.selectedUserWalletId, - userWallets = loadedState.userWallets, - prevSelectedWalletIndex = prevState.userWallets.indexOfFirst { - it.walletId == prevState.selectedUserWalletId - }, - ) - - state.value = loadedState.copy(selectedUserWalletId = selectedWallet?.walletId) - - selectedWallet - } - } - UnlockType.ANY -> { - val prevState = state.value - - val selectedWallet = findOrSetSelectedWallet( - prevSelectedWalletId = state.value.selectedUserWalletId, - prevSelectedWalletIndex = prevState.userWallets.indexOfFirst { - it.walletId == prevState.selectedUserWalletId - }, - userWallets = loadedState.userWallets, - ) - - state.value = loadedState.copy(selectedUserWalletId = selectedWallet?.walletId) - - selectedWallet - } - UnlockType.ALL_WITHOUT_SELECT -> { - state.value = loadedState - - findSelectedUserWallet() - } - } - } - } - - private suspend fun loadUserWallets(encryptionKeys: List): CompletionResult { - return publicInformationRepository.getAll() - .map { it.toUserWallets() } - .flatMap { userWallets -> - sensitiveInformationRepository.getAll(encryptionKeys) - .map { walletIdToSensitiveInformation -> - userWallets.updateWith(walletIdToSensitiveInformation) - } - } - .map { userWallets -> - val prevState = state.value - - if (userWallets.isNotEmpty()) { - val newUserWallets = (userWallets + prevState.userWallets) - .distinctBy(UserWallet::walletId) - - prevState.copy( - userWallets = newUserWallets, - encryptionKeys = encryptionKeys, - isLocked = newUserWallets.any(UserWallet::isLocked), - ) - } else { - prevState - } - } - } - - private suspend fun findOrSetSelectedWallet( - prevSelectedWalletId: UserWalletId?, - prevSelectedWalletIndex: Int, - userWallets: List, - ignorePrevSelectedWallet: Boolean = false, - ): UserWallet? { - var possibleSelectedUserWallet: UserWallet? = null - - if (!ignorePrevSelectedWallet) { - val selectedWalletId = prevSelectedWalletId ?: selectedUserWalletRepository.get() - possibleSelectedUserWallet = findSelectedUserWallet(userWallets, selectedWalletId) - } - - if (possibleSelectedUserWallet == null || possibleSelectedUserWallet.isLocked) { - possibleSelectedUserWallet = - userWallets.findAvailableUserWallet(prevSelectedIndex = prevSelectedWalletIndex) - } - - selectedUserWalletRepository.set(possibleSelectedUserWallet?.walletId) - - return possibleSelectedUserWallet - } - - /** - * Find the nearest available wallet that can be selected - * - * Example: - * Number with *n* is previous selected wallet with index [prevSelectedIndex]. - * - * 1. [*1*, 2, 3, 4] => delete 1 => [2, 3, 4] => find and select => [*2*, 3, 4] - * 2. [1, *2*, 3, 4] => delete 2 => [1, 3, 4] => find and select => [1, *3*, 4] - * 3. [1, 2, *3*, 4] => delete 3 => [1, 2, 4] => find and select => [1, 2, *4*] - * 4. [1, 2, 3, *4*] => delete 4 => [1, 2, 3] => find and select => [1, 2, *3*] - * - * @receiver list of user wallets without deleted wallet - */ - private fun List.findAvailableUserWallet(prevSelectedIndex: Int): UserWallet? { - if (prevSelectedIndex == 0) return firstOrNull { !it.isLocked } ?: firstOrNull() - - if (prevSelectedIndex in indices && !this[prevSelectedIndex].isLocked) return this[prevSelectedIndex] - - for (offset in 1..size) { - val rightIndex = prevSelectedIndex + offset - if (rightIndex in indices && !this[rightIndex].isLocked) return this[rightIndex] - - val leftIndex = prevSelectedIndex - offset - if (leftIndex in indices && !this[leftIndex].isLocked) return this[leftIndex] - } - - return lastOrNull() - } - - private fun findSelectedUserWallet( - userWallets: List = state.value.userWallets, - selectedUserWalletId: UserWalletId? = state.value.selectedUserWalletId, - ): UserWallet? { - return userWallets.firstOrNull { it.walletId == selectedUserWalletId } - } - - private data class State( - val encryptionKeys: List = emptyList(), - val userWallets: List = emptyList(), - val selectedUserWalletId: UserWalletId? = null, - val isLocked: Boolean = true, - ) -} \ No newline at end of file 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 deleted file mode 100644 index f38d94f5c8..0000000000 --- a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/GeneralUserWalletsListManager.kt +++ /dev/null @@ -1,203 +0,0 @@ -package com.tangem.tap.domain.userWalletList.implementation - -import com.tangem.common.CompletionResult -import com.tangem.datasource.local.preferences.AppPreferencesStore -import com.tangem.datasource.local.preferences.PreferencesKeys -import com.tangem.datasource.local.preferences.utils.get -import com.tangem.domain.models.wallet.UserWallet -import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.domain.wallets.legacy.UserWalletsListManager -import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.flow.* -import timber.log.Timber - -/** - * General implementation of [UserWalletsListManager] that helps to switch between Runtime and Biometric - * implementations. - * - * @property runtimeUserWalletsListManager runtime user wallets list manager - * @property biometricUserWalletsListManager biometric user wallets list manager - * @property appPreferencesStore app preferences store - * @property dispatchers coroutine dispatcher provider - * -[REDACTED_AUTHOR] - */ -@OptIn(ExperimentalCoroutinesApi::class) -internal class GeneralUserWalletsListManager( - private val runtimeUserWalletsListManager: UserWalletsListManager, - private val biometricUserWalletsListManager: UserWalletsListManager, - private val appPreferencesStore: AppPreferencesStore, - private val dispatchers: CoroutineDispatcherProvider, -) : UserWalletsListManager.Lockable { - - private val applicationScope = CoroutineScope(dispatchers.io) - private val implementation: MutableStateFlow = MutableStateFlow(value = null) - - private val requireImplementation: UserWalletsListManager - get() = requireNotNull(implementation.value) { - "UserWalletsListManager is not initialized" - } - - init { - subscribeOnCurrentManager() - } - - override val isLockable: Boolean - get() = requireImplementation.isLockable - - override val userWallets: Flow> - get() = implementation - .transformLatest { impl -> - if (impl != null) { - emitAll(impl.userWallets) - } - } - // To avoid returning empty flow to subscriber while implementation and userWallets are null - // Flow is called first time when implementation is null and then when its assigned with implementation - // that may have not user wallets (null or empty). - // As a result subscription occurs on empty flow, than will not change if user wallets are available - .filter { requireImplementation.hasUserWallets } - - override val savedWalletsCount: Flow - get() = implementation - .transformLatest { impl -> - if (impl != null) { - emitAll(impl.savedWalletsCount) - } - } - - override val userWalletsSync: List - get() = requireImplementation.userWalletsSync - - override val selectedUserWallet: Flow - get() = implementation - .transformLatest { impl -> - if (impl != null) { - emitAll(impl.selectedUserWallet) - } - } - // To avoid returning empty flow to subscriber while implementation and userWallets are null - // Flow is called first time when implementation is null and then when its assigned with implementation - // that may have not user wallets (null or empty). - // As a result subscription occurs on empty flow, than will not change if user wallets are available - .filter { requireImplementation.hasUserWallets } - - override val selectedUserWalletSync: UserWallet? - get() = requireImplementation.selectedUserWalletSync - - override val hasUserWallets: Boolean - get() = requireImplementation.hasUserWallets - - override val walletsCount: Int - get() = requireImplementation.walletsCount - - override val lockedState: Flow - get() = implementation.transformLatest { impl -> - if (impl == null) return@transformLatest - - if (impl is UserWalletsListManager.Lockable) { - emitAll(impl.lockedState) - } else { - error("RuntimeUserWalletsListManager is not lockable") - } - } - - override val isLocked: Boolean - get() { - val impl = requireImplementation - - return if (impl is UserWalletsListManager.Lockable) { - impl.isLocked - } else { - error("RuntimeUserWalletsListManager is not lockable") - } - } - - override suspend fun select(userWalletId: UserWalletId): CompletionResult { - return requireImplementation.select(userWalletId) - } - - override suspend fun save(userWallet: UserWallet, canOverride: Boolean): CompletionResult { - return requireImplementation.save(userWallet, canOverride) - } - - override suspend fun update( - userWalletId: UserWalletId, - update: suspend (UserWallet) -> UserWallet, - ): CompletionResult { - return requireImplementation.update(userWalletId, update) - } - - override suspend fun delete(userWalletIds: List): CompletionResult { - return requireImplementation.delete(userWalletIds) - } - - override suspend fun clear(): CompletionResult { - return requireImplementation.clear() - } - - override suspend fun get(userWalletId: UserWalletId): CompletionResult { - return requireImplementation.get(userWalletId) - } - - override suspend fun unlock(type: UserWalletsListManager.Lockable.UnlockType): CompletionResult { - val implementation = requireImplementation - - return if (implementation is UserWalletsListManager.Lockable) { - implementation.unlock(type) - } else { - error("RuntimeUserWalletsListManager is not lockable") - } - } - - override fun lock() { - val implementation = requireImplementation - - return if (implementation is UserWalletsListManager.Lockable) { - implementation.lock() - } else { - error("RuntimeUserWalletsListManager is not lockable") - } - } - - private fun subscribeOnCurrentManager() { - appPreferencesStore.get(key = PreferencesKeys.SAVE_USER_WALLETS_KEY, default = false) - .distinctUntilChanged() - .onEach { shouldSaveUserWallets -> - val possibleManager = if (shouldSaveUserWallets) { - biometricUserWalletsListManager - } else { - runtimeUserWalletsListManager - } - - if (possibleManager == implementation.value) { - Timber.e("Switch to the same manager ${possibleManager::class.simpleName.orEmpty()}") - } - - Timber.i("Switch to ${possibleManager::class.simpleName.orEmpty()}") - - val previousManager = implementation.value - implementation.value = copySelectedUserWallet( - sourceManager = previousManager, - destinationManager = possibleManager, - ) - - previousManager?.clear() - } - .flowOn(dispatchers.io) - .launchIn(applicationScope) - } - - 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/domain/userWalletList/implementation/RuntimeUserWalletsListManager.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/RuntimeUserWalletsListManager.kt deleted file mode 100644 index 8ee8847ffa..0000000000 --- a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/RuntimeUserWalletsListManager.kt +++ /dev/null @@ -1,115 +0,0 @@ -package com.tangem.tap.domain.userWalletList.implementation - -import com.tangem.common.CompletionResult -import com.tangem.common.catching -import com.tangem.domain.models.wallet.UserWallet -import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.domain.wallets.legacy.UserWalletsListError -import com.tangem.domain.wallets.legacy.UserWalletsListManager -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.flow.* - -@OptIn(ExperimentalCoroutinesApi::class) -internal class RuntimeUserWalletsListManager : UserWalletsListManager { - private val state = MutableStateFlow(State()) - - override val isLockable: Boolean = false - - override val userWallets: Flow> - get() = state - .mapLatest { listOfNotNull(it.userWallet) } - .distinctUntilChanged() - - override val selectedUserWallet: Flow - get() = state - .mapLatest { it.userWallet } - .filterNotNull() - .distinctUntilChanged() - - override val userWalletsSync: List - get() = listOfNotNull(state.value.userWallet) - - override val selectedUserWalletSync: UserWallet? - get() = state.value.userWallet - - override val hasUserWallets: Boolean - get() = state.value.userWallet != null - - /** - * only 1 wallet stored in runtime implementation - */ - override val walletsCount: Int - get() = if (hasUserWallets) 1 else 0 - - override val savedWalletsCount: Flow - get() = state - .mapLatest { walletsCount } - .distinctUntilChanged() - - override suspend fun select(userWalletId: UserWalletId): CompletionResult = catching { - state.value.userWallet - ?.takeIf { it.walletId == userWalletId } - ?: walletNotFound() - } - - override suspend fun save(userWallet: UserWallet, canOverride: Boolean): CompletionResult { - return if (canOverride) { - saveInternal(userWallet) - } else { - val isWalletSaved = state.value.userWallet?.walletId == userWallet.walletId - - if (isWalletSaved) { - CompletionResult.Failure(UserWalletsListError.WalletAlreadySaved) - } else { - saveInternal(userWallet) - } - } - } - - override suspend fun update( - userWalletId: UserWalletId, - update: suspend (UserWallet) -> UserWallet, - ): CompletionResult = catching { - val wallet = state.value.userWallet - ?.takeIf { it.walletId == userWalletId } - ?: walletNotFound() - - requireNotNull( - state.updateAndGet { prevState -> - prevState.copy( - userWallet = update(wallet), - ) - }.userWallet, - ) { "User wallet is null after update" } - } - - override suspend fun delete(userWalletIds: List): CompletionResult = clear() - - override suspend fun clear(): CompletionResult = catching { - state.update { prevState -> - prevState.copy( - userWallet = null, - ) - } - } - - override suspend fun get(userWalletId: UserWalletId): CompletionResult = catching { - state.value.userWallet ?: walletNotFound() - } - - private fun saveInternal(userWallet: UserWallet): CompletionResult = catching { - state.update { prevState -> - prevState.copy( - userWallet = userWallet, - ) - } - } - - private fun walletNotFound(): Nothing { - throw NoSuchElementException("User wallet not found") - } - - private data class State( - val userWallet: UserWallet? = null, - ) -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/BiometricFailReasonConverter.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/BiometricFailReasonConverter.kt deleted file mode 100644 index 89013b048e..0000000000 --- a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/BiometricFailReasonConverter.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.tangem.tap.domain.userWalletList.repository.implementation - -import com.tangem.common.core.TangemError -import com.tangem.common.core.TangemSdkError -import com.tangem.core.analytics.models.Basic -import com.tangem.domain.wallets.legacy.UserWalletsListError -import com.tangem.utils.converter.Converter - -object BiometricFailReasonConverter : Converter { - - override fun convert(value: TangemError): Basic.BiometryFailed.BiometricFailReason { - // 1. Try handle TangemSdkError cases first if error has not been mapped - when (value) { - is TangemSdkError.AuthenticationCanceled -> - return Basic.BiometryFailed.BiometricFailReason.AuthenticationCancelled - is TangemSdkError.AuthenticationAlreadyInProgress -> - return Basic.BiometryFailed.BiometricFailReason.AuthenticationAlreadyInProgress - } - - // 2. For other errors, check if they are of type UserWalletsListError - if (value !is UserWalletsListError) { - return Basic.BiometryFailed.BiometricFailReason.Other(value.customMessage) - } - // 3. Map UserWalletsListError to BiometricFailReason - return when (value) { - UserWalletsListError.AllKeysInvalidated -> - Basic.BiometryFailed.BiometricFailReason.AllKeysInvalidated - UserWalletsListError.BiometricsAuthenticationDisabled -> - Basic.BiometryFailed.BiometricFailReason.BiometricsAuthenticationDisabled - is UserWalletsListError.BiometricsAuthenticationLockout -> - if (value.isPermanent) { - Basic.BiometryFailed.BiometricFailReason.AuthenticationLockoutPermanent - } else { - Basic.BiometryFailed.BiometricFailReason.AuthenticationLockout - } - else -> Basic.BiometryFailed.BiometricFailReason.Other(value.customMessage) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/BiometricUserWalletsKeysRepository.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/BiometricUserWalletsKeysRepository.kt deleted file mode 100644 index 6f82167edd..0000000000 --- a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/implementation/BiometricUserWalletsKeysRepository.kt +++ /dev/null @@ -1,207 +0,0 @@ -package com.tangem.tap.domain.userWalletList.repository.implementation - -import com.squareup.moshi.JsonAdapter -import com.squareup.moshi.Moshi -import com.squareup.moshi.Types -import com.tangem.common.* -import com.tangem.common.authentication.storage.AuthenticatedStorage -import com.tangem.common.core.TangemSdkError -import com.tangem.common.services.secure.SecureStorage -import com.tangem.core.analytics.api.AnalyticsEventHandler -import com.tangem.core.analytics.models.AnalyticsParam -import com.tangem.core.analytics.models.Basic -import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.domain.wallets.legacy.UserWalletsListError -import com.tangem.tap.domain.userWalletList.model.UserWalletEncryptionKey -import com.tangem.tap.domain.userWalletList.repository.UserWalletsKeysRepository -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.withContext - -internal class BiometricUserWalletsKeysRepository( - moshi: Moshi, - private val authenticatedStorage: AuthenticatedStorage, - private val secureStorage: SecureStorage, - private val analyticsEventHandler: AnalyticsEventHandler, -) : UserWalletsKeysRepository { - - private val encryptionKeyAdapter: JsonAdapter = moshi.adapter( - UserWalletEncryptionKey::class.java, - ) - private val userWalletsIdsListAdapter: JsonAdapter> = moshi.adapter( - Types.newParameterizedType(List::class.java, UserWalletId::class.java), - ) - - override suspend fun getAll(): CompletionResult> { - return withContext(Dispatchers.IO) { - getAllInternal() - .mapFailure { error -> - val mappedError = when (error) { - is TangemSdkError.AuthenticationLockout -> - UserWalletsListError.BiometricsAuthenticationLockout(isPermanent = false) - is TangemSdkError.AuthenticationPermanentLockout -> - UserWalletsListError.BiometricsAuthenticationLockout(isPermanent = true) - is TangemSdkError.KeystoreInvalidated -> - UserWalletsListError.AllKeysInvalidated - is TangemSdkError.AuthenticationUnavailable -> - UserWalletsListError.BiometricsAuthenticationDisabled - else -> error - } - analyticsEventHandler.send( - Basic.BiometryFailed( - source = AnalyticsParam.ScreensSources.SignIn, - reason = BiometricFailReasonConverter.convert(mappedError), - ), - ) - mappedError - } - } - } - - override suspend fun save(encryptionKey: UserWalletEncryptionKey): CompletionResult { - return withContext(Dispatchers.IO) { - storeEncryptionKey(encryptionKey) - } - } - - override suspend fun delete(userWalletsIds: List) { - return withContext(Dispatchers.IO) { - userWalletsIds.forEach { userWalletId -> - deleteEncryptionKey(userWalletId) - } - - deleteUserWalletsIds(userWalletsIds) - } - } - - override suspend fun clear() { - return withContext(Dispatchers.IO) { - getUserWalletsIds() - .forEach { userWalletId -> - deleteEncryptionKey(userWalletId) - } - - clearUserWalletsIds() - } - } - - override fun hasSavedEncryptionKeys(): Boolean { - return runBlocking { - getUserWalletsIds().isNotEmpty() - } - } - - private suspend fun getAllInternal(): CompletionResult> { - return catching { - val userWalletIds = getUserWalletsIds() - - getEncryptionKeys(userWalletIds) - } - .doOnFailure { error -> - when (error) { - is TangemSdkError.KeystoreInvalidated -> { - getUserWalletsIds().forEach { userWalletId -> - deleteEncryptionKey(userWalletId) - } - } - else -> Unit - } - } - } - - private suspend fun getEncryptionKeys(userWalletsIds: List): List { - val keys = userWalletsIds.map { userWalletId -> - StorageKey.UserWalletEncryptionKey(userWalletId).name - } - - return authenticatedStorage.get(keys).mapNotNull { (_, encodedData) -> - encodedData.decodeToKey() - } - } - - private suspend fun storeEncryptionKey(encryptionKey: UserWalletEncryptionKey): CompletionResult { - return catching { - authenticatedStorage.store( - keyAlias = StorageKey.UserWalletEncryptionKey(encryptionKey.walletId).name, - data = encryptionKey.encode(), - ) - } - .map { storeUserWalletId(encryptionKey.walletId) } - } - - private fun deleteEncryptionKey(userWalletId: UserWalletId) { - authenticatedStorage.delete(StorageKey.UserWalletEncryptionKey(userWalletId).name) - } - - private suspend fun getUserWalletsIds(): List { - return withContext(Dispatchers.IO) { - secureStorage.get(StorageKey.UserWalletIds.name) - .decodeToUserWalletsIds() - } - } - - private suspend fun storeUserWalletId(userWalletId: UserWalletId) { - val userWalletIds = (getUserWalletsIds() + userWalletId).distinct() - - withContext(Dispatchers.IO) { - secureStorage.store(userWalletIds.encode(), StorageKey.UserWalletIds.name) - } - } - - private suspend fun deleteUserWalletsIds(userWalletsIds: List) { - val remainingIds = getUserWalletsIds() - userWalletsIds.toSet() - - withContext(Dispatchers.IO) { - secureStorage.store(remainingIds.encode(), StorageKey.UserWalletIds.name) - } - } - - private suspend fun clearUserWalletsIds() { - withContext(Dispatchers.IO) { - secureStorage.delete(StorageKey.UserWalletIds.name) - } - } - - private suspend fun UserWalletEncryptionKey.encode(): ByteArray { - return withContext(Dispatchers.Default) { - encryptionKeyAdapter.toJson(this@encode) - .encodeToByteArray(throwOnInvalidSequence = true) - } - } - - private suspend fun ByteArray?.decodeToKey(): UserWalletEncryptionKey? { - return withContext(Dispatchers.Default) { - this@decodeToKey - ?.decodeToString(throwOnInvalidSequence = true) - ?.let(encryptionKeyAdapter::fromJson) - } - } - - private suspend fun List.encode(): ByteArray { - return withContext(Dispatchers.Default) { - userWalletsIdsListAdapter.toJson(this@encode) - .encodeToByteArray(throwOnInvalidSequence = true) - } - } - - private suspend fun ByteArray?.decodeToUserWalletsIds(): List { - return withContext(Dispatchers.Default) { - this@decodeToUserWalletsIds - ?.decodeToString(throwOnInvalidSequence = true) - ?.let(userWalletsIdsListAdapter::fromJson) - .orEmpty() - } - } - - private sealed interface StorageKey { - val name: String - - class UserWalletEncryptionKey(userWalletId: UserWalletId) : StorageKey { - override val name: String = "user_wallet_encryption_key_${userWalletId.stringValue}" - } - - object UserWalletIds : StorageKey { - override val name: String = "user_wallets_ids_with_saved_keys" - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/utils/Mapper.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/utils/Mapper.kt index 2b08bba4a9..c9184f1335 100644 --- a/app/src/main/java/com/tangem/tap/domain/userWalletList/utils/Mapper.kt +++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/utils/Mapper.kt @@ -104,8 +104,6 @@ internal fun List.updateWith( } } -internal fun List.lockAll(): List = map(UserWallet::lock) - internal fun UserWallet.lock(): UserWallet = when (this) { is UserWallet.Cold -> { copy( diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt index e3e1923c6b..6ecd467e40 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt @@ -3,15 +3,12 @@ package com.tangem.tap.features.details.redux import com.tangem.common.CompletionResult import com.tangem.common.doOnFailure import com.tangem.common.doOnSuccess -import com.tangem.common.routing.AppRoute import com.tangem.core.analytics.Analytics import com.tangem.domain.apptheme.model.AppThemeMode import com.tangem.domain.common.wallets.UserWalletsListRepository.LockMethod -import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.models.wallet.UserWallet import com.tangem.tap.common.analytics.events.AnalyticsParam import com.tangem.tap.common.analytics.events.Settings -import com.tangem.tap.common.extensions.dispatchNavigationAction import com.tangem.tap.common.extensions.dispatchWithMain import com.tangem.tap.common.extensions.inject import com.tangem.tap.common.redux.AppState @@ -43,7 +40,7 @@ class DetailsMiddleware { if (!DemoHelper.tryHandle(stateProvider)) { val detailsState = stateProvider()?.detailsState if (detailsState != null) { - handleAction(detailsState, action) + handleAction(action) } } next(action) @@ -51,9 +48,9 @@ class DetailsMiddleware { } } - private fun handleAction(state: DetailsState, action: Action) { + private fun handleAction(action: Action) { when (action) { - is DetailsAction.AppSettings -> appSettingsMiddleware.handle(state, action) + is DetailsAction.AppSettings -> appSettingsMiddleware.handle(action) } } @@ -61,12 +58,10 @@ class DetailsMiddleware { private val checkBiometricsStatusJobHolder = JobHolder() - fun handle(state: DetailsState, action: DetailsAction.AppSettings) { + fun handle(action: DetailsAction.AppSettings) { when (action) { is DetailsAction.AppSettings.SwitchPrivacySetting -> { when (action.setting) { - AppSetting.SaveWallets -> toggleSaveWallets(state, enable = action.enable) - AppSetting.SaveAccessCode -> toggleSaveAccessCodes(state, enable = action.enable) AppSetting.RequireAccessCode -> toggleRequireAccessCode(enable = action.enable) AppSetting.BiometricAuthentication -> toggleBiometricsAuthentication(enable = action.enable) } @@ -221,118 +216,6 @@ class DetailsMiddleware { } } - private fun toggleSaveWallets(state: DetailsState, enable: Boolean) = scope.launch { - // Nothing to change - val walletsRepository = store.inject(DaggerGraphState::walletsRepository) - - if (walletsRepository.shouldSaveUserWalletsSync() == enable) { - store.dispatchWithMain(DetailsAction.AppSettings.SwitchPrivacySetting.Success) - return@launch - } - - toggleSaveWallets(state.scanResponse, enable) - .doOnFailure { - store.dispatchWithMain( - DetailsAction.AppSettings.SwitchPrivacySetting.Failure( - prevState = !enable, - setting = AppSetting.SaveWallets, - ), - ) - } - .doOnSuccess { - store.dispatchWithMain(DetailsAction.AppSettings.SwitchPrivacySetting.Success) - } - } - - private suspend fun toggleSaveWallets(scanResponse: ScanResponse?, enable: Boolean): CompletionResult { - return if (enable) { - saveCurrentWallet(scanResponse, enableAccessCodesSaving = false) - } else { - deleteSavedWalletsAndAccessCodes() - } - } - - private fun toggleSaveAccessCodes(state: DetailsState, enable: Boolean) = scope.launch { - val shouldSaveAccessCodes = store.inject(DaggerGraphState::settingsRepository).shouldSaveAccessCodes() - - // Nothing to change - if (shouldSaveAccessCodes == enable) { - store.dispatchWithMain(DetailsAction.AppSettings.SwitchPrivacySetting.Success) - return@launch - } - - toggleSaveAccessCodes(state.scanResponse, state.appSettingsState.saveWallets, enable) - .doOnFailure { - store.dispatchWithMain( - DetailsAction.AppSettings.SwitchPrivacySetting.Failure( - prevState = !enable, - setting = AppSetting.SaveAccessCode, - ), - ) - } - .doOnSuccess { - store.dispatchWithMain(DetailsAction.AppSettings.SwitchPrivacySetting.Success) - } - } - - private suspend fun toggleSaveAccessCodes( - scanResponse: ScanResponse?, - isWalletsSavingEnabled: Boolean, - enable: Boolean, - ): CompletionResult { - return if (enable) { - if (!isWalletsSavingEnabled) { - saveCurrentWallet(scanResponse, enableAccessCodesSaving = true) - } else { - saveAccessCodes(scanResponse) - } - } else { - deleteSavedAccessCodes() - } - } - - private suspend fun saveCurrentWallet( - scanResponse: ScanResponse?, - enableAccessCodesSaving: Boolean, - ): CompletionResult { - store.inject(DaggerGraphState::walletsRepository).saveShouldSaveUserWallets(item = true) - - return if (enableAccessCodesSaving) { - saveAccessCodes(scanResponse) - } else { - CompletionResult.Success(Unit) - } - .doOnSuccess { - Analytics.send(Settings.AppSettings.SaveWalletSwitcherChanged(AnalyticsParam.OnOffState.On)) - } - .doOnFailure { error -> - Timber.e(error, "Unable to save user wallet") - } - } - - private suspend fun deleteSavedWalletsAndAccessCodes(): CompletionResult { - Analytics.send(Settings.AppSettings.SaveWalletSwitcherChanged(AnalyticsParam.OnOffState.Off)) - - deleteSavedAccessCodes() - store.inject(DaggerGraphState::walletsRepository).saveShouldSaveUserWallets(item = false) - - store.dispatchNavigationAction { replaceAll(AppRoute.Home()) } - - return CompletionResult.Success(Unit) - } - - private suspend fun saveAccessCodes(scanResponse: ScanResponse?): CompletionResult { - Analytics.send(Settings.AppSettings.SaveAccessCodeSwitcherChanged(AnalyticsParam.OnOffState.On)) - - store.inject(DaggerGraphState::settingsRepository).setShouldSaveAccessCodes(value = true) - - store.inject(DaggerGraphState::cardSdkConfigRepository).setAccessCodeRequestPolicy( - isBiometricsRequestPolicy = scanResponse?.card?.isAccessCodeSet == true, - ) - - return CompletionResult.Success(Unit) - } - private suspend fun deleteSavedAccessCodes(): CompletionResult { return tangemSdkManager.clearSavedUserCodes() .doOnSuccess { diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt index 54a13d6915..a01428dbfd 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt @@ -38,15 +38,6 @@ private fun handlePrivacyAction(action: DetailsAction.AppSettings, state: Detail return when (action) { is DetailsAction.AppSettings.SwitchPrivacySetting -> state.copy( appSettingsState = when (action.setting) { - AppSetting.SaveWallets -> state.appSettingsState.copy( - isInProgress = true, - saveWallets = action.enable, - ) - AppSetting.SaveAccessCode -> state.appSettingsState.copy( - isInProgress = true, - saveWallets = true, // User can't enable access codes saving without wallets saving - saveAccessCodes = action.enable, - ) AppSetting.RequireAccessCode -> state.appSettingsState.copy( isInProgress = true, requireAccessCode = action.enable, @@ -64,14 +55,6 @@ private fun handlePrivacyAction(action: DetailsAction.AppSettings, state: Detail ) is DetailsAction.AppSettings.SwitchPrivacySetting.Failure -> state.copy( appSettingsState = when (action.setting) { - AppSetting.SaveWallets -> state.appSettingsState.copy( - isInProgress = false, - saveWallets = action.prevState, - ) - AppSetting.SaveAccessCode -> state.appSettingsState.copy( - isInProgress = false, - saveAccessCodes = action.prevState, - ) AppSetting.RequireAccessCode -> state.appSettingsState.copy( isInProgress = false, requireAccessCode = action.prevState, @@ -105,9 +88,6 @@ private fun handlePrivacyAction(action: DetailsAction.AppSettings, state: Detail // state should be copied to avoid concurrent modifications from different sources is DetailsAction.AppSettings.Prepare -> state.copy( appSettingsState = state.appSettingsState.copy( - saveWallets = action.state.saveWallets, - saveAccessCodes = action.state.saveAccessCodes, - isBiometricsAvailable = action.state.isBiometricsAvailable, isHidingEnabled = action.state.isHidingEnabled, selectedAppCurrency = action.state.selectedAppCurrency, selectedThemeMode = action.state.selectedThemeMode, diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt index 518cd67afb..83cf685304 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt @@ -13,12 +13,6 @@ data class DetailsState( @Suppress("BooleanPropertyNaming") data class AppSettingsState( - @Deprecated("Delete after hot wallet release") - val saveWallets: Boolean = false, - @Deprecated("Delete after hot wallet release") - val saveAccessCodes: Boolean = false, - @Deprecated("Delete after hot wallet release") - val isBiometricsAvailable: Boolean = false, val requireAccessCode: Boolean = false, val useBiometricAuthentication: Boolean = false, val needEnrollBiometrics: Boolean = false, @@ -32,5 +26,5 @@ data class AppSettingsState( enum class SecurityOption { LongTap, PassCode, AccessCode } enum class AppSetting { - SaveWallets, SaveAccessCode, RequireAccessCode, BiometricAuthentication, + RequireAccessCode, BiometricAuthentication, } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsDialogsFactory.kt b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsDialogsFactory.kt index 73459bc7b9..106fad8b50 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsDialogsFactory.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsDialogsFactory.kt @@ -9,26 +9,6 @@ import kotlinx.collections.immutable.toImmutableList internal class AppSettingsDialogsFactory { - fun createDeleteSavedWalletsAlert(onDelete: () -> Unit, onDismiss: () -> Unit): Dialog.Alert { - return Dialog.Alert( - title = resourceReference(R.string.common_attention), - description = resourceReference(R.string.app_settings_off_saved_wallet_alert_message), - confirmText = resourceReference(R.string.common_delete), - onConfirm = onDelete, - onDismiss = onDismiss, - ) - } - - fun createDeleteSavedAccessCodesAlert(onDelete: () -> Unit, onDismiss: () -> Unit): Dialog.Alert { - return Dialog.Alert( - title = resourceReference(R.string.common_attention), - description = resourceReference(R.string.app_settings_off_saved_access_code_alert_message), - confirmText = resourceReference(R.string.common_delete), - onConfirm = onDelete, - onDismiss = onDismiss, - ) - } - fun createThemeModeSelectorDialog( selectedModeIndex: Int, onSelect: (AppThemeMode) -> Unit, diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsItemsFactory.kt b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsItemsFactory.kt index 53b58cdd25..f8f30677e8 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsItemsFactory.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsItemsFactory.kt @@ -19,21 +19,6 @@ internal class AppSettingsItemsFactory { ) } - fun createSaveWalletsSwitch( - isChecked: Boolean, - isEnabled: Boolean, - onCheckedChange: (Boolean) -> Unit, - ): Item.Switch { - return Item.Switch( - id = ID_SAVE_WALLETS_SWITCH, - title = resourceReference(R.string.app_settings_saved_wallet), - description = resourceReference(R.string.app_settings_saved_wallet_footer), - isEnabled = isEnabled, - isChecked = isChecked, - onCheckedChange = onCheckedChange, - ) - } - fun createUseBiometricsSwitch( isChecked: Boolean, isEnabled: Boolean, @@ -127,7 +112,6 @@ internal class AppSettingsItemsFactory { companion object { const val ID_ENROLL_BIOMETRICS_CARD = "enroll_biometrics_card" - const val ID_SAVE_WALLETS_SWITCH = "save_wallets_switch" const val ID_SAVE_ACCESS_CODES_SWITCH = "save_access_codes_switch" const val ID_FLIP_TO_HIDE_BALANCE_SWITCH = "flip_to_hide_balance_switch" const val ID_SELECT_APP_CURRENCY_BUTTON = "select_app_currency_button" diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsScreen.kt b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsScreen.kt index 438819ed0a..d17e6b23b6 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsScreen.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsScreen.kt @@ -97,7 +97,6 @@ private class AppSettingsScreenStateProvider : CollectionPreviewParameterProvide val items = persistentListOf( itemsFactory.createEnrollBiometricsCard {}, itemsFactory.createSelectAppCurrencyButton(currentAppCurrencyName = "US Dollar") {}, - itemsFactory.createSaveWalletsSwitch(isChecked = true, isEnabled = true, { _ -> }), itemsFactory.createSaveAccessCodeSwitch(isChecked = false, isEnabled = true) { _ -> }, itemsFactory.createFlipToHideBalanceSwitch(isChecked = false, isEnabled = true) { _ -> }, itemsFactory.createSelectThemeModeButton(AppThemeMode.DEFAULT, {}), diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/components/SettingsAlertDialog.kt b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/components/SettingsAlertDialog.kt index f27a3d76d8..ff7916fd68 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/components/SettingsAlertDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/components/SettingsAlertDialog.kt @@ -43,12 +43,12 @@ private fun AlertDialogPreview(@PreviewParameter(AlertDialogProvider::class) dia } } -private class AlertDialogProvider : CollectionPreviewParameterProvider( +private class AlertDialogProvider : CollectionPreviewParameterProvider( collection = buildList { val dialogsFactory = AppSettingsDialogsFactory() - add(dialogsFactory.createDeleteSavedAccessCodesAlert({}, {})) - add(dialogsFactory.createDeleteSavedWalletsAlert({}, {})) + add(dialogsFactory.createThemeModeSelectorDialog(selectedModeIndex = 0, onSelect = {}, onDismiss = {})) + add(dialogsFactory.createDisableBiometricAuthenticationAlert(onDisable = {}, onDismiss = {})) }, ) // endregion Preview \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/model/AppSettingsModel.kt b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/model/AppSettingsModel.kt index c5cc2f6f36..3f7613c86c 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/model/AppSettingsModel.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/model/AppSettingsModel.kt @@ -14,10 +14,7 @@ import com.tangem.domain.apptheme.model.AppThemeMode import com.tangem.domain.apptheme.repository.AppThemeModeRepository import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository import com.tangem.domain.common.wallets.UserWalletsListRepository -import com.tangem.domain.settings.CanUseBiometryUseCase -import com.tangem.domain.settings.repositories.SettingsRepository import com.tangem.domain.wallets.repository.WalletsRepository -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.tap.common.analytics.events.AnalyticsParam import com.tangem.tap.common.analytics.events.Settings import com.tangem.tap.common.extensions.dispatchNavigationAction @@ -52,14 +49,11 @@ internal class AppSettingsModel @Inject constructor( override val dispatchers: CoroutineDispatcherProvider, private val appCurrencyRepository: AppCurrencyRepository, private val walletsRepository: WalletsRepository, - private val canUseBiometryUseCase: CanUseBiometryUseCase, private val userWalletsListRepository: UserWalletsListRepository, private val balanceHidingRepository: BalanceHidingRepository, private val analyticsEventHandler: AnalyticsEventHandler, private val appThemeModeRepository: AppThemeModeRepository, - private val settingsRepository: SettingsRepository, private val appSettingsItemsAnalyticsSender: AppSettingsItemsAnalyticsSender, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, private val uiMessageSender: UiMessageSender, ) : Model(), StoreSubscriber { @@ -120,47 +114,25 @@ internal class AppSettingsModel @Inject constructor( ), ) - if (hotWalletFeatureToggles.isHotWalletEnabled) { - val canUseBiometrics = - !state.needEnrollBiometrics && !state.isInProgress && state.hasSecuredWallets + val canUseBiometrics = + !state.needEnrollBiometrics && !state.isInProgress && state.hasSecuredWallets - add( - itemsFactory.createUseBiometricsSwitch( - isChecked = state.useBiometricAuthentication, - isEnabled = canUseBiometrics, - onCheckedChange = ::onBiometricAuthenticationToggled, - onDisabledClick = ::onBiometricAuthenticationDisabledClicked, - ), - ) + add( + itemsFactory.createUseBiometricsSwitch( + isChecked = state.useBiometricAuthentication, + isEnabled = canUseBiometrics, + onCheckedChange = ::onBiometricAuthenticationToggled, + onDisabledClick = ::onBiometricAuthenticationDisabledClicked, + ), + ) - add( - itemsFactory.createRequireAccessCodeSwitch( - isChecked = state.requireAccessCode || !state.useBiometricAuthentication, - isEnabled = canUseBiometrics && state.useBiometricAuthentication, - onCheckedChange = ::onRequireAccessCodeToggled, - ), - ) - } else { - if (state.isBiometricsAvailable) { - val canUseBiometrics = !state.needEnrollBiometrics && !state.isInProgress - - add( - itemsFactory.createSaveWalletsSwitch( - isChecked = state.saveWallets, - isEnabled = canUseBiometrics, - onCheckedChange = ::onSaveWalletsToggled, - ), - ) - - add( - itemsFactory.createSaveAccessCodeSwitch( - isChecked = state.saveAccessCodes, - isEnabled = canUseBiometrics, - onCheckedChange = ::onSaveAccessCodesToggled, - ), - ) - } - } + add( + itemsFactory.createRequireAccessCodeSwitch( + isChecked = state.requireAccessCode || !state.useBiometricAuthentication, + isEnabled = canUseBiometrics && state.useBiometricAuthentication, + onCheckedChange = ::onRequireAccessCodeToggled, + ), + ) add( itemsFactory.createFlipToHideBalanceSwitch( @@ -261,42 +233,6 @@ internal class AppSettingsModel @Inject constructor( } } - private fun onSaveWalletsToggled(isChecked: Boolean) { - if (isChecked) { - onSettingsToggled(AppSetting.SaveWallets, enable = true) - } else { - updateContentState { - copy( - dialog = dialogsFactory.createDeleteSavedWalletsAlert( - onDelete = { - onSettingsToggled(AppSetting.SaveWallets, enable = false) - dismissDialog() - }, - onDismiss = ::dismissDialog, - ), - ) - } - } - } - - private fun onSaveAccessCodesToggled(isChecked: Boolean) { - if (isChecked) { - onSettingsToggled(AppSetting.SaveAccessCode, enable = true) - } else { - updateContentState { - copy( - dialog = dialogsFactory.createDeleteSavedAccessCodesAlert( - onDelete = { - onSettingsToggled(AppSetting.SaveAccessCode, enable = false) - dismissDialog() - }, - onDismiss = ::dismissDialog, - ), - ) - } - } - } - private fun onSettingsToggled(setting: AppSetting, enable: Boolean) { store.dispatch(DetailsAction.AppSettings.SwitchPrivacySetting(enable = enable, setting = setting)) } @@ -326,9 +262,6 @@ internal class AppSettingsModel @Inject constructor( private fun bootstrapBiometricsUpdates() = modelScope.launch { val state = AppSettingsState( - saveWallets = walletsRepository.shouldSaveUserWalletsSync(), - saveAccessCodes = settingsRepository.shouldSaveAccessCodes(), - isBiometricsAvailable = canUseBiometryUseCase(), useBiometricAuthentication = walletsRepository.useBiometricAuthentication(), requireAccessCode = walletsRepository.requireAccessCode(), isHidingEnabled = balanceHidingRepository.getBalanceHidingSettings().isHidingEnabledInSettings, diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/model/ResetCardModel.kt b/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/model/ResetCardModel.kt index c53ead9529..6e124933fc 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/model/ResetCardModel.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/model/ResetCardModel.kt @@ -14,12 +14,9 @@ import com.tangem.domain.card.ResetCardUseCase import com.tangem.domain.card.ResetCardUserCodeParams import com.tangem.domain.card.common.util.cardTypesResolver import com.tangem.domain.models.wallet.requireColdWallet -import com.tangem.domain.wallets.legacy.UserWalletsListManager -import com.tangem.domain.wallets.legacy.asLockable import com.tangem.domain.wallets.usecase.DeleteWalletUseCase import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase import com.tangem.domain.wallets.usecase.GetUserWalletUseCase -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.tap.common.analytics.events.Settings import com.tangem.tap.common.extensions.dispatchNavigationAction import com.tangem.tap.common.extensions.onUserWalletSelected @@ -52,10 +49,8 @@ internal class ResetCardModel @Inject constructor( private val resetCardUseCase: ResetCardUseCase, private val deleteSavedAccessCodesUseCase: DeleteSavedAccessCodesUseCase, private val deleteWalletUseCase: DeleteWalletUseCase, - private val userWalletsListManager: UserWalletsListManager, private val analyticsEventHandler: AnalyticsEventHandler, private val cardSettingsInteractor: CardSettingsInteractor, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, ) : Model() { private val params = paramsContainer.require() @@ -277,16 +272,7 @@ internal class ResetCardModel @Inject constructor( if (newSelectedWallet != null) { store.dispatchNavigationAction { popTo() } } else { - if (hotWalletFeatureToggles.isHotWalletEnabled) { - store.dispatchNavigationAction { replaceAll(AppRoute.Home()) } - } else { - val isLocked = runCatching { userWalletsListManager.asLockable()?.isLocked }.isSuccess - if (isLocked && userWalletsListManager.hasUserWallets) { - store.dispatchNavigationAction { popTo() } - } else { - store.dispatchNavigationAction { replaceAll(AppRoute.Home()) } - } - } + store.dispatchNavigationAction { replaceAll(AppRoute.Home()) } } } diff --git a/app/src/main/java/com/tangem/tap/features/welcome/component/DefaultWelcomeComponent.kt b/app/src/main/java/com/tangem/tap/features/welcome/component/DefaultWelcomeComponent.kt deleted file mode 100644 index b90ec7a20f..0000000000 --- a/app/src/main/java/com/tangem/tap/features/welcome/component/DefaultWelcomeComponent.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.tangem.tap.features.welcome.component - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Modifier -import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.tangem.core.decompose.context.AppComponentContext -import com.tangem.core.decompose.model.getOrCreateModel -import com.tangem.tap.features.welcome.model.WelcomeModel -import com.tangem.tap.features.welcome.ui.components.WelcomeScreen -import dagger.assisted.Assisted -import dagger.assisted.AssistedFactory -import dagger.assisted.AssistedInject - -internal class DefaultWelcomeComponent @AssistedInject constructor( - @Assisted context: AppComponentContext, - @Assisted params: WelcomeComponent.Params, -) : WelcomeComponent, AppComponentContext by context { - - private val model: WelcomeModel = getOrCreateModel(params) - - @Composable - override fun Content(modifier: Modifier) { - val state by model.state.collectAsStateWithLifecycle() - - WelcomeScreen( - modifier = modifier, - state = state, - ) - } - - @AssistedFactory - interface Factory : WelcomeComponent.Factory { - override fun create(context: AppComponentContext, params: WelcomeComponent.Params): DefaultWelcomeComponent - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/welcome/component/WelcomeComponent.kt b/app/src/main/java/com/tangem/tap/features/welcome/component/WelcomeComponent.kt deleted file mode 100644 index 120b0b5484..0000000000 --- a/app/src/main/java/com/tangem/tap/features/welcome/component/WelcomeComponent.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.tangem.tap.features.welcome.component - -import com.tangem.common.routing.entity.InitScreenLaunchMode -import com.tangem.core.decompose.factory.ComponentFactory -import com.tangem.core.ui.decompose.ComposableContentComponent - -interface WelcomeComponent : ComposableContentComponent { - - data class Params( - val launchMode: InitScreenLaunchMode, - ) - - interface Factory : ComponentFactory -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/welcome/component/impl/PreviewWelcomeComponent.kt b/app/src/main/java/com/tangem/tap/features/welcome/component/impl/PreviewWelcomeComponent.kt deleted file mode 100644 index 94c08e4f70..0000000000 --- a/app/src/main/java/com/tangem/tap/features/welcome/component/impl/PreviewWelcomeComponent.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.tangem.tap.features.welcome.component.impl - -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import com.tangem.tap.features.welcome.component.WelcomeComponent -import com.tangem.tap.features.welcome.ui.WelcomeScreenState -import com.tangem.tap.features.welcome.ui.components.WelcomeScreen - -internal class PreviewWelcomeComponent( - private val initialState: WelcomeScreenState = WelcomeScreenState(), -) : WelcomeComponent { - - @Composable - override fun Content(modifier: Modifier) { - WelcomeScreen( - modifier = modifier, - state = initialState, - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/welcome/di/ComponentModule.kt b/app/src/main/java/com/tangem/tap/features/welcome/di/ComponentModule.kt deleted file mode 100644 index 68f1c6121f..0000000000 --- a/app/src/main/java/com/tangem/tap/features/welcome/di/ComponentModule.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.tangem.tap.features.welcome.di - -import com.tangem.tap.features.welcome.component.DefaultWelcomeComponent -import com.tangem.tap.features.welcome.component.WelcomeComponent -import dagger.Binds -import dagger.Module -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import javax.inject.Singleton - -@Module -@InstallIn(SingletonComponent::class) -internal interface ComponentModule { - - @Binds - @Singleton - fun bindWelcomeComponentFactory(factory: DefaultWelcomeComponent.Factory): WelcomeComponent.Factory -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/welcome/di/ModelModule.kt b/app/src/main/java/com/tangem/tap/features/welcome/di/ModelModule.kt deleted file mode 100644 index 92e347fe26..0000000000 --- a/app/src/main/java/com/tangem/tap/features/welcome/di/ModelModule.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.tangem.tap.features.welcome.di - -import com.tangem.core.decompose.di.ModelComponent -import com.tangem.core.decompose.model.Model -import com.tangem.tap.features.welcome.model.WelcomeModel -import dagger.Binds -import dagger.Module -import dagger.hilt.InstallIn -import dagger.multibindings.ClassKey -import dagger.multibindings.IntoMap - -@Module -@InstallIn(ModelComponent::class) -internal interface ModelModule { - - @Binds - @IntoMap - @ClassKey(WelcomeModel::class) - fun bindWelcomeModel(model: WelcomeModel): Model -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/welcome/model/WelcomeModel.kt b/app/src/main/java/com/tangem/tap/features/welcome/model/WelcomeModel.kt deleted file mode 100644 index fcfcc02601..0000000000 --- a/app/src/main/java/com/tangem/tap/features/welcome/model/WelcomeModel.kt +++ /dev/null @@ -1,140 +0,0 @@ -package com.tangem.tap.features.welcome.model - -import com.tangem.common.core.TangemError -import com.tangem.common.routing.entity.InitScreenLaunchMode -import com.tangem.core.analytics.api.AnalyticsEventHandler -import com.tangem.core.decompose.di.ModelScoped -import com.tangem.core.decompose.model.Model -import com.tangem.core.decompose.model.ParamsContainer -import com.tangem.core.navigation.finisher.AppFinisher -import com.tangem.domain.wallets.legacy.UserWalletsListError -import com.tangem.tap.common.analytics.events.SignIn -import com.tangem.tap.common.redux.global.GlobalAction -import com.tangem.core.ui.extensions.TextReference -import com.tangem.tap.features.welcome.component.WelcomeComponent -import com.tangem.tap.features.welcome.redux.WelcomeAction -import com.tangem.tap.features.welcome.redux.WelcomeState -import com.tangem.tap.features.welcome.ui.WelcomeScreenState -import com.tangem.tap.features.welcome.ui.model.WarningModel -import com.tangem.tap.store -import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.update -import org.rekotlin.StoreSubscriber -import javax.inject.Inject - -// FIXME: Remove redux: [REDACTED_JIRA] -@ModelScoped -internal class WelcomeModel @Inject constructor( - override val dispatchers: CoroutineDispatcherProvider, - private val appFinisher: AppFinisher, - private val analyticsEventsHandler: AnalyticsEventHandler, - paramsContainer: ParamsContainer, -) : Model(), StoreSubscriber { - - private val params: WelcomeComponent.Params = paramsContainer.require() - private val initialState: WelcomeScreenState = WelcomeScreenState( - onPopBack = appFinisher::finish, - onUnlockClick = this::unlockWallets, - onScanCardClick = this::scanCard, - onCloseError = this::closeError, - ) - - val state: MutableStateFlow = MutableStateFlow(initialState) - - init { - subscribeToStoreChanges() - initGlobalState() - - val welcomeAction = when (params.launchMode) { - is InitScreenLaunchMode.WithCardScan -> WelcomeAction.ProceedWithCard - is InitScreenLaunchMode.Standard -> WelcomeAction.ProceedWithBiometrics - } - - store.dispatch(welcomeAction) - } - - private fun unlockWallets() { - analyticsEventsHandler.send(SignIn.ButtonBiometricSignIn()) - store.dispatch(WelcomeAction.ProceedWithBiometrics) - } - - private fun scanCard() { - analyticsEventsHandler.send(SignIn.ButtonCardSignIn()) - store.dispatch(WelcomeAction.ProceedWithCard) - } - - private fun closeError() { - store.dispatch(WelcomeAction.CloseError) - } - - override fun newState(state: WelcomeState) { - val warning = createWarningIfNeeded(state.error) - - this.state.update { prevState -> - prevState.copy( - isUnlockWithBiometricsProgressVisible = state.isUnlockWithBiometricsInProgress, - isUnlockWithCardProgressVisible = state.isUnlockWithCardInProgress, - warning = warning, - error = state.error - ?.takeIf { !it.silent && warning == null } - ?.let { error -> - val messageResId = error.messageResId - if (messageResId != null) { - TextReference.Res(messageResId) - } else { - TextReference.Str(error.customMessage) - } - }, - ) - } - } - - override fun onDestroy() { - store.unsubscribe(subscriber = this) - - super.onDestroy() - } - - private fun createWarningIfNeeded(error: TangemError?): WarningModel? { - return when (error) { - is UserWalletsListError.BiometricsAuthenticationLockout -> WarningModel.BiometricsLockoutWarning( - isPermanent = error.isPermanent, - onDismiss = this::dismissWarning, - ) - is UserWalletsListError.AllKeysInvalidated, - is UserWalletsListError.NoUserWalletSelected, - -> WarningModel.KeyInvalidatedWarning( - onDismiss = this::dismissWarning, - ) - is UserWalletsListError.BiometricsAuthenticationDisabled -> WarningModel.BiometricsDisabledWarning( - onDismiss = this::clearUserWallets, - ) - else -> null - } - } - - private fun dismissWarning() { - state.update { prevState -> - prevState.copy( - warning = null, - ) - } - closeError() - } - - private fun clearUserWallets() { - store.dispatch(WelcomeAction.ClearUserWallets) - } - - private fun subscribeToStoreChanges() { - store.subscribe(this) { appState -> - appState.skip { old, new -> old.welcomeState == new.welcomeState } - .select { it.welcomeState } - } - } - - private fun initGlobalState() { - store.dispatch(GlobalAction.RestoreAppCurrency) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeAction.kt b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeAction.kt deleted file mode 100644 index 6d0e6b6183..0000000000 --- a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeAction.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.tangem.tap.features.welcome.redux - -import com.tangem.common.core.TangemError -import org.rekotlin.Action - -internal sealed interface WelcomeAction : Action { - - data object ProceedWithBiometrics : WelcomeAction { - object Success : WelcomeAction - data class Error(val error: TangemError) : WelcomeAction - } - - object ProceedWithCard : WelcomeAction { - object Success : WelcomeAction - data class Error(val error: TangemError) : WelcomeAction - data class ChangeProgress(val isProgress: Boolean) : WelcomeAction - } - - object CloseError : WelcomeAction - - object ClearUserWallets : WelcomeAction -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt deleted file mode 100644 index 3fea04772f..0000000000 --- a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt +++ /dev/null @@ -1,164 +0,0 @@ -package com.tangem.tap.features.welcome.redux - -import com.tangem.common.core.TangemSdkError -import com.tangem.common.doOnFailure -import com.tangem.common.doOnResult -import com.tangem.common.doOnSuccess -import com.tangem.common.flatMap -import com.tangem.common.routing.AppRoute -import com.tangem.common.routing.utils.popTo -import com.tangem.core.analytics.Analytics -import com.tangem.core.analytics.models.AnalyticsParam -import com.tangem.core.analytics.models.Basic -import com.tangem.domain.card.analytics.ParamCardCurrencyConverter -import com.tangem.domain.card.common.util.cardTypesResolver -import com.tangem.domain.models.scan.ScanResponse -import com.tangem.domain.models.wallet.UserWallet -import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType -import com.tangem.domain.wallets.legacy.unlockIfLockable -import com.tangem.tap.* -import com.tangem.tap.common.extensions.* -import com.tangem.tap.common.redux.AppState -import com.tangem.tap.proxy.redux.DaggerGraphState -import kotlinx.coroutines.launch -import org.rekotlin.Middleware -import timber.log.Timber - -internal class WelcomeMiddleware { - val middleware: Middleware = { _, appStateProvider -> - { next -> - { action -> - val appState = appStateProvider() - if (action is WelcomeAction && appState != null) { - handleAction(action) - } - next(action) - } - } - } - - private fun handleAction(action: WelcomeAction) { - mainScope.launch { - when (action) { - is WelcomeAction.ProceedWithBiometrics -> proceedWithBiometrics() - is WelcomeAction.ProceedWithCard -> proceedWithCard() - is WelcomeAction.ClearUserWallets -> disableUserWalletsSaving() - else -> Unit - } - } - } - - private suspend fun proceedWithBiometrics() { - val userWalletsListManager = store.inject(DaggerGraphState::generalUserWalletsListManager) - userWalletsListManager.unlockIfLockable(type = UnlockType.ANY) - .doOnFailure { error -> - Timber.e(error, "Unable to unlock user wallets with biometrics") - store.dispatchWithMain(WelcomeAction.ProceedWithBiometrics.Error(error)) - } - .doOnSuccess { selectedUserWallet -> - sendSignedInAnalyticsEvent( - userWallet = selectedUserWallet, - signInType = Basic.SignedInLegacy.SignInType.Biometric, - ) - - store.dispatchNavigationAction { replaceAll(AppRoute.Wallet) } - store.dispatchWithMain(WelcomeAction.ProceedWithBiometrics.Success) - store.onUserWalletSelected(userWallet = selectedUserWallet) - } - } - - private suspend fun proceedWithCard() { - scanCardInternal { scanResponse -> - val userWalletBuilder = store.inject(DaggerGraphState::coldUserWalletBuilderFactory).create(scanResponse) - - val userWallet = userWalletBuilder.build() ?: return@scanCardInternal - - val userWalletsListManager = store.inject(DaggerGraphState::generalUserWalletsListManager) - userWalletsListManager.save(userWallet, canOverride = true) - .doOnFailure { error -> - Timber.e(error, "Unable to save user wallet") - store.dispatchWithMain(WelcomeAction.ProceedWithCard.Error(error)) - } - .doOnSuccess { - sendSignedInAnalyticsEvent(userWallet, signInType = Basic.SignedInLegacy.SignInType.Card) - - store.dispatchNavigationAction { replaceAll(AppRoute.Wallet) } - store.dispatchWithMain(WelcomeAction.ProceedWithCard.Success) - store.onUserWalletSelected(userWallet = userWallet) - } - } - } - - private fun sendSignedInAnalyticsEvent(userWallet: UserWallet, signInType: Basic.SignedInLegacy.SignInType) { - if (userWallet !is UserWallet.Cold) { - return - } - - val scanResponse = userWallet.scanResponse - val currency = ParamCardCurrencyConverter().convert( - value = scanResponse.cardTypesResolver, - ) - - val trackingContextProxy = store.inject(DaggerGraphState::trackingContextProxy) - trackingContextProxy.addContext(scanResponse) - - if (currency != null) { - val userWalletsListManager = store.inject(DaggerGraphState::generalUserWalletsListManager) - - Analytics.send( - event = Basic.SignedInLegacy( - currency = currency, - batch = scanResponse.card.batchId, - signInType = signInType, - walletsCount = userWalletsListManager.walletsCount.toString(), - isImported = userWallet.isImported, - hasBackup = scanResponse.card.backupStatus?.isActive, - ), - ) - } - } - - private suspend fun disableUserWalletsSaving() { - val userWalletsListManager = store.inject(DaggerGraphState::generalUserWalletsListManager) - userWalletsListManager.clear() - .flatMap { tangemSdkManager.clearSavedUserCodes() } - .doOnFailure { e -> - Timber.e(e, "Unable to clear user wallets") - } - .doOnResult { - store.dispatchWithMain(WelcomeAction.CloseError) - store.dispatchNavigationAction { popTo() } - } - } - - private suspend inline fun scanCardInternal(crossinline onCardScanned: suspend (ScanResponse) -> Unit) { - val shouldSaveAccessCodes = store.inject(DaggerGraphState::settingsRepository).shouldSaveAccessCodes() - - store.inject(DaggerGraphState::cardSdkConfigRepository).setAccessCodeRequestPolicy( - isBiometricsRequestPolicy = shouldSaveAccessCodes, - ) - - store.inject(DaggerGraphState::scanCardProcessor).scan( - analyticsSource = AnalyticsParam.ScreensSources.SignIn, - onSuccess = { scanResponse -> - scope.launch { onCardScanned(scanResponse) } - }, - onFailure = { error -> - when (error) { - is TangemSdkError.ExceptionError -> { - store.dispatchOnMain(WelcomeAction.ProceedWithCard.Success) - } - else -> { - store.dispatchOnMain(WelcomeAction.ProceedWithCard.Error(error)) - } - } - }, - onProgressStateChange = { - store.dispatchWithMain(WelcomeAction.ProceedWithCard.ChangeProgress(it)) - }, - onWalletNotCreated = { - store.dispatchOnMain(WelcomeAction.ProceedWithCard.Success) - }, - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeReducer.kt b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeReducer.kt deleted file mode 100644 index f324887d0a..0000000000 --- a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeReducer.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.tangem.tap.features.welcome.redux - -import com.tangem.tap.common.redux.AppState -import org.rekotlin.Action - -internal object WelcomeReducer { - fun reduce(action: Action, state: AppState): WelcomeState { - return if (action is WelcomeAction) { - internalReduce(action, state.welcomeState) - } else { - state.welcomeState - } - } - - private fun internalReduce(action: WelcomeAction, state: WelcomeState): WelcomeState { - return when (action) { - is WelcomeAction.ProceedWithBiometrics -> state.copy(isUnlockWithBiometricsInProgress = true) - is WelcomeAction.ProceedWithCard -> state.copy(isUnlockWithCardInProgress = true) - is WelcomeAction.ProceedWithBiometrics.Error -> state.copy( - error = action.error, - isUnlockWithBiometricsInProgress = false, - ) - is WelcomeAction.ProceedWithCard.Error -> state.copy( - error = action.error, - isUnlockWithCardInProgress = false, - ) - is WelcomeAction.ProceedWithCard.ChangeProgress -> state.copy( - isUnlockWithCardInProgress = action.isProgress, - ) - is WelcomeAction.ProceedWithBiometrics.Success -> state.copy(isUnlockWithBiometricsInProgress = false) - is WelcomeAction.ProceedWithCard.Success -> state.copy(isUnlockWithCardInProgress = false) - is WelcomeAction.CloseError -> state.copy(error = null) - else -> state - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeState.kt b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeState.kt deleted file mode 100644 index a4fce23f93..0000000000 --- a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeState.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.tangem.tap.features.welcome.redux - -import com.tangem.common.core.TangemError -import org.rekotlin.StateType - -data class WelcomeState( - val isUnlockWithBiometricsInProgress: Boolean = false, - val isUnlockWithCardInProgress: Boolean = false, - val error: TangemError? = null, -) : StateType \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeScreenState.kt b/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeScreenState.kt deleted file mode 100644 index 5c3ddfe725..0000000000 --- a/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeScreenState.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.tangem.tap.features.welcome.ui - -import com.tangem.core.ui.extensions.TextReference -import com.tangem.tap.features.welcome.ui.model.WarningModel - -internal data class WelcomeScreenState( - val onPopBack: () -> Unit = {}, - val isUnlockWithBiometricsProgressVisible: Boolean = false, - val isUnlockWithCardProgressVisible: Boolean = false, - val warning: WarningModel? = null, - val error: TextReference? = null, - val onUnlockClick: () -> Unit = {}, - val onScanCardClick: () -> Unit = {}, - val onCloseError: () -> Unit = {}, -) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/welcome/ui/components/WarningDialog.kt b/app/src/main/java/com/tangem/tap/features/welcome/ui/components/WarningDialog.kt deleted file mode 100644 index 2dc63dd5dd..0000000000 --- a/app/src/main/java/com/tangem/tap/features/welcome/ui/components/WarningDialog.kt +++ /dev/null @@ -1,136 +0,0 @@ -package com.tangem.tap.features.welcome.ui.components - -import android.content.res.Configuration -import androidx.compose.foundation.layout.Column -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview -import com.tangem.core.ui.components.BasicDialog -import com.tangem.core.ui.components.DialogButtonUM -import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.tap.features.welcome.ui.model.WarningModel -import com.tangem.wallet.R - -@Composable -internal fun WarningDialog(warning: WarningModel?) { - when (warning) { - null -> Unit - is WarningModel.BiometricsLockoutWarning -> { - BasicDialog( - title = stringResourceSafe(id = R.string.biometric_lockout_warning_title), - message = stringResourceSafe( - id = if (warning.isPermanent) { - R.string.biometric_lockout_permanent_warning_description - } else { - R.string.biometric_lockout_warning_description - }, - ), - onDismissDialog = warning.onDismiss, - confirmButton = DialogButtonUM( - title = stringResourceSafe(id = R.string.common_ok), - onClick = warning.onDismiss, - ), - ) - } - is WarningModel.KeyInvalidatedWarning -> { - BasicDialog( - title = stringResourceSafe(id = R.string.common_attention), - message = stringResourceSafe(id = R.string.key_invalidated_warning_description), - onDismissDialog = warning.onDismiss, - confirmButton = DialogButtonUM( - title = stringResourceSafe(id = R.string.common_ok), - onClick = warning.onDismiss, - ), - ) - } - is WarningModel.BiometricsDisabledWarning -> { - BasicDialog( - title = stringResourceSafe(id = R.string.common_warning), - message = stringResourceSafe(id = R.string.biometric_unavailable_warning), - onDismissDialog = warning.onDismiss, - isDismissable = false, - confirmButton = DialogButtonUM( - title = stringResourceSafe(id = R.string.common_ok), - onClick = warning.onDismiss, - ), - ) - } - } -} - -// region Preview -@Composable -private fun BiometricsLockoutDialogSample(modifier: Modifier = Modifier) { - Column(modifier = modifier) { - WarningDialog( - warning = WarningModel.BiometricsLockoutWarning( - isPermanent = false, - onDismiss = {}, - ), - ) - } -} - -@Preview(showBackground = true, widthDp = 360) -@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun BiometricsLockoutDialogPreview() { - TangemThemePreview { - BiometricsLockoutDialogSample() - } -} - -@Composable -private fun BiometricsLockoutDialog_Permanent_Sample(modifier: Modifier = Modifier) { - Column(modifier = modifier) { - WarningDialog( - warning = WarningModel.BiometricsLockoutWarning( - isPermanent = true, - onDismiss = {}, - ), - ) - } -} - -@Preview(showBackground = true, widthDp = 360) -@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun BiometricsLockoutDialog_Permanent_Preview() { - TangemThemePreview { - BiometricsLockoutDialog_Permanent_Sample() - } -} - -@Composable -private fun KeyInvalidatedWarningSample(modifier: Modifier = Modifier) { - Column(modifier = modifier) { - WarningDialog(warning = WarningModel.KeyInvalidatedWarning(onDismiss = {})) - } -} - -@Preview(showBackground = true, widthDp = 360) -@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun KeyInvalidatedWarningPreview() { - TangemThemePreview { - KeyInvalidatedWarningSample() - } -} - -@Composable -private fun BiometricDisabledWarningSample(modifier: Modifier = Modifier) { - Column(modifier = modifier) { - WarningDialog(warning = WarningModel.BiometricsDisabledWarning(onDismiss = {})) - } -} - -@Preview(showBackground = true, widthDp = 360) -@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun BiometricDisabledWarningPreview() { - TangemThemePreview { - BiometricDisabledWarningSample() - } -} -// endregion Preview \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/welcome/ui/components/WelcomeScreen.kt b/app/src/main/java/com/tangem/tap/features/welcome/ui/components/WelcomeScreen.kt deleted file mode 100644 index 50cfcc86b1..0000000000 --- a/app/src/main/java/com/tangem/tap/features/welcome/ui/components/WelcomeScreen.kt +++ /dev/null @@ -1,101 +0,0 @@ -package com.tangem.tap.features.welcome.ui.components - -import android.content.res.Configuration -import androidx.activity.compose.BackHandler -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.systemBarsPadding -import androidx.compose.material3.SnackbarHost -import androidx.compose.material3.SnackbarHostState -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import androidx.compose.ui.unit.dp -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.core.ui.extensions.TextReference -import com.tangem.core.ui.extensions.resolveReference -import com.tangem.tap.features.welcome.component.WelcomeComponent -import com.tangem.tap.features.welcome.component.impl.PreviewWelcomeComponent -import com.tangem.tap.features.welcome.ui.WelcomeScreenState -import com.tangem.tap.features.welcome.ui.model.WarningModel - -@Composable -internal fun WelcomeScreen(state: WelcomeScreenState, modifier: Modifier = Modifier) { - val snackbarHostState = remember { SnackbarHostState() } - val errorMessage by rememberUpdatedState(newValue = state.error?.resolveReference()) - val warning by rememberUpdatedState(newValue = state.warning) - - BackHandler(onBack = state.onPopBack) - - Box( - modifier = modifier - .background(TangemTheme.colors.background.primary) - .systemBarsPadding(), - ) { - WelcomeScreenContent( - showUnlockProgress = state.isUnlockWithBiometricsProgressVisible, - showScanCardProgress = state.isUnlockWithCardProgressVisible, - onUnlockClick = state.onUnlockClick, - onScanCardClick = state.onScanCardClick, - ) - - SnackbarHost( - modifier = Modifier - .align(Alignment.BottomCenter) - .padding(vertical = 16.dp) - .fillMaxWidth(), - hostState = snackbarHostState, - ) - } - - WarningDialog(warning) - - LaunchedEffect(errorMessage, state.onCloseError) { - errorMessage?.let { message -> - snackbarHostState.showSnackbar(message) - state.onCloseError() - } - } -} - -// region Preview -@Composable -@Preview(showBackground = true, widthDp = 360) -@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) -private fun Preview_WelcomeScreen( - @PreviewParameter(WelcomeComponentPreviewProvider::class) component: WelcomeComponent, -) { - TangemThemePreview { - component.Content(Modifier) - } -} - -private class WelcomeComponentPreviewProvider : PreviewParameterProvider { - override val values: Sequence - get() = sequenceOf( - PreviewWelcomeComponent(), - PreviewWelcomeComponent( - initialState = WelcomeScreenState( - isUnlockWithBiometricsProgressVisible = true, - isUnlockWithCardProgressVisible = true, - ), - ), - PreviewWelcomeComponent( - initialState = WelcomeScreenState( - error = TextReference.Str(value = "Error"), - ), - ), - PreviewWelcomeComponent( - initialState = WelcomeScreenState( - warning = WarningModel.KeyInvalidatedWarning(onDismiss = {}), - ), - ), - ) -} -// endregion Preview \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/welcome/ui/components/WelcomeScreenContent.kt b/app/src/main/java/com/tangem/tap/features/welcome/ui/components/WelcomeScreenContent.kt deleted file mode 100644 index 433f9521fa..0000000000 --- a/app/src/main/java/com/tangem/tap/features/welcome/ui/components/WelcomeScreenContent.kt +++ /dev/null @@ -1,113 +0,0 @@ -package com.tangem.tap.features.welcome.ui.components - -import android.content.res.Configuration -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.material3.Icon -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview -import com.tangem.core.ui.components.* -import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.wallet.R - -@Suppress("LongMethod") -@Composable -internal fun WelcomeScreenContent( - showUnlockProgress: Boolean, - showScanCardProgress: Boolean, - onUnlockClick: () -> Unit, - onScanCardClick: () -> Unit, - modifier: Modifier = Modifier, -) { - Column( - modifier = modifier, - horizontalAlignment = Alignment.CenterHorizontally, - ) { - SpacerHMax() - Icon( - modifier = Modifier.size(TangemTheme.dimens.size96), - painter = painterResource(id = R.drawable.img_tangem_logo_96), - tint = TangemTheme.colors.icon.primary1, - contentDescription = null, - ) - SpacerH32() - Text( - modifier = Modifier - .padding(horizontal = TangemTheme.dimens.spacing16) - .fillMaxWidth(), - text = stringResourceSafe(R.string.welcome_unlock_title), - style = TangemTheme.typography.h2, - color = TangemTheme.colors.text.primary1, - textAlign = TextAlign.Center, - ) - SpacerH12() - Text( - modifier = Modifier - .padding(horizontal = TangemTheme.dimens.spacing44) - .fillMaxWidth(), - text = stringResourceSafe( - id = R.string.welcome_unlock_description, - stringResourceSafe(id = R.string.common_biometric_authentication), - ), - style = TangemTheme.typography.body1, - color = TangemTheme.colors.text.secondary, - textAlign = TextAlign.Center, - ) - SpacerHMax() - SecondaryButton( - modifier = Modifier - .padding(horizontal = TangemTheme.dimens.spacing16) - .fillMaxWidth(), - text = stringResourceSafe( - id = R.string.welcome_unlock, - stringResourceSafe(id = R.string.common_biometrics), - ), - showProgress = showUnlockProgress, - onClick = onUnlockClick, - ) - SpacerH12() - PrimaryButtonIconEnd( - modifier = Modifier - .padding(horizontal = TangemTheme.dimens.spacing16) - .fillMaxWidth(), - text = stringResourceSafe(R.string.welcome_unlock_card), - showProgress = showScanCardProgress, - iconResId = R.drawable.ic_tangem_24, - onClick = onScanCardClick, - ) - SpacerH16() - } -} - -// region Preview -@Composable -private fun WelcomeScreenContentSample(modifier: Modifier = Modifier) { - Box( - modifier = modifier - .background(TangemTheme.colors.background.primary), - ) { - WelcomeScreenContent( - showUnlockProgress = false, - showScanCardProgress = false, - onUnlockClick = { /* no-op */ }, - onScanCardClick = { /* no-op */ }, - ) - } -} - -@Preview(showBackground = true, widthDp = 360) -@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun WelcomeScreenContentPreview() { - TangemThemePreview { - WelcomeScreenContentSample() - } -} -// endregion Preview \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/welcome/ui/model/WarningModel.kt b/app/src/main/java/com/tangem/tap/features/welcome/ui/model/WarningModel.kt deleted file mode 100644 index f8fb28135c..0000000000 --- a/app/src/main/java/com/tangem/tap/features/welcome/ui/model/WarningModel.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.tangem.tap.features.welcome.ui.model - -internal sealed interface WarningModel { - data class BiometricsLockoutWarning( - val isPermanent: Boolean, - val onDismiss: () -> Unit, - ) : WarningModel - - data class KeyInvalidatedWarning( - val onDismiss: () -> Unit, - ) : WarningModel - - data class BiometricsDisabledWarning( - val onDismiss: () -> Unit, - ) : WarningModel -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/network/auth/DefaultAuthProvider.kt b/app/src/main/java/com/tangem/tap/network/auth/DefaultAuthProvider.kt index 79a50c1403..1c102c9e0c 100644 --- a/app/src/main/java/com/tangem/tap/network/auth/DefaultAuthProvider.kt +++ b/app/src/main/java/com/tangem/tap/network/auth/DefaultAuthProvider.kt @@ -6,14 +6,11 @@ import com.tangem.datasource.api.common.config.ApiEnvironment import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.models.wallet.UserWallet -import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.utils.Provider import com.tangem.utils.ProviderSuspend internal class DefaultAuthProvider( - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, - private val shouldUseNewListRepository: Boolean = false, private val environmentConfigStorage: EnvironmentConfigStorage, ) : AuthProvider { @@ -71,18 +68,10 @@ internal class DefaultAuthProvider( } private suspend fun getWallets(): List { - return if (shouldUseNewListRepository) { - userWalletsListRepository.userWalletsSync() - } else { - userWalletsListManager.userWalletsSync - } + return userWalletsListRepository.userWalletsSync() } private suspend fun getSelectedWallet(): UserWallet? { - return if (shouldUseNewListRepository) { - userWalletsListRepository.selectedUserWalletSync() - } else { - userWalletsListManager.selectedUserWalletSync - } + return userWalletsListRepository.selectedUserWalletSync() } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/network/auth/di/AuthModule.kt b/app/src/main/java/com/tangem/tap/network/auth/di/AuthModule.kt index b6f4c2bec8..e6cba79706 100644 --- a/app/src/main/java/com/tangem/tap/network/auth/di/AuthModule.kt +++ b/app/src/main/java/com/tangem/tap/network/auth/di/AuthModule.kt @@ -3,16 +3,10 @@ package com.tangem.tap.network.auth.di import com.tangem.datasource.api.common.AuthProvider import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage import com.tangem.domain.common.wallets.UserWalletsListRepository -import com.tangem.domain.wallets.legacy.UserWalletsListManager -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.lib.auth.ExpressAuthProvider import com.tangem.lib.auth.P2PEthPoolAuthProvider import com.tangem.lib.auth.StakeKitAuthProvider -import com.tangem.tap.network.auth.DefaultAppVersionProvider -import com.tangem.tap.network.auth.DefaultAuthProvider -import com.tangem.tap.network.auth.DefaultExpressAuthProvider -import com.tangem.tap.network.auth.DefaultP2PEthPoolAuthProvider -import com.tangem.tap.network.auth.DefaultStakeKitAuthProvider +import com.tangem.tap.network.auth.* import com.tangem.utils.version.AppVersionProvider import dagger.Module import dagger.Provides @@ -27,15 +21,11 @@ internal class AuthModule { @Provides @Singleton fun provideAuthProvider( - userWalletsListManager: UserWalletsListManager, userWalletsListRepository: UserWalletsListRepository, - hotWalletFeatureToggles: HotWalletFeatureToggles, environmentConfigStorage: EnvironmentConfigStorage, ): AuthProvider { return DefaultAuthProvider( - userWalletsListManager = userWalletsListManager, userWalletsListRepository = userWalletsListRepository, - shouldUseNewListRepository = hotWalletFeatureToggles.isHotWalletEnabled, environmentConfigStorage = environmentConfigStorage, ) } diff --git a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt index 8095c3df87..133c325afc 100644 --- a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt +++ b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt @@ -31,9 +31,7 @@ import com.tangem.domain.onboarding.repository.OnboardingRepository import com.tangem.domain.settings.repositories.SettingsRepository import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.builder.ColdUserWalletBuilder -import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.repository.WalletsRepository -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles import com.tangem.hot.sdk.TangemHotSdk import com.tangem.operations.attestation.CardArtworksProvider @@ -53,7 +51,6 @@ data class DaggerGraphState( val appThemeModeRepository: AppThemeModeRepository? = null, val balanceHidingRepository: BalanceHidingRepository? = null, val walletsRepository: WalletsRepository? = null, - val generalUserWalletsListManager: UserWalletsListManager? = null, val wasTwinsOnboardingShownUseCase: WasTwinsOnboardingShownUseCase? = null, val saveTwinsOnboardingShownUseCase: SaveTwinsOnboardingShownUseCase? = null, val cardRepository: CardRepository? = null, @@ -78,7 +75,6 @@ data class DaggerGraphState( val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory? = null, val userTokensResponseStore: UserTokensResponseStore? = null, val userWalletsListRepository: UserWalletsListRepository? = null, - val hotWalletFeatureToggles: HotWalletFeatureToggles? = null, val tangemHotSdk: TangemHotSdk? = null, val trackingContextProxy: TrackingContextProxy? = null, ) : StateType \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/routing/component/impl/DefaultRoutingComponent.kt b/app/src/main/java/com/tangem/tap/routing/component/impl/DefaultRoutingComponent.kt index 23bc630cec..52a03dcf84 100644 --- a/app/src/main/java/com/tangem/tap/routing/component/impl/DefaultRoutingComponent.kt +++ b/app/src/main/java/com/tangem/tap/routing/component/impl/DefaultRoutingComponent.kt @@ -29,7 +29,6 @@ import com.tangem.domain.common.wallets.UserWalletsListRepository 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.HotWalletFeatureToggles import com.tangem.features.hotwallet.accesscoderequest.proxy.HotWalletPasswordRequesterProxy import com.tangem.features.walletconnect.components.WcRoutingComponent import com.tangem.hot.sdk.TangemHotSdk @@ -69,7 +68,6 @@ internal class DefaultRoutingComponent @AssistedInject constructor( private val userWalletsListRepository: UserWalletsListRepository, private val cardRepository: CardRepository, private val onboardingRepository: OnboardingRepository, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, private val trackingContextProxy: TrackingContextProxy, private val analyticsEventHandler: AnalyticsEventHandler, private val analyticsExceptionHandler: AnalyticsExceptionHandler, @@ -254,16 +252,14 @@ internal class DefaultRoutingComponent @AssistedInject constructor( } private suspend fun trackSignInEvent() { - if (hotWalletFeatureToggles.isHotWalletEnabled) { - val userWallets = userWalletsListRepository.userWalletsSync() - val selectedWallet = userWalletsListRepository.selectedUserWalletSync() ?: return - trackingContextProxy.addContext(selectedWallet) - analyticsEventHandler.send( - event = Basic.SignedIn( - signInType = Basic.SignedIn.SignInType.NoSecurity, - walletsCount = userWallets.size, - ), - ) - } + val userWallets = userWalletsListRepository.userWalletsSync() + val selectedWallet = userWalletsListRepository.selectedUserWalletSync() ?: return + trackingContextProxy.addContext(selectedWallet) + analyticsEventHandler.send( + event = Basic.SignedIn( + signInType = Basic.SignedIn.SignInType.NoSecurity, + walletsCount = userWallets.size, + ), + ) } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt index f182a2555b..cbc3285d4f 100644 --- a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt +++ b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt @@ -52,7 +52,6 @@ import com.tangem.tap.features.details.ui.cardsettings.api.CardSettingsComponent import com.tangem.tap.features.details.ui.cardsettings.coderecovery.api.AccessCodeRecoveryComponent import com.tangem.tap.features.details.ui.resetcard.api.ResetCardComponent import com.tangem.tap.features.details.ui.securitymode.api.SecurityModeComponent -import com.tangem.tap.features.welcome.component.WelcomeComponent import com.tangem.tap.routing.component.RoutingComponent.Child import dagger.hilt.android.scopes.ActivityScoped import javax.inject.Inject @@ -76,7 +75,6 @@ internal class ChildFactory @Inject constructor( private val sellCryptoComponentFactory: SellCryptoComponent.Factory, private val swapSelectTokensComponentFactory: SwapSelectTokensComponent.Factory, private val onboardingEntryComponentFactory: OnboardingEntryComponent.Factory, - private val welcomeComponentFactory: WelcomeComponent.Factory, private val newWelcomeComponentFactory: NewWelcomeComponent.Factory, private val storiesComponentFactory: StoriesComponent.Factory, private val stakingComponentFactory: StakingComponent.Factory, @@ -118,7 +116,6 @@ internal class ChildFactory @Inject constructor( private val tangemPayOnboardingComponentFactory: TangemPayOnboardingComponent.Factory, private val kycComponentFactory: KycComponent.Factory, private val yieldSupplyEntryComponentFactory: YieldSupplyEntryComponent.Factory, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, private val feedEntryComponentFactory: FeedEntryComponent.Factory, private val feedFeatureToggle: FeedFeatureToggle, ) { @@ -162,21 +159,11 @@ internal class ChildFactory @Inject constructor( ) } is AppRoute.Welcome -> { - if (hotWalletFeatureToggles.isHotWalletEnabled) { - createComponentChild( - context = context, - params = Unit, - componentFactory = newWelcomeComponentFactory, - ) - } else { - createComponentChild( - context = context, - params = WelcomeComponent.Params( - launchMode = route.launchMode, - ), - componentFactory = welcomeComponentFactory, - ) - } + createComponentChild( + context = context, + params = Unit, + componentFactory = newWelcomeComponentFactory, + ) } is AppRoute.WalletSettings -> { createComponentChild( diff --git a/app/src/test/kotlin/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManagerTest.kt b/app/src/test/kotlin/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManagerTest.kt deleted file mode 100644 index 7e54ffc6bd..0000000000 --- a/app/src/test/kotlin/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManagerTest.kt +++ /dev/null @@ -1,216 +0,0 @@ -package com.tangem.tap.domain.userWalletList.implementation - -import com.google.common.truth.Truth -import com.tangem.common.test.domain.card.MockScanResponseFactory -import com.tangem.domain.card.configs.GenericCardConfig -import com.tangem.domain.models.wallet.UserWallet -import com.tangem.domain.models.wallet.UserWalletId -import io.mockk.mockk -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.Parameterized -import kotlin.reflect.full.declaredFunctions -import kotlin.reflect.jvm.isAccessible - -/** -[REDACTED_AUTHOR] - */ -@RunWith(Parameterized::class) -internal class BiometricUserWalletsListManagerTest(private val model: Model) { - - private val manager = BiometricUserWalletsListManager( - keysRepository = mockk(), - publicInformationRepository = mockk(), - sensitiveInformationRepository = mockk(), - selectedUserWalletRepository = mockk(), - dispatcherProvider = mockk(), - ) - - @Test - fun testFindAvailableUserWallet() { - with(model) { - val actual = userWallets.findAvailableUserWallet(prevSelectedIndex) - - Truth.assertThat(actual).isEqualTo(newSelectedWallet) - } - } - - private fun List.findAvailableUserWallet(prevSelectedIndex: Int): UserWallet? { - return manager::class - .declaredFunctions - .firstOrNull { it.name == "findAvailableUserWallet" } - ?.apply { isAccessible = true } - ?.call(manager, this, prevSelectedIndex) - as? UserWallet - } - - data class Model( - val userWallets: List, - val prevSelectedIndex: Int, - val newSelectedWallet: UserWallet?, - ) - - private companion object { - - val userWallet0 = createUserWallet(id = "0", isLocked = false) - val lockedUserWallet0 = createUserWallet(id = "0", isLocked = true) - - val userWallet1 = createUserWallet(id = "1", isLocked = false) - val lockedUserWallet1 = createUserWallet(id = "1", isLocked = true) - - val userWallet2 = createUserWallet(id = "2", isLocked = false) - val lockedUserWallet2 = createUserWallet(id = "2", isLocked = true) - - val userWallet3 = createUserWallet(id = "3", isLocked = false) - val lockedUserWallet3 = createUserWallet(id = "3", isLocked = true) - - val unlockedWallets = listOf(userWallet0, userWallet1, userWallet2, userWallet3) - val lockedWallets = listOf(lockedUserWallet0, lockedUserWallet1, lockedUserWallet2, lockedUserWallet3) - - @JvmStatic - @Parameterized.Parameters - fun data(): Collection { - return listOf( - Model(userWallets = emptyList(), prevSelectedIndex = 0, newSelectedWallet = null), - *getTestsWithUnlockedWallets().toTypedArray(), - *getTestsIfPrevSelectedIndexIs0().toTypedArray(), - *getTestsIfPrevSelectedIndexIsLastIndex().toTypedArray(), - *getTestsIfNewSelectedIndexIsNearby().toTypedArray(), - *getTestsIfNewSelectedIndexIsThroughOne().toTypedArray(), - ) - } - - fun getTestsWithUnlockedWallets() = listOf( - // [*0*, 1, 2, 3, 4] => delete 0 => [1, 2, 3, 4] => select 1 => [*1*, 2, 3, 4] - Model(userWallets = unlockedWallets, prevSelectedIndex = 0, newSelectedWallet = userWallet0), - // [0, *1*, 2, 3, 4] => delete 1 => [0, 2, 3, 4] => select 2 => [0, *2*, 3, 4] - Model(userWallets = unlockedWallets, prevSelectedIndex = 1, newSelectedWallet = userWallet1), - // [0, 1, *2*, 3, 4] => delete 2 => [0, 1, 3, 4] => select 3 => [0, 1, *3*, 4] - Model(userWallets = unlockedWallets, prevSelectedIndex = 2, newSelectedWallet = userWallet2), - // [0, 1, 2, *3*, 4] => delete 3 => [0, 1, 2, 4] => select 4 => [0, 1, 2, 4] - Model(userWallets = unlockedWallets, prevSelectedIndex = 3, newSelectedWallet = userWallet3), - // [0, 1, 2, 3, *4*] => delete 4 => [0, 1, 2, 3] => select 3 => [0, 1, 2, *3*] - Model(userWallets = unlockedWallets, prevSelectedIndex = 4, newSelectedWallet = userWallet3), - ) - - fun getTestsIfPrevSelectedIndexIs0() = listOf( - // [*0*, -1-, 2, 3, 4] => delete 0 => [-1-, 2, 3, 4] => select 2 => [-1-, *2*, 3, 4] - Model( - userWallets = listOf(lockedUserWallet0, userWallet1, userWallet2, userWallet3), - prevSelectedIndex = 0, - newSelectedWallet = userWallet1, - ), - // [*0*, -1-, -2-, 3, 4] => delete 0 => [-1-, -2-, 3, 4] => select 3 => [-1-, -2-, *3*, 4] - Model( - userWallets = listOf(lockedUserWallet0, lockedUserWallet1, userWallet2, userWallet3), - prevSelectedIndex = 0, - newSelectedWallet = userWallet2, - ), - // [*0*, -1-, -2-, -3-, 4] => delete 0 => [-1-, -2-, -3-, 4] => select 4 => [-1-, -2-, -3-, *4*] - Model( - userWallets = listOf(lockedUserWallet0, lockedUserWallet1, lockedUserWallet2, userWallet3), - prevSelectedIndex = 0, - newSelectedWallet = userWallet3, - ), - // [*0*, -1-, -2-, -3-, -4-] => delete 0 => [-1-, -2-, -3-, -4-] => select 1 => [*-1-*, -2-, -3-, -4-] - Model(userWallets = lockedWallets, prevSelectedIndex = 0, newSelectedWallet = lockedUserWallet0), - ) - - fun getTestsIfPrevSelectedIndexIsLastIndex() = listOf( - // [0, 1, 2, -3-, *4*] => delete 4 => [0, 1, 2, -3-] => select 2 => [0, 1, *2*, -3-] - Model( - userWallets = listOf(userWallet0, userWallet1, userWallet2, lockedUserWallet3), - prevSelectedIndex = 4, - newSelectedWallet = userWallet2, - ), - // [0, 1, -2-, -3-, *4*] => delete 4 => [0, 1, -2-, -3-] => select 1 => [0, *1*, -2-, -3-] - Model( - userWallets = listOf(userWallet0, userWallet1, lockedUserWallet2, lockedUserWallet3), - prevSelectedIndex = 4, - newSelectedWallet = userWallet1, - ), - // [0, -1-, -2-, -3-, *4*] => delete 4 => [0, -1-, -2-, -3-] => select 0 => [*0*, -1-, -2-, -3-] - Model( - userWallets = listOf(userWallet0, lockedUserWallet1, lockedUserWallet2, lockedUserWallet3), - prevSelectedIndex = 4, - newSelectedWallet = userWallet0, - ), - // [-0-, -1-, -2-, -3-, *4*] => delete 4 => [-0-, -1-, -2-, -3-] => select 3 => [-0-, -1-, -2-, *-3-*] - Model(userWallets = lockedWallets, prevSelectedIndex = 4, newSelectedWallet = lockedUserWallet3), - ) - - fun getTestsIfNewSelectedIndexIsNearby() = listOf( - // [0, *1*, 2, 3, 4] => delete 1 => [0, 2, 3, 4] => select 2 => [0, *2*, 3, 4] - Model(userWallets = unlockedWallets, prevSelectedIndex = 1, newSelectedWallet = userWallet1), - // [0, *1*, -2-, 3, 4] => delete 1 => [0, -2-, 3, 4] => select 3 => [0, -2-, *3*, 4] - Model( - userWallets = listOf(userWallet0, lockedUserWallet1, userWallet2, userWallet3), - prevSelectedIndex = 1, - newSelectedWallet = userWallet2, - ), - // [0, *1*, -2-, -3-, 4] => delete 1 => [0, -2-, -3-, 4] => select 0 => [*0*, -2-, -3-, 4] - Model( - userWallets = listOf(userWallet0, lockedUserWallet1, lockedUserWallet2, userWallet3), - prevSelectedIndex = 1, - newSelectedWallet = userWallet0, - ), - // [0, 1, 2, *3*, 4] => delete 3 => [0, 1, 2, 4] => select 4 => [0, 1, 2, *4*] - Model(userWallets = unlockedWallets, prevSelectedIndex = 3, newSelectedWallet = userWallet3), - // [0, 1, 2, *3*, -4-] => delete 3 => [0, 1, 2, -4-] => select 2 => [0, 1, *2*, -4-] - Model( - userWallets = listOf(userWallet0, userWallet1, userWallet2, lockedUserWallet3), - prevSelectedIndex = 3, - newSelectedWallet = userWallet2, - ), - ) - - fun getTestsIfNewSelectedIndexIsThroughOne() = listOf( - // [-0-, *1*, -2-, 3, 4] => delete 1 => [-0-, -2-, 3, 4] => select 3 => [-0-, -2-, *3*, 4] - Model( - userWallets = listOf(lockedUserWallet0, lockedUserWallet1, userWallet2, userWallet3), - prevSelectedIndex = 1, - newSelectedWallet = userWallet2, - ), - // [-0-, *1*, -2-, -3-, 4] => delete 1 => [-0-, -2-, -3-, 4] => select 4 => [-0-, -2-, -3-, *4*] - Model( - userWallets = listOf(lockedUserWallet0, lockedUserWallet1, lockedUserWallet2, userWallet3), - prevSelectedIndex = 1, - newSelectedWallet = userWallet3, - ), - // [0, 1, -2-, *3*, -4-] => delete 3 => [0, 1, -2-, -4-] => select 1 => [0, *1*, -2-, -4-] - Model( - userWallets = listOf(userWallet0, userWallet1, lockedUserWallet2, lockedUserWallet3), - prevSelectedIndex = 3, - newSelectedWallet = userWallet1, - ), - // [0, -1-, -2-, *3*, -4-] => delete 3 => [*0*, -1-, -2-, -4-] => select 0 => [0, -1-, -2-, -4-] - Model( - userWallets = listOf(userWallet0, lockedUserWallet1, lockedUserWallet2, lockedUserWallet3), - prevSelectedIndex = 3, - newSelectedWallet = userWallet0, - ), - ) - - fun createUserWallet(id: String, isLocked: Boolean): UserWallet { - return UserWallet.Cold( - name = "Wallet $id", - walletId = UserWalletId(stringValue = id), - cardsInWallet = emptySet(), - isMultiCurrency = true, - hasBackupError = false, - scanResponse = MockScanResponseFactory.create( - cardConfig = GenericCardConfig(maxWalletCount = 1), - derivedKeys = emptyMap(), - ).let { - if (isLocked) { - it.copy( - card = it.card.copy(wallets = emptyList()), - ) - } else { - it - } - }, - ) - } - } -} \ No newline at end of file diff --git a/core/config-toggles/src/main/assets/configs/feature_toggles_config.json b/core/config-toggles/src/main/assets/configs/feature_toggles_config.json index 299c0abe09..1490dbb009 100644 --- a/core/config-toggles/src/main/assets/configs/feature_toggles_config.json +++ b/core/config-toggles/src/main/assets/configs/feature_toggles_config.json @@ -31,18 +31,10 @@ "name": "SWAP_REDESIGN_ENABLED", "version": "undefined" }, - { - "name": "HOT_WALLET_ENABLED", - "version": "5.32.0" - }, { "name": "HOT_WALLET_CREATION_RESTRICTION_ENABLED", "version": "5.32.0" }, - { - "name": "HOT_WALLET_VISIBLE", - "version": "5.32.1" - }, { "name": "TANGEM_PAY_ENABLED", "version": "5.31.0" diff --git a/data/feedback/src/main/java/com/tangem/data/feedback/DefaultFeedbackRepository.kt b/data/feedback/src/main/java/com/tangem/data/feedback/DefaultFeedbackRepository.kt index 24ce5d7b07..ca09522466 100644 --- a/data/feedback/src/main/java/com/tangem/data/feedback/DefaultFeedbackRepository.kt +++ b/data/feedback/src/main/java/com/tangem/data/feedback/DefaultFeedbackRepository.kt @@ -13,7 +13,6 @@ import com.tangem.domain.feedback.repository.FeedbackRepository import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.usecase.GetSelectedWalletUseCase import com.tangem.utils.version.AppVersionProvider import kotlinx.coroutines.flow.MutableStateFlow @@ -26,7 +25,6 @@ import java.io.File * * @property appLogsStore app logs store * @property userWalletsListManager user wallets list manager - * @property shouldUseNewUserWalletsRepository flag to use new user wallets repository * @property userWalletsListRepository user wallets repository * @property walletManagersStore wallet managers store * @property emailSender email sender @@ -37,9 +35,7 @@ import java.io.File @Suppress("LongParameterList") internal class DefaultFeedbackRepository( private val appLogsStore: AppLogsStore, - private val shouldUseNewUserWalletsRepository: Boolean, private val userWalletsListRepository: UserWalletsListRepository, - private val userWalletsListManager: UserWalletsListManager, private val walletManagersStore: WalletManagersStore, private val emailSender: EmailSender, private val appVersionProvider: AppVersionProvider, @@ -126,18 +122,10 @@ internal class DefaultFeedbackRepository( } private suspend fun getUserWalletById(userWalletId: UserWalletId): UserWallet? { - return if (shouldUseNewUserWalletsRepository) { - userWalletsListRepository.userWalletsSync().find { it.walletId == userWalletId } - } else { - userWalletsListManager.userWalletsSync.find { it.walletId == userWalletId } - } + return userWalletsListRepository.userWalletsSync().find { it.walletId == userWalletId } } private fun totalUserWallets(): Int { - return if (shouldUseNewUserWalletsRepository) { - userWalletsListRepository.userWallets.value?.size ?: 0 - } else { - userWalletsListManager.walletsCount - } + return userWalletsListRepository.userWallets.value?.size ?: 0 } } \ No newline at end of file diff --git a/data/feedback/src/main/java/com/tangem/data/feedback/di/FeedbackModule.kt b/data/feedback/src/main/java/com/tangem/data/feedback/di/FeedbackModule.kt index d6ecc8ef1e..db803a21d2 100644 --- a/data/feedback/src/main/java/com/tangem/data/feedback/di/FeedbackModule.kt +++ b/data/feedback/src/main/java/com/tangem/data/feedback/di/FeedbackModule.kt @@ -9,9 +9,7 @@ import com.tangem.datasource.local.walletmanager.WalletManagersStore import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.feedback.repository.FeedbackFeatureToggles import com.tangem.domain.feedback.repository.FeedbackRepository -import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.usecase.GetSelectedWalletUseCase -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.utils.version.AppVersionProvider import dagger.Module import dagger.Provides @@ -27,9 +25,7 @@ internal object FeedbackModule { @Singleton fun provideFeedbackRepository( appLogsStore: AppLogsStore, - userWalletsListManager: UserWalletsListManager, userWalletsListRepository: UserWalletsListRepository, - hotWalletFeatureToggles: HotWalletFeatureToggles, walletManagersStore: WalletManagersStore, emailSender: EmailSender, appVersionProvider: AppVersionProvider, @@ -37,12 +33,10 @@ internal object FeedbackModule { ): FeedbackRepository { return DefaultFeedbackRepository( appLogsStore = appLogsStore, - userWalletsListManager = userWalletsListManager, walletManagersStore = walletManagersStore, emailSender = emailSender, appVersionProvider = appVersionProvider, userWalletsListRepository = userWalletsListRepository, - shouldUseNewUserWalletsRepository = hotWalletFeatureToggles.isHotWalletEnabled, getSelectedWalletUseCase = getSelectedWalletUseCase, ) } diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/DefaultTangemPayEligibilityManager.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/DefaultTangemPayEligibilityManager.kt index 7225c10f60..311260900e 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/DefaultTangemPayEligibilityManager.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/DefaultTangemPayEligibilityManager.kt @@ -7,8 +7,6 @@ import com.tangem.domain.models.wallet.isLocked import com.tangem.domain.models.wallet.isMultiCurrency import com.tangem.domain.pay.TangemPayEligibilityManager import com.tangem.domain.pay.repository.OnboardingRepository -import com.tangem.domain.wallets.legacy.UserWalletsListManager -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.hot.sdk.model.HotWalletId import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.* @@ -19,9 +17,7 @@ import javax.inject.Inject internal class DefaultTangemPayEligibilityManager @Inject constructor( dispatchers: CoroutineDispatcherProvider, - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, private val onboardingRepository: OnboardingRepository, ) : TangemPayEligibilityManager { @@ -73,11 +69,7 @@ internal class DefaultTangemPayEligibilityManager @Inject constructor( return emptyList() } - val wallets = if (hotWalletFeatureToggles.isHotWalletEnabled) { - userWalletsListRepository.userWallets.value - } else { - userWalletsListManager.userWalletsSync - } ?: return emptyList() + val wallets = userWalletsListRepository.userWallets.value ?: return emptyList() return wallets.filter { wallet -> wallet.isMultiCurrency && !wallet.isLocked && wallet.isCompatible() @@ -111,11 +103,7 @@ internal class DefaultTangemPayEligibilityManager @Inject constructor( private fun resetDataWhenWalletsUpdate() { coroutineScope.launch { - if (hotWalletFeatureToggles.isHotWalletEnabled) { - userWalletsListRepository.userWallets.collectLatest { reset() } - } else { - userWalletsListManager.userWallets.collectLatest { reset() } - } + userWalletsListRepository.userWallets.collectLatest { reset() } } } diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultOnboardingRepository.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultOnboardingRepository.kt index 0872260f70..2fdcfabcb6 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultOnboardingRepository.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultOnboardingRepository.kt @@ -19,8 +19,6 @@ import com.tangem.domain.pay.model.CustomerInfo.ProductInstance import com.tangem.domain.pay.repository.OnboardingRepository import com.tangem.domain.visa.error.VisaApiError import com.tangem.domain.visa.model.TangemPayCardFrozenState -import com.tangem.domain.wallets.legacy.UserWalletsListManager -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -42,9 +40,7 @@ internal class DefaultOnboardingRepository @Inject constructor( private val tangemPayStorage: TangemPayStorage, private val authDataSource: TangemPayAuthDataSource, private val cardFrozenStateStore: TangemPayCardFrozenStateStore, - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, ) : OnboardingRepository { // Save data for a session @@ -133,12 +129,8 @@ internal class DefaultOnboardingRepository @Inject constructor( } private fun getUserWallet(userWalletId: UserWalletId): UserWallet { - val userWallet = if (hotWalletFeatureToggles.isHotWalletEnabled) { - userWalletsListRepository.userWallets.value?.firstOrNull { it.walletId == userWalletId } - } else { - userWalletsListManager.userWalletsSync.firstOrNull { it.walletId == userWalletId } - } ?: error("no userWallet found") - return userWallet + return userWalletsListRepository.userWallets.value?.firstOrNull { it.walletId == userWalletId } + ?: error("no userWallet found") } private suspend fun getCustomerInfo( diff --git a/data/wallets/src/main/java/com/tangem/data/wallets/DefaultWalletsRepository.kt b/data/wallets/src/main/java/com/tangem/data/wallets/DefaultWalletsRepository.kt index d2e807c047..cccf49fea8 100644 --- a/data/wallets/src/main/java/com/tangem/data/wallets/DefaultWalletsRepository.kt +++ b/data/wallets/src/main/java/com/tangem/data/wallets/DefaultWalletsRepository.kt @@ -20,7 +20,10 @@ import com.tangem.datasource.local.datastore.RuntimeStateStore import com.tangem.datasource.local.preferences.AppPreferencesStore import com.tangem.datasource.local.preferences.PreferencesKeys import com.tangem.datasource.local.preferences.PreferencesKeys.SEED_FIRST_NOTIFICATION_SHOW_TIME -import com.tangem.datasource.local.preferences.utils.* +import com.tangem.datasource.local.preferences.utils.getObjectMap +import com.tangem.datasource.local.preferences.utils.getSyncOrDefault +import com.tangem.datasource.local.preferences.utils.getSyncOrNull +import com.tangem.datasource.local.preferences.utils.store import com.tangem.datasource.local.userwallet.UserWalletsStore import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles import com.tangem.domain.models.wallet.UserWallet @@ -54,21 +57,6 @@ internal class DefaultWalletsRepository( private val moshi: com.squareup.moshi.Moshi, ) : WalletsRepository { - @Deprecated("Hot wallet feature makes app always save user wallets. Do not use this method") - override suspend fun shouldSaveUserWalletsSync(): Boolean { - return appPreferencesStore.getSyncOrDefault(key = PreferencesKeys.SAVE_USER_WALLETS_KEY, default = false) - } - - @Deprecated("Hot wallet feature makes app always save user wallets. Do not use this method") - override fun shouldSaveUserWallets(): Flow { - return appPreferencesStore.get(key = PreferencesKeys.SAVE_USER_WALLETS_KEY, default = false) - } - - @Deprecated("Hot wallet feature makes app always save user wallets. Do not use this method") - override suspend fun saveShouldSaveUserWallets(item: Boolean) { - appPreferencesStore.store(key = PreferencesKeys.SAVE_USER_WALLETS_KEY, value = item) - } - override suspend fun useBiometricAuthentication(): Boolean { val shouldUseBiometricAuth = appPreferencesStore.getSyncOrNull( key = PreferencesKeys.USE_BIOMETRIC_AUTHENTICATION_KEY, diff --git a/domain/markets/src/main/java/com/tangem/domain/markets/FilterAvailableNetworksForWalletUseCase.kt b/domain/markets/src/main/java/com/tangem/domain/markets/FilterAvailableNetworksForWalletUseCase.kt index aaf389d312..f2e4b3fbf1 100644 --- a/domain/markets/src/main/java/com/tangem/domain/markets/FilterAvailableNetworksForWalletUseCase.kt +++ b/domain/markets/src/main/java/com/tangem/domain/markets/FilterAvailableNetworksForWalletUseCase.kt @@ -7,12 +7,9 @@ import com.tangem.domain.card.common.extensions.supportedBlockchains import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.common.wallets.requireUserWalletsSync import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.domain.wallets.legacy.UserWalletsListManager class FilterAvailableNetworksForWalletUseCase( - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, - private val shouldUseNewRepository: Boolean, private val excludedBlockchains: ExcludedBlockchains, ) { @@ -24,9 +21,9 @@ class FilterAvailableNetworksForWalletUseCase( userWalletId: UserWalletId, networks: Set, ): Set { - val userWallet = getWallets().firstOrNull { - it.walletId == userWalletId - } ?: return networks.toSet() + val userWallet = userWalletsListRepository.requireUserWalletsSync() + .firstOrNull { it.walletId == userWalletId } + ?: return networks.toSet() val supportedBlockchains = userWallet.supportedBlockchains( excludedBlockchains = excludedBlockchains, @@ -37,10 +34,4 @@ class FilterAvailableNetworksForWalletUseCase( supportedBlockchains.contains(blockchain) }.toSet() } - - private fun getWallets() = if (shouldUseNewRepository) { - userWalletsListRepository.requireUserWalletsSync() - } else { - userWalletsListManager.userWalletsSync - } } \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/delegate/DefaultUserWalletsSyncDelegate.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/delegate/DefaultUserWalletsSyncDelegate.kt index 8af6e7c2ee..8cfc761703 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/delegate/DefaultUserWalletsSyncDelegate.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/delegate/DefaultUserWalletsSyncDelegate.kt @@ -3,22 +3,15 @@ package com.tangem.domain.wallets.delegate import arrow.core.Either import arrow.core.raise.either import arrow.core.raise.ensure -import com.tangem.common.CompletionResult import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.models.wallet.copy -import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.models.UpdateWalletError import com.tangem.domain.wallets.models.UserWalletRemoteInfo -import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import kotlinx.coroutines.withContext class DefaultUserWalletsSyncDelegate( - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, - private val useNewRepository: Boolean, - private val dispatchers: CoroutineDispatcherProvider, ) : UserWalletsSyncDelegate { override suspend fun syncWallet(userWalletId: UserWalletId, name: String): Either { @@ -34,15 +27,6 @@ class DefaultUserWalletsSyncDelegate( private suspend fun renameUserWallet( userWalletId: UserWalletId, name: String, - ): Either = if (useNewRepository) { - renameUserWalletInNewRepository(userWalletId, name) - } else { - renameUserWalletInLegacyRepository(userWalletId, name) - } - - private suspend fun renameUserWalletInNewRepository( - userWalletId: UserWalletId, - name: String, ): Either = either { val userWallets = userWalletsListRepository.userWalletsSync() val userWallet = userWallets.find { it.walletId == userWalletId } @@ -60,34 +44,7 @@ class DefaultUserWalletsSyncDelegate( userWalletsListRepository.saveWithoutLock(updatedWallet, canOverride = true) .map { updatedWallet } - .mapLeft { error -> UpdateWalletError.DataError(IllegalStateException("")) } + .mapLeft { error -> UpdateWalletError.DataError(IllegalStateException("$error")) } .bind() } - - // TODO remove dispatchers whnen UserWalletsListManager will be main safe - private suspend fun renameUserWalletInLegacyRepository( - userWalletId: UserWalletId, - name: String, - ): Either = withContext(dispatchers.io) { - either { - val existingNames = userWalletsListManager.userWalletsSync - - ensure(existingNames.none { it.name == name && it.walletId != userWalletId }) { - UpdateWalletError.NameAlreadyExists - } - - val previousName = existingNames.firstOrNull { it.walletId == userWalletId }?.name.orEmpty() - if (previousName == name) { - raise(UpdateWalletError.NameAlreadyExists) - } - - when ( - val result = - userWalletsListManager.update(userWalletId) { it.copy(name = name) } - ) { - is CompletionResult.Failure -> raise(UpdateWalletError.DataError(result.error)) - is CompletionResult.Success -> result.data - } - } - } } \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/UserWalletsListError.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/UserWalletsListError.kt deleted file mode 100644 index f287da375c..0000000000 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/UserWalletsListError.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.tangem.domain.wallets.legacy - -import com.tangem.common.core.TangemError -import com.tangem.domain.wallets.R - -sealed class UserWalletsListError(code: Int) : TangemError(code) { - - override val silent: Boolean - get() = (cause as? TangemError)?.silent == true - - override val messageResId: Int? = null - - object WalletAlreadySaved : UserWalletsListError(code = 60001) { - override var customMessage: String = "This wallet has already been saved, you can add another one" - override val messageResId: Int = R.string.user_wallet_list_error_wallet_already_saved - } - - object AllKeysInvalidated : UserWalletsListError(code = 60002) { - override var customMessage: String = "Encryption key invalidated" - } - - data class BiometricsAuthenticationLockout(val isPermanent: Boolean) : UserWalletsListError(code = 60003) { - override var customMessage: String = "Biometric authentication lockout, permanent: $isPermanent" - } - - data class UnableToUnlockUserWallets(override val cause: Throwable? = null) : UserWalletsListError(code = 60004) { - override var customMessage: String = "An error has occurred, please scan your card to log in" - override val messageResId: Int = R.string.user_wallet_list_error_unable_to_unlock - } - - object BiometricsAuthenticationDisabled : UserWalletsListError(code = 60005) { - override var customMessage: String = "Biometrics authentication disabled" - } - - object NoUserWalletSelected : UserWalletsListError(code = 60006) { - override var customMessage: String = "No user wallet selected" - } - - object NotAllUserWalletsUnlocked : UserWalletsListError(code = 60007) { - override var customMessage: String = "Not all user wallets was unlocked" - } -} \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/UserWalletsListManagerExtensions.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/UserWalletsListManagerExtensions.kt deleted file mode 100644 index cb47f21996..0000000000 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/legacy/UserWalletsListManagerExtensions.kt +++ /dev/null @@ -1,56 +0,0 @@ -package com.tangem.domain.wallets.legacy - -import com.tangem.common.CompletionResult -import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType -import com.tangem.domain.models.wallet.UserWallet -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flowOf - -/** - * Indicates that the [UserWalletsListManager] is locked - * - * @return If [UserWalletsListManager] not implements [UserWalletsListManager.Lockable] returns [Flow] which - * produces only one false value - * - * @see UserWalletsListManager.Lockable.isLocked - * */ -val UserWalletsListManager.isLocked: Flow - get() = asLockable()?.lockedState ?: flowOf(false) - -/** - * Indicates that the [UserWalletsListManager] is locked - * - * @return If [UserWalletsListManager] not implements [UserWalletsListManager.Lockable] returns false - * - * @see UserWalletsListManager.Lockable.isLocked - * */ -val UserWalletsListManager.isLockedSync: Boolean - get() = asLockable()?.isLocked == true - -/** - * Call [UserWalletsListManager.Lockable.unlock] if [UserWalletsListManager] implements [UserWalletsListManager.Lockable] - * - * @return If [UserWalletsListManager] not implements [UserWalletsListManager.Lockable] - * returns [CompletionResult.Failure] with [UserWalletsListError.UnableToUnlockUserWallets] - * - * If [UserWalletsListManager] implements [UserWalletsListManager.Lockable] - * returns [CompletionResult.Success] with selected [UserWallet] - * - * @see UserWalletsListManager.Lockable.unlock - * */ -suspend fun UserWalletsListManager.unlockIfLockable(type: UnlockType = UnlockType.ANY): CompletionResult { - return asLockable()?.unlock(type) ?: CompletionResult.Failure(UserWalletsListError.UnableToUnlockUserWallets()) -} - -/** - * Safe cast [UserWalletsListManager] to [UserWalletsListManager.Lockable] - * - * @return If [UserWalletsListManager] not implements [UserWalletsListManager.Lockable] then returns null or - * [UserWalletsListManager.Lockable] otherwise - * */ -fun UserWalletsListManager.asLockable(): UserWalletsListManager.Lockable? { - if (this.isLockable) { - return this as? UserWalletsListManager.Lockable - } - return null -} \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/models/UnlockWalletsError.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/models/UnlockWalletsError.kt deleted file mode 100644 index a6558fb0dd..0000000000 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/models/UnlockWalletsError.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.tangem.domain.wallets.models - -sealed class UnlockWalletsError { - - object UnableToUnlockWallets : UnlockWalletsError() - - object NoUserWalletSelected : UnlockWalletsError() - - object NotAllUserWalletsUnlocked : UnlockWalletsError() - - data class DataError(val cause: Throwable) : UnlockWalletsError() -} \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/repository/WalletsRepository.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/repository/WalletsRepository.kt index 1431dc5e6f..da0352f7fd 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/repository/WalletsRepository.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/repository/WalletsRepository.kt @@ -11,15 +11,6 @@ import kotlinx.coroutines.flow.Flow @Suppress("TooManyFunctions") interface WalletsRepository { - @Deprecated("Hot wallet feature makes app always save user wallets. Do not use this method") - suspend fun shouldSaveUserWalletsSync(): Boolean - - @Deprecated("Hot wallet feature makes app always save user wallets. Do not use this method") - fun shouldSaveUserWallets(): Flow - - @Deprecated("Hot wallet feature makes app always save user wallets. Do not use this method") - suspend fun saveShouldSaveUserWallets(item: Boolean) - suspend fun useBiometricAuthentication(): Boolean suspend fun setUseBiometricAuthentication(value: Boolean) diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/DeleteWalletUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/DeleteWalletUseCase.kt index 22123c07a7..4037df2361 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/DeleteWalletUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/DeleteWalletUseCase.kt @@ -1,24 +1,19 @@ package com.tangem.domain.wallets.usecase import arrow.core.Either -import arrow.core.raise.either -import com.tangem.common.doOnFailure import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.common.wallets.error.DeleteWalletError import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.domain.wallets.legacy.UserWalletsListManager /** * Use case for deleting user wallet * - * @property userWalletsListManager user wallets list manager + * @property userWalletsListRepository repository for getting list of user wallets * [REDACTED_AUTHOR] */ class DeleteWalletUseCase( - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, - private val useNewRepository: Boolean, ) { /** @@ -29,19 +24,8 @@ class DeleteWalletUseCase( * @return [Either] with [com.tangem.domain.common.wallets.error.DeleteWalletError] or [Boolean] which indicates that there are still saved wallets. * */ suspend operator fun invoke(userWalletId: UserWalletId): Either { - if (useNewRepository) { - return userWalletsListRepository.delete(userWalletIds = listOf(userWalletId)).map { - userWalletsListRepository.selectedUserWallet.value != null - } - } - - return either { - userWalletsListManager.delete(userWalletIds = listOf(userWalletId)) - .doOnFailure { - raise(DeleteWalletError.UnableToDelete) - } - - userWalletsListManager.hasUserWallets + return userWalletsListRepository.delete(userWalletIds = listOf(userWalletId)).map { + userWalletsListRepository.selectedUserWallet.value != null } } } \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GenerateWalletNameUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GenerateWalletNameUseCase.kt index 55a32a38ba..3e4f011fee 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GenerateWalletNameUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GenerateWalletNameUseCase.kt @@ -1,19 +1,16 @@ package com.tangem.domain.wallets.usecase -import com.tangem.domain.models.scan.CardDTO -import com.tangem.domain.demo.models.DemoConfig import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.common.wallets.requireUserWalletsSync +import com.tangem.domain.demo.models.DemoConfig +import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.scan.ProductType -import com.tangem.domain.wallets.legacy.UserWalletsListManager /** * Use case for user wallet name generation */ class GenerateWalletNameUseCase( - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, - private val useNewRepository: Boolean, ) { private val CardDTO.isBackupNotAllowed: Boolean @@ -38,11 +35,7 @@ class GenerateWalletNameUseCase( } private fun getNamesSet(): Set { - return if (useNewRepository) { - userWalletsListRepository.requireUserWalletsSync().map { it.name }.toSet() - } else { - userWalletsListManager.userWalletsSync.map { it.name }.toSet() - } + return userWalletsListRepository.requireUserWalletsSync().map { it.name }.toSet() } private fun suggestedWalletName(defaultName: String, existingNames: Set): String { diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetSavedWalletsCountUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetSavedWalletsCountUseCase.kt index 2784698845..0be243b67a 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetSavedWalletsCountUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetSavedWalletsCountUseCase.kt @@ -2,34 +2,14 @@ package com.tangem.domain.wallets.usecase import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.models.wallet.UserWallet -import com.tangem.domain.wallets.legacy.UserWalletsListManager -import com.tangem.domain.wallets.legacy.asLockable -import com.tangem.domain.wallets.legacy.isLockedSync import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map class GetSavedWalletsCountUseCase( - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, - private val useNewRepository: Boolean, ) { operator fun invoke(): Flow> { - if (useNewRepository) { - return userWalletsListRepository.userWallets.map { requireNotNull(it) } - } - - return userWalletsListManager.savedWalletsCount - .filter { count -> - if (count == 0) return@filter true - userWalletsListManager.asLockable() ?: return@filter false - return@filter userWalletsListManager.isLockedSync.not() - } - .map { - userWalletsListManager.userWalletsSync - } - .distinctUntilChanged() + return userWalletsListRepository.userWallets.map { requireNotNull(it) } } } \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetSelectedWalletSyncUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetSelectedWalletSyncUseCase.kt index 549813b0bf..071bc36c87 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetSelectedWalletSyncUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetSelectedWalletSyncUseCase.kt @@ -2,39 +2,26 @@ package com.tangem.domain.wallets.usecase import arrow.core.Either import arrow.core.raise.either -import arrow.core.raise.ensureNotNull import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.models.wallet.UserWallet -import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.models.GetUserWalletError /** * Use case for getting selected wallet. * Important! If all wallets is locked, use case returns a error. * - * @property userWalletsListManager user wallets list manager + * @property userWalletsListRepository repository for getting list of user wallets * [REDACTED_AUTHOR] */ class GetSelectedWalletSyncUseCase( - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, - private val useNewRepository: Boolean = false, ) { @Deprecated("You should provide the selected wallet via routing parameters due to the scalability of the features") operator fun invoke(): Either { - if (useNewRepository) { - return either { - userWalletsListRepository.selectedUserWallet.value ?: raise(GetUserWalletError.UserWalletNotFound) - } - } - return either { - ensureNotNull( - value = userWalletsListManager.selectedUserWalletSync, - raise = { GetUserWalletError.UserWalletNotFound }, - ) + userWalletsListRepository.selectedUserWallet.value ?: raise(GetUserWalletError.UserWalletNotFound) } } } \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetSelectedWalletUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetSelectedWalletUseCase.kt index 2f62d3a115..b5506dacff 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetSelectedWalletUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetSelectedWalletUseCase.kt @@ -4,7 +4,6 @@ import arrow.core.Either import arrow.core.raise.either import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.models.wallet.UserWallet -import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.models.GetUserWalletError import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.filterNotNull @@ -12,36 +11,26 @@ import kotlinx.coroutines.flow.filterNotNull /** * Use case for getting flow of selected wallet. * - * @property userWalletsListManager user wallets list manager + * @property userWalletsListRepository repository for getting list of user wallets * [REDACTED_AUTHOR] */ @Deprecated("You should provide the selected wallet via routing parameters due to the scalability of the features") class GetSelectedWalletUseCase( - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, - private val useNewRepository: Boolean = false, ) { @Deprecated("You should provide the selected wallet via routing parameters due to the scalability of the features") operator fun invoke(): Either> { return either { - if (useNewRepository) { - userWalletsListRepository.selectedUserWallet.filterNotNull() - } else { - userWalletsListManager.selectedUserWallet - } + userWalletsListRepository.selectedUserWallet.filterNotNull() } } @Deprecated("You should provide the selected wallet via routing parameters due to the scalability of the features") fun sync(): Either { return either { - if (useNewRepository) { - userWalletsListRepository.selectedUserWallet.value - } else { - userWalletsListManager.selectedUserWalletSync - } + userWalletsListRepository.selectedUserWallet.value } } } \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetUserWalletUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetUserWalletUseCase.kt index 8ca4292c70..577f7d8b93 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetUserWalletUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetUserWalletUseCase.kt @@ -10,24 +10,17 @@ import com.tangem.domain.common.wallets.requireUserWalletsSync import com.tangem.domain.core.utils.EitherFlow import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.models.GetUserWalletError import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.transformLatest class GetUserWalletUseCase( - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, - private val useNewListRepository: Boolean, ) { operator fun invoke(userWalletId: UserWalletId): Either = either { - val userWallets = if (useNewListRepository) { - userWalletsListRepository.requireUserWalletsSync() - } else { - userWalletsListManager.userWalletsSync - } + val userWallets = userWalletsListRepository.requireUserWalletsSync() ensureNotNull(userWallets.firstOrNull { it.walletId == userWalletId }) { raise(GetUserWalletError.UserWalletNotFound) @@ -36,11 +29,7 @@ class GetUserWalletUseCase( @OptIn(ExperimentalCoroutinesApi::class) fun invokeFlow(userWalletId: UserWalletId): EitherFlow { - val flow = if (useNewListRepository) { - userWalletsListRepository.userWallets.map { requireNotNull(it) } - } else { - userWalletsListManager.userWallets - } + val flow = userWalletsListRepository.userWallets.map { requireNotNull(it) } return flow.transformLatest { userWallets -> userWallets.firstOrNull { it.walletId == userWalletId } diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletNamesUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletNamesUseCase.kt index 549644162e..d9a1ee4499 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletNamesUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletNamesUseCase.kt @@ -2,22 +2,15 @@ package com.tangem.domain.wallets.usecase import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.common.wallets.requireUserWalletsSync -import com.tangem.domain.wallets.legacy.UserWalletsListManager /** * Use case for getting list of user wallets names. * - * @property userWalletsListManager user wallets list manager + * @property userWalletsListRepository repository for getting list of user wallets */ class GetWalletNamesUseCase( - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, - private val useNewRepository: Boolean, ) { - operator fun invoke(): List = if (useNewRepository) { - userWalletsListRepository.requireUserWalletsSync().map { it.name } - } else { - userWalletsListManager.userWalletsSync.map { it.name } - } + operator fun invoke(): List = userWalletsListRepository.requireUserWalletsSync().map { it.name } } \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletsForAutomaticallyPushEnablingUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletsForAutomaticallyPushEnablingUseCase.kt index 75c623d401..fc73252e8f 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletsForAutomaticallyPushEnablingUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletsForAutomaticallyPushEnablingUseCase.kt @@ -2,7 +2,6 @@ package com.tangem.domain.wallets.usecase import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.withContext @@ -11,24 +10,17 @@ import kotlinx.coroutines.withContext * * This use case filters out wallets that have already had push notifications automatically enabled * from the complete list of user wallets, returning only those wallets that still need to have * push notifications automatically enabled. - * @property userWalletsListManager Manager for user wallets list operations * @property userWalletsListRepository Repository for user wallets list operations * @property dispatchers Coroutine dispatcher provider for background operations */ class GetWalletsForAutomaticallyPushEnablingUseCase( - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, - private val shouldUseNewListRepository: Boolean, private val dispatchers: CoroutineDispatcherProvider, ) { suspend operator fun invoke(walletsListWherePushWasEnabled: List): List = withContext(dispatchers.default) { - val allLocalWallets = if (shouldUseNewListRepository) { - userWalletsListRepository.userWalletsSync().map { it.walletId } - } else { - userWalletsListManager.userWalletsSync.map { it.walletId } - } + val allLocalWallets = userWalletsListRepository.userWalletsSync().map { it.walletId } allLocalWallets - walletsListWherePushWasEnabled.toSet() } } \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletsUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletsUseCase.kt index d92a9a5555..de1b19acf0 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletsUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/GetWalletsUseCase.kt @@ -2,34 +2,23 @@ package com.tangem.domain.wallets.usecase import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.models.wallet.UserWallet -import com.tangem.domain.wallets.legacy.UserWalletsListManager import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map /** * Use case for getting list of user wallets * - * @property userWalletsListManager user wallets list manager + * @property userWalletsListRepository repository for getting list of user wallets * [REDACTED_AUTHOR] */ class GetWalletsUseCase( - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, - private val useNewListRepository: Boolean, ) { @Throws(IllegalArgumentException::class) - operator fun invoke(): Flow> = if (useNewListRepository) { - userWalletsListRepository.userWallets.map { requireNotNull(it) } - } else { - userWalletsListManager.userWallets - } + operator fun invoke(): Flow> = userWalletsListRepository.userWallets.map { requireNotNull(it) } @Throws(IllegalArgumentException::class) - fun invokeSync(): List = if (useNewListRepository) { - userWalletsListRepository.userWallets.value!! - } else { - userWalletsListManager.userWalletsSync - } + fun invokeSync(): List = userWalletsListRepository.userWallets.value!! } \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/IsNeedToBackupUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/IsNeedToBackupUseCase.kt index 25722fa134..e15cfc13df 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/IsNeedToBackupUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/IsNeedToBackupUseCase.kt @@ -4,27 +4,20 @@ import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.domain.wallets.legacy.UserWalletsListManager import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map /** * Use case that checks if wallet need backup cards * - * @property userWalletsListManager user wallets list manager + * @property userWalletsListRepository repository for getting user wallets */ class IsNeedToBackupUseCase( - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, - private val useNewRepository: Boolean, ) { operator fun invoke(id: UserWalletId): Flow { - val userWalletsFlow = if (useNewRepository) { - userWalletsListRepository.userWallets - } else { - userWalletsListManager.userWallets - } + val userWalletsFlow = userWalletsListRepository.userWallets return userWalletsFlow .map { wallets -> diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/IsWalletAlreadySavedUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/IsWalletAlreadySavedUseCase.kt index 86cf920cd5..3f6b9ede87 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/IsWalletAlreadySavedUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/IsWalletAlreadySavedUseCase.kt @@ -5,28 +5,16 @@ import arrow.core.raise.either import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.common.wallets.error.SaveWalletError import com.tangem.domain.models.wallet.UserWallet -import com.tangem.domain.wallets.legacy.UserWalletsListManager class IsWalletAlreadySavedUseCase( - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, - private val useNewRepository: Boolean, ) { suspend operator fun invoke( userWallet: UserWallet, canOverride: Boolean = false, - ): Either { - return if (useNewRepository) { - either { - userWalletsListRepository.userWalletsSync() - .any { it.walletId == userWallet.walletId } - } - } else { - either { - userWalletsListManager.userWalletsSync - .any { it.walletId == userWallet.walletId } - } - } + ): Either = either { + userWalletsListRepository.userWalletsSync() + .any { it.walletId == userWallet.walletId } } } \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/SaveWalletUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/SaveWalletUseCase.kt index 354d0b6bc8..77f03f306a 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/SaveWalletUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/SaveWalletUseCase.kt @@ -1,78 +1,52 @@ package com.tangem.domain.wallets.usecase import arrow.core.Either -import arrow.core.left import arrow.core.raise.either import arrow.core.right -import com.tangem.common.doOnFailure -import com.tangem.common.doOnSuccess import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.common.wallets.error.SaveWalletError import com.tangem.domain.models.wallet.UserWallet -import com.tangem.domain.wallets.legacy.UserWalletsListError -import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.repository.WalletsRepository /** * Use case for saving user wallet * - * @property userWalletsListManager user wallets list manager - * [REDACTED_AUTHOR] */ class SaveWalletUseCase( - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, private val walletsRepository: WalletsRepository, - private val useNewRepository: Boolean, ) { suspend operator fun invoke(userWallet: UserWallet, canOverride: Boolean = false): Either { - return if (useNewRepository) { - either { - val newUserWallet = - userWalletsListRepository.userWalletsSync().none { it.walletId == userWallet.walletId } - val userWallet = userWalletsListRepository.saveWithoutLock(userWallet, canOverride).bind() + return either { + val newUserWallet = + userWalletsListRepository.userWalletsSync().none { it.walletId == userWallet.walletId } + val userWallet = userWalletsListRepository.saveWithoutLock(userWallet, canOverride).bind() - if (newUserWallet) { - when (userWallet) { - is UserWallet.Cold -> { - if (walletsRepository.useBiometricAuthentication()) { - userWalletsListRepository.setLock( - userWallet.walletId, - UserWalletsListRepository.LockMethod.Biometric, - ) - } else { - Unit.right() - } - } - is UserWallet.Hot -> { + if (newUserWallet) { + when (userWallet) { + is UserWallet.Cold -> { + if (walletsRepository.useBiometricAuthentication()) { userWalletsListRepository.setLock( userWallet.walletId, - UserWalletsListRepository.LockMethod.NoLock, + UserWalletsListRepository.LockMethod.Biometric, ) + } else { + Unit.right() } - }.mapLeft { - SaveWalletError.DataError(null) - }.map { - userWalletsListRepository.select(userWallet.walletId) - }.bind() - } - } - } else { - either { - userWalletsListManager.save(userWallet, canOverride) - .doOnSuccess { return Unit.right() } - .doOnFailure { - return when (it) { - is UserWalletsListError.WalletAlreadySaved -> SaveWalletError.WalletAlreadySaved( - it.messageResId, - ) - else -> SaveWalletError.DataError(it.messageResId) - }.left() } - - return Unit.right() + is UserWallet.Hot -> { + userWalletsListRepository.setLock( + userWallet.walletId, + UserWalletsListRepository.LockMethod.NoLock, + ) + } + }.mapLeft { + SaveWalletError.DataError(null) + }.map { + userWalletsListRepository.select(userWallet.walletId) + }.bind() } } } diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/SelectWalletUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/SelectWalletUseCase.kt index 8d416c90e3..239ada3255 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/SelectWalletUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/SelectWalletUseCase.kt @@ -1,47 +1,29 @@ package com.tangem.domain.wallets.usecase import arrow.core.Either -import arrow.core.raise.either -import arrow.core.right -import com.tangem.common.CompletionResult import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.common.wallets.error.SelectWalletError import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.redux.ReduxStateHolder -import com.tangem.domain.wallets.legacy.UserWalletsListManager /** * Use case for selecting wallet * - * @property userWalletsListManager user wallets list manager + * @property userWalletsListRepository repository for getting list of user wallets * @property reduxStateHolder redux state holder * [REDACTED_AUTHOR] */ class SelectWalletUseCase( - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, - private val useNewRepository: Boolean, private val reduxStateHolder: ReduxStateHolder, ) { suspend operator fun invoke(userWalletId: UserWalletId): Either { - if (useNewRepository) { - return userWalletsListRepository.select(userWalletId).map { - reduxStateHolder.onUserWalletSelected(it) - it - } - } - - return either { - return when (val result = userWalletsListManager.select(userWalletId)) { - is CompletionResult.Failure -> raise(SelectWalletError.UnableToSelectUserWallet) - is CompletionResult.Success -> { - reduxStateHolder.onUserWalletSelected(result.data) - result.data.right() - } - } + return userWalletsListRepository.select(userWalletId).map { + reduxStateHolder.onUserWalletSelected(it) + it } } } \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/ShouldSaveUserWalletsSyncUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/ShouldSaveUserWalletsSyncUseCase.kt deleted file mode 100644 index 85e7b0265f..0000000000 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/ShouldSaveUserWalletsSyncUseCase.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.tangem.domain.wallets.usecase - -import com.tangem.domain.wallets.repository.WalletsRepository - -@Deprecated("Hot wallet feature makes app always save user wallets. Do not use this method") -class ShouldSaveUserWalletsSyncUseCase(private val walletsRepository: WalletsRepository) { - - suspend operator fun invoke(): Boolean = walletsRepository.shouldSaveUserWalletsSync() -} \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/ShouldSaveUserWalletsUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/ShouldSaveUserWalletsUseCase.kt deleted file mode 100644 index fc62813050..0000000000 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/ShouldSaveUserWalletsUseCase.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.tangem.domain.wallets.usecase - -import com.tangem.domain.wallets.repository.WalletsRepository -import kotlinx.coroutines.flow.Flow - -class ShouldSaveUserWalletsUseCase(private val walletsRepository: WalletsRepository) { - - operator fun invoke(): Flow = walletsRepository.shouldSaveUserWallets() -} \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/UnlockWalletsUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/UnlockWalletsUseCase.kt deleted file mode 100644 index 3bbed19358..0000000000 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/UnlockWalletsUseCase.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.tangem.domain.wallets.usecase - -import arrow.core.Either -import arrow.core.raise.either -import arrow.core.raise.ensureNotNull -import com.tangem.common.doOnFailure -import com.tangem.domain.wallets.legacy.UserWalletsListError -import com.tangem.domain.wallets.legacy.UserWalletsListManager -import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType -import com.tangem.domain.wallets.legacy.asLockable -import com.tangem.domain.wallets.models.UnlockWalletsError - -/** - * Unlock wallets use case - * - * @property userWalletsListManager user wallets list manager - * -[REDACTED_AUTHOR] - */ -@Deprecated("Use NonBiometricUnlockWalletUseCase after migrating to new wallets repository") -class UnlockWalletsUseCase(private val userWalletsListManager: UserWalletsListManager) { - - suspend operator fun invoke(type: UnlockType = UnlockType.ANY): Either = either { - val userWalletsListManager = ensureNotNull( - value = userWalletsListManager.asLockable(), - raise = { - UnlockWalletsError.DataError( - cause = IllegalStateException("The lockable user wallets list manager could not be found"), - ) - }, - ) - - userWalletsListManager.unlock(type) - .doOnFailure { error -> - val e = when (error) { - is UserWalletsListError.NoUserWalletSelected -> UnlockWalletsError.NoUserWalletSelected - is UserWalletsListError.NotAllUserWalletsUnlocked -> - UnlockWalletsError.NotAllUserWalletsUnlocked - else -> UnlockWalletsError.UnableToUnlockWallets - } - - raise(e) - } - } -} \ No newline at end of file diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/UpdateWalletUseCase.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/UpdateWalletUseCase.kt index b8204b14fa..c06851d5d4 100644 --- a/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/UpdateWalletUseCase.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/usecase/UpdateWalletUseCase.kt @@ -1,55 +1,41 @@ package com.tangem.domain.wallets.usecase import arrow.core.Either -import arrow.core.raise.either -import com.tangem.common.CompletionResult import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.common.wallets.error.SaveWalletError import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.models.UpdateWalletError import com.tangem.domain.wallets.models.UpdateWalletError.DataError /** * Use case for updating user wallet * - * @property userWalletsListManager user wallets list manager + * @property userWalletsListRepository repository for getting list of user wallets * [REDACTED_AUTHOR] */ class UpdateWalletUseCase( - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, - private val useNewRepository: Boolean, ) { suspend operator fun invoke( userWalletId: UserWalletId, update: suspend (UserWallet) -> UserWallet, ): Either { - if (useNewRepository) { - val userWallet = userWalletsListRepository.userWallets.value?.find { it.walletId == userWalletId } - ?: return Either.Left( - DataError(IllegalStateException("User wallet with id $userWalletId not found")), - ) - val updatedWallet = update(userWallet) - return userWalletsListRepository.saveWithoutLock(updatedWallet, canOverride = true) - .mapLeft { - when (it) { - is SaveWalletError.DataError -> DataError( - IllegalStateException("Failed to update wallet: ${it.messageId}"), - ) - is SaveWalletError.WalletAlreadySaved -> UpdateWalletError.NameAlreadyExists - } + val userWallet = userWalletsListRepository.userWallets.value?.find { it.walletId == userWalletId } + ?: return Either.Left( + DataError(IllegalStateException("User wallet with id $userWalletId not found")), + ) + val updatedWallet = update(userWallet) + return userWalletsListRepository.saveWithoutLock(updatedWallet, canOverride = true) + .mapLeft { + when (it) { + is SaveWalletError.DataError -> DataError( + IllegalStateException("Failed to update wallet: ${it.messageId}"), + ) + is SaveWalletError.WalletAlreadySaved -> UpdateWalletError.NameAlreadyExists } - } - - return either { - when (val result = userWalletsListManager.update(userWalletId, update)) { - is CompletionResult.Failure -> raise(DataError(result.error)) - is CompletionResult.Success -> result.data } - } } } \ No newline at end of file diff --git a/domain/wallets/src/test/java/com/tangem/domain/wallets/usecase/GetSavedWalletsCountUseCaseTest.kt b/domain/wallets/src/test/java/com/tangem/domain/wallets/usecase/GetSavedWalletsCountUseCaseTest.kt deleted file mode 100644 index 4df283dd5e..0000000000 --- a/domain/wallets/src/test/java/com/tangem/domain/wallets/usecase/GetSavedWalletsCountUseCaseTest.kt +++ /dev/null @@ -1,141 +0,0 @@ -package com.tangem.domain.wallets.usecase - -import com.google.common.truth.Truth.assertThat -import com.tangem.domain.wallets.legacy.UserWalletsListManager -import com.tangem.domain.wallets.legacy.asLockable -import com.tangem.domain.wallets.legacy.isLockedSync -import com.tangem.domain.models.wallet.UserWallet -import io.mockk.every -import io.mockk.mockk -import io.mockk.mockkStatic -import kotlinx.coroutines.flow.firstOrNull -import kotlinx.coroutines.flow.flowOf -import kotlinx.coroutines.test.runTest -import org.junit.Before -import org.junit.Test - -class GetSavedWalletsCountUseCaseTest { - - private lateinit var useCase: GetSavedWalletsCountUseCase - private lateinit var userWalletsListManager: UserWalletsListManager - - @Before - fun setup() { - userWalletsListManager = mockk() - useCase = GetSavedWalletsCountUseCase( - userWalletsListManager, - userWalletsListRepository = mockk(), - useNewRepository = false, - ) - mockkStatic("com.tangem.domain.wallets.legacy.UserWalletsListManagerExtensionsKt") - } - - @Test - fun `GIVEN manager is not lockable WHEN invoke THEN return empty list`() = runTest { - // GIVEN - every { userWalletsListManager.isLockable } returns false - every { userWalletsListManager.savedWalletsCount } returns flowOf(0) - every { userWalletsListManager.userWallets } returns flowOf(emptyList()) - every { userWalletsListManager.userWalletsSync } returns emptyList() - every { userWalletsListManager.isLockedSync } returns false - every { userWalletsListManager.asLockable() } returns null - - // WHEN - val result = useCase().firstOrNull() - - // THEN - assertThat(result).isEmpty() - } - - @Test - fun `GIVEN manager is locked WHEN invoke THEN return empty list`() = runTest { - // GIVEN - val mockLockable = mockk() - every { userWalletsListManager.isLockable } returns true - every { userWalletsListManager.savedWalletsCount } returns flowOf(0) - every { userWalletsListManager.userWallets } returns flowOf(emptyList()) - every { userWalletsListManager.userWalletsSync } returns emptyList() - every { userWalletsListManager.isLockedSync } returns true - every { userWalletsListManager.asLockable() } returns mockLockable - - // WHEN - val result = useCase().firstOrNull() - - // THEN - assertThat(result).isEmpty() - } - - @Test - fun `GIVEN manager is not locked and has wallets WHEN invoke THEN return wallets list`() = runTest { - // GIVEN - val mockLockable = mockk() - val wallets = listOf(mockk(), mockk()) - every { userWalletsListManager.isLockable } returns true - every { userWalletsListManager.savedWalletsCount } returns flowOf(wallets.size) - every { userWalletsListManager.userWallets } returns flowOf(wallets) - every { userWalletsListManager.userWalletsSync } returns wallets - every { userWalletsListManager.isLockedSync } returns false - every { userWalletsListManager.asLockable() } returns mockLockable - - // WHEN - val result = useCase().firstOrNull() - - // THEN - assertThat(result).isEqualTo(wallets) - } - - @Test - fun `GIVEN manager is not lockable and savedWalletsCount is zero WHEN invoke THEN return empty list`() = runTest { - // GIVEN - every { userWalletsListManager.isLockable } returns false - every { userWalletsListManager.savedWalletsCount } returns flowOf(0) - every { userWalletsListManager.userWallets } returns flowOf(emptyList()) - every { userWalletsListManager.userWalletsSync } returns emptyList() - every { userWalletsListManager.isLockedSync } returns false - every { userWalletsListManager.asLockable() } returns null - - // WHEN - val result = useCase().firstOrNull() - - // THEN - assertThat(result).isEmpty() - } - - @Test - fun `GIVEN manager is lockable and locked and savedWalletsCount is zero WHEN invoke THEN return empty list`() = - runTest { - // GIVEN - val mockLockable = mockk() - every { userWalletsListManager.isLockable } returns true - every { userWalletsListManager.savedWalletsCount } returns flowOf(0) - every { userWalletsListManager.userWallets } returns flowOf(emptyList()) - every { userWalletsListManager.userWalletsSync } returns emptyList() - every { userWalletsListManager.isLockedSync } returns true - every { userWalletsListManager.asLockable() } returns mockLockable - - // WHEN - val result = useCase().firstOrNull() - - // THEN - assertThat(result).isEmpty() - } - - @Test - fun `GIVEN manager is lockable and unlocked and savedWalletsCount is zero WHEN invoke THEN return empty list`() = - runTest { - // GIVEN - val mockLockable = mockk() - every { userWalletsListManager.isLockable } returns true - every { userWalletsListManager.savedWalletsCount } returns flowOf(0) - every { userWalletsListManager.userWallets } returns flowOf(emptyList()) - every { userWalletsListManager.userWalletsSync } returns emptyList() - every { userWalletsListManager.isLockedSync } returns false - every { userWalletsListManager.asLockable() } returns mockLockable - - // WHEN - val result = useCase().firstOrNull() - - // THEN - assertThat(result).isEmpty() - } -} \ No newline at end of file diff --git a/features/biometry/impl/src/main/kotlin/com/tangem/features/biometry/impl/model/AskBiometryModel.kt b/features/biometry/impl/src/main/kotlin/com/tangem/features/biometry/impl/model/AskBiometryModel.kt index 1f8093ed68..78cd72167e 100644 --- a/features/biometry/impl/src/main/kotlin/com/tangem/features/biometry/impl/model/AskBiometryModel.kt +++ b/features/biometry/impl/src/main/kotlin/com/tangem/features/biometry/impl/model/AskBiometryModel.kt @@ -16,12 +16,10 @@ import com.tangem.domain.card.repository.CardSdkConfigRepository import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.settings.SetAskBiometryShownUseCase -import com.tangem.domain.settings.repositories.SettingsRepository import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.domain.wallets.usecase.GetSelectedWalletUseCase import com.tangem.features.biometry.AskBiometryComponent import com.tangem.features.biometry.impl.ui.state.AskBiometryUM -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.sdk.api.TangemSdkManager import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.delay @@ -40,7 +38,6 @@ internal class AskBiometryModel @Inject constructor( override val dispatchers: CoroutineDispatcherProvider, paramsContainer: ParamsContainer, private val setAskBiometryShownUseCase: SetAskBiometryShownUseCase, - private val settingsRepository: SettingsRepository, private val tangemSdkManager: TangemSdkManager, private val getSelectedWalletUseCase: GetSelectedWalletUseCase, private val walletsRepository: WalletsRepository, @@ -48,7 +45,6 @@ internal class AskBiometryModel @Inject constructor( private val settingsManager: SettingsManager, private val uiMessageSender: UiMessageSender, private val userWalletsListRepository: UserWalletsListRepository, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, ) : Model() { private val params = paramsContainer.require() @@ -110,24 +106,13 @@ internal class AskBiometryModel @Inject constructor( } private suspend fun handleSuccessAllowing(userWallet: UserWallet) { - walletsRepository.saveShouldSaveUserWallets(item = true) - - if (hotWalletFeatureToggles.isHotWalletEnabled) { - walletsRepository.setUseBiometricAuthentication(value = true) - walletsRepository.setRequireAccessCode(value = false) - setBiometryLockForAllWallets() - if (userWallet is UserWallet.Cold) { - cardSdkConfigRepository.setAccessCodeRequestPolicy( - isBiometricsRequestPolicy = userWallet.hasAccessCode, - ) - } - } else { - settingsRepository.setShouldSaveAccessCodes(value = true) - if (userWallet is UserWallet.Cold) { - cardSdkConfigRepository.setAccessCodeRequestPolicy( - isBiometricsRequestPolicy = userWallet.hasAccessCode, - ) - } + walletsRepository.setUseBiometricAuthentication(value = true) + walletsRepository.setRequireAccessCode(value = false) + setBiometryLockForAllWallets() + if (userWallet is UserWallet.Cold) { + cardSdkConfigRepository.setAccessCodeRequestPolicy( + isBiometricsRequestPolicy = userWallet.hasAccessCode, + ) } if (_uiState.value.isBottomSheetVariant) { diff --git a/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModel.kt b/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModel.kt index 0760ef5917..2183fc05a0 100644 --- a/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModel.kt +++ b/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModel.kt @@ -32,7 +32,6 @@ import com.tangem.domain.wallets.builder.ColdUserWalletBuilder import com.tangem.domain.wallets.usecase.GenerateBuyTangemCardLinkUseCase import com.tangem.domain.wallets.usecase.SaveWalletUseCase import com.tangem.features.createwalletstart.entity.CreateWalletStartUM -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.delay @@ -64,7 +63,6 @@ internal class CreateWalletStartModel @Inject constructor( private val urlOpener: UrlOpener, private val trackingContextProxy: TrackingContextProxy, private val analyticsEventHandler: AnalyticsEventHandler, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, ) : Model() { private val params = paramsContainer.require() @@ -99,7 +97,6 @@ internal class CreateWalletStartModel @Inject constructor( onBackClick = { router.pop() }, onScanClick = ::onScanClick, isScanInProgress = false, - isHotWalletOptionVisible = hotWalletFeatureToggles.isHotWalletVisible, ) CreateWalletStartComponent.Mode.HotWallet -> CreateWalletStartUM( title = resourceReference(R.string.hw_mobile_wallet), diff --git a/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/entity/CreateWalletStartUM.kt b/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/entity/CreateWalletStartUM.kt index babf146ab3..bce2d230b2 100644 --- a/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/entity/CreateWalletStartUM.kt +++ b/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/entity/CreateWalletStartUM.kt @@ -17,7 +17,6 @@ internal data class CreateWalletStartUM( val otherMethodClick: () -> Unit, val onScanClick: () -> Unit, val onBackClick: () -> Unit, - val isHotWalletOptionVisible: Boolean = true, ) { data class FeatureItem( val iconResId: Int, diff --git a/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/ui/CreateWalletStartContent.kt b/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/ui/CreateWalletStartContent.kt index d88ad17317..3c4245ca54 100644 --- a/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/ui/CreateWalletStartContent.kt +++ b/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/ui/CreateWalletStartContent.kt @@ -6,7 +6,6 @@ import androidx.annotation.DrawableRes import androidx.compose.foundation.* import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.* -import androidx.compose.foundation.layout.Arrangement import androidx.compose.material3.* import androidx.compose.runtime.Composable import androidx.compose.runtime.remember @@ -165,74 +164,72 @@ internal fun CreateWalletStartContent(state: CreateWalletStartUM, modifier: Modi text = state.primaryButtonText.resolveReference(), onClick = state.onPrimaryButtonClick, ) - if (state.isHotWalletOptionVisible) { - Row( + + Row( + modifier = Modifier + .padding( + start = 16.dp, + top = 24.dp, + end = 16.dp, + ), + horizontalArrangement = Arrangement.spacedBy(16.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + DashedGradientLine( modifier = Modifier + .weight(1f) + .height(16.dp), + ) + Text( + text = stringResourceSafe(R.string.common_or), + style = TangemTheme.typography.caption1, + color = TangemTheme.colors.text.secondary, + textAlign = TextAlign.Center, + ) + DashedGradientLine( + modifier = Modifier + .weight(1f) + .height(16.dp) + .scale(scaleX = -1f, scaleY = 1f), + ) + } + + if (state.otherMethodDescription != null) { + Text( + modifier = Modifier + .fillMaxWidth() .padding( start = 16.dp, - top = 24.dp, + top = 16.dp, end = 16.dp, ), - horizontalArrangement = Arrangement.spacedBy(16.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - DashedGradientLine( - modifier = Modifier - .weight(1f) - .height(16.dp), - ) - Text( - text = stringResourceSafe(R.string.common_or), - style = TangemTheme.typography.caption1, - color = TangemTheme.colors.text.secondary, - textAlign = TextAlign.Center, - ) - DashedGradientLine( - modifier = Modifier - .weight(1f) - .height(16.dp) - .scale(scaleX = -1f, scaleY = 1f), - ) - } + text = state.otherMethodDescription.resolveReference(), + style = TangemTheme.typography.subtitle2, + color = TangemTheme.colors.text.tertiary, + textAlign = TextAlign.Center, + ) } - if (state.isHotWalletOptionVisible) { - if (state.otherMethodDescription != null) { - Text( - modifier = Modifier - .fillMaxWidth() - .padding( - start = 16.dp, - top = 16.dp, - end = 16.dp, - ), - text = state.otherMethodDescription.resolveReference(), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.tertiary, - textAlign = TextAlign.Center, - ) - } - Row( - modifier = Modifier - .wrapContentWidth() - .clickable { state.otherMethodClick() } - .padding( - horizontal = 16.dp, - vertical = 12.dp, - ), - horizontalArrangement = Arrangement.Center, - ) { - Text( - text = state.otherMethodTitle.resolveReference(), - style = TangemTheme.typography.subtitle1, - color = TangemTheme.colors.text.primary1, - textAlign = TextAlign.Center, - ) - Icon( - painter = painterResource(id = R.drawable.ic_chevron_right_18x24), - tint = TangemTheme.colors.icon.primary1, - contentDescription = null, - ) - } + Row( + modifier = Modifier + .wrapContentWidth() + .clickable { state.otherMethodClick() } + .padding( + horizontal = 16.dp, + vertical = 12.dp, + ), + horizontalArrangement = Arrangement.Center, + ) { + Text( + text = state.otherMethodTitle.resolveReference(), + style = TangemTheme.typography.subtitle1, + color = TangemTheme.colors.text.primary1, + textAlign = TextAlign.Center, + ) + Icon( + painter = painterResource(id = R.drawable.ic_chevron_right_18x24), + tint = TangemTheme.colors.icon.primary1, + contentDescription = null, + ) } }, minImageHeight = 160.dp, diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewDetailsComponent.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewDetailsComponent.kt index 3373105976..018768f225 100644 --- a/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewDetailsComponent.kt +++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewDetailsComponent.kt @@ -21,9 +21,7 @@ internal class PreviewDetailsComponent : DetailsComponent { ItemsBuilder( router = DummyRouter(), hotWalletFeatureToggles = object : HotWalletFeatureToggles { - override val isHotWalletEnabled: Boolean = true override val isWalletCreationRestrictionEnabled: Boolean = true - override val isHotWalletVisible: Boolean = true }, ).buildAll( isWalletConnectAvailable = true, diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt index 4abde012d5..3b3784c0cc 100644 --- a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt +++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt @@ -3,7 +3,6 @@ package com.tangem.features.details.model import android.content.res.Resources import arrow.core.getOrElse import com.tangem.common.routing.AppRoute -import com.tangem.core.analytics.AppInstanceIdProvider import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.core.analytics.models.Basic @@ -34,7 +33,6 @@ import com.tangem.features.details.entity.DetailsUM import com.tangem.features.details.entity.SelectEmailFeedbackTypeBS import com.tangem.features.details.utils.ItemsBuilder import com.tangem.features.details.utils.SocialsBuilder -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.version.AppVersionProvider import kotlinx.collections.immutable.ImmutableList @@ -59,7 +57,6 @@ internal class DetailsModel @Inject constructor( private val checkIsWalletConnectAvailableUseCase: CheckIsWalletConnectAvailableUseCase, private val router: Router, private val urlOpener: UrlOpener, - private val appInstanceIdProvider: AppInstanceIdProvider, private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, private val appStateHolder: ReduxStateHolder, private val getWalletMetaInfoUseCase: GetWalletMetaInfoUseCase, @@ -67,7 +64,6 @@ internal class DetailsModel @Inject constructor( private val getWalletsUseCase: GetWalletsUseCase, override val dispatchers: CoroutineDispatcherProvider, private val generateBuyTangemCardLinkUseCase: GenerateBuyTangemCardLinkUseCase, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, private val analyticsEventHandler: AnalyticsEventHandler, private val tangemPayEligibilityManager: TangemPayEligibilityManager, ) : Model() { @@ -229,14 +225,10 @@ internal class DetailsModel @Inject constructor( private fun onBuyClick() { modelScope.launch { - if (hotWalletFeatureToggles.isHotWalletEnabled) { - analyticsEventHandler.send(Basic.ButtonBuy(source = AnalyticsParam.ScreensSources.Settings)) - generateBuyTangemCardLinkUseCase - .invoke(GenerateBuyTangemCardLinkUseCase.Source.Settings).let { urlOpener.openUrl(it) } - } else { - // This is incorrect implementation of buy link generation, but it is left here - urlOpener.openUrl(buildBuyLink()) - } + analyticsEventHandler.send(Basic.ButtonBuy(source = AnalyticsParam.ScreensSources.Settings)) + + val url = generateBuyTangemCardLinkUseCase(GenerateBuyTangemCardLinkUseCase.Source.Settings) + urlOpener.openUrl(url) } } @@ -270,12 +262,6 @@ internal class DetailsModel @Inject constructor( private fun getAppVersion(): String = "${appVersionProvider.versionName} (${appVersionProvider.versionCode})" - private suspend fun buildBuyLink(): String { - return appInstanceIdProvider.getAppInstanceId()?.let { - "$BUY_TANGEM_URL&app_instance_id=$it" - } ?: BUY_TANGEM_URL - } - private companion object { val SYSTEM_LANGUAGE = runCatching { Resources.getSystem().configuration.locales[0].language }.getOrElse { "" } val APP_LANGUAGE = Locale.getDefault().language @@ -283,7 +269,5 @@ internal class DetailsModel @Inject constructor( "&utm_medium=app" + "&utm_campaign=users-$SYSTEM_LANGUAGE" + "&utm_content=devicelang-$APP_LANGUAGE" - - val BUY_TANGEM_URL = "https://buy.tangem.com/?$UTM_MARKS" } } \ No newline at end of file diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/UserWalletListModel.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/UserWalletListModel.kt index d1a90f171f..78426bd036 100644 --- a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/UserWalletListModel.kt +++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/UserWalletListModel.kt @@ -13,7 +13,6 @@ import com.tangem.core.decompose.ui.UiMessageSender import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resourceReference import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase import com.tangem.domain.wallets.usecase.UnlockWalletUseCase import com.tangem.features.details.entity.UserWalletListUM import com.tangem.features.details.impl.R @@ -32,7 +31,6 @@ import javax.inject.Inject @ModelScoped internal class UserWalletListModel @Inject constructor( userWalletsFetcherFactory: UserWalletsFetcher.Factory, - shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase, private val router: Router, private val messageSender: UiMessageSender, override val dispatchers: CoroutineDispatcherProvider, @@ -47,7 +45,7 @@ internal class UserWalletListModel @Inject constructor( messageSender = messageSender, onlyMultiCurrency = false, isAuthMode = false, - isClickableIfLocked = hotWalletFeatureToggles.isHotWalletEnabled, + isClickableIfLocked = true, onWalletClick = ::onWalletClicked, ) @@ -68,67 +66,48 @@ internal class UserWalletListModel @Inject constructor( combine( flow = userWalletsFlow, - flow2 = shouldSaveUserWalletsUseCase(), - flow3 = isWalletSavingInProgress, - ) { userWallets, shouldSaveUserWallets, isWalletSavingInProgress -> - updateState(userWallets, shouldSaveUserWallets, isWalletSavingInProgress) + flow2 = isWalletSavingInProgress, + ) { userWallets, isWalletSavingInProgress -> + updateState(userWallets, isWalletSavingInProgress) }.collect() } } - private fun updateState( - userWallets: ImmutableList, - shouldSaveUserWallets: Boolean, - isWalletSavingInProgress: Boolean, - ) = state.update { value -> - value.copy( - userWallets = userWallets, - isWalletSavingInProgress = isWalletSavingInProgress, - addNewWalletText = when { - shouldSaveUserWallets || hotWalletFeatureToggles.isHotWalletEnabled -> { - resourceReference(R.string.user_wallet_list_add_button) - } - else -> resourceReference(R.string.scan_card_settings_button) - }, - ) - } + private fun updateState(userWallets: ImmutableList, isWalletSavingInProgress: Boolean) = + state.update { value -> + value.copy( + userWallets = userWallets, + isWalletSavingInProgress = isWalletSavingInProgress, + addNewWalletText = resourceReference(R.string.user_wallet_list_add_button), + ) + } private fun onAddNewWalletClick() { - if (hotWalletFeatureToggles.isHotWalletEnabled) { - analyticsEventHandler.send(SignIn.ButtonAddWallet(AnalyticsParam.ScreensSources.Settings)) + analyticsEventHandler.send(SignIn.ButtonAddWallet(AnalyticsParam.ScreensSources.Settings)) - if (hotWalletFeatureToggles.isWalletCreationRestrictionEnabled) { - withProgress(isWalletSavingInProgress) { - userWalletSaver.scanAndSaveUserWallet(modelScope) - } - } else { - router.push(AppRoute.CreateWalletSelection) - } - } else { + if (hotWalletFeatureToggles.isWalletCreationRestrictionEnabled) { withProgress(isWalletSavingInProgress) { userWalletSaver.scanAndSaveUserWallet(modelScope) } + } else { + router.push(AppRoute.CreateWalletSelection) } } private fun onWalletClicked(userWalletId: UserWalletId) { - if (hotWalletFeatureToggles.isHotWalletEnabled) { - modelScope.launch { - unlockWalletUseCase(userWalletId) - .onRight { router.push(AppRoute.WalletSettings(userWalletId)) } - .onLeft { error -> - Timber.e("Failed to unlock wallet $userWalletId: $error") - error.handle( - onUserCancelled = {}, - isFromUnlockAll = false, - onAlreadyUnlocked = { router.push(AppRoute.WalletSettings(userWalletId)) }, - analyticsEventHandler = analyticsEventHandler, - showMessage = messageSender::send, - ) - } - } - } else { - router.push(AppRoute.WalletSettings(userWalletId)) + modelScope.launch { + unlockWalletUseCase(userWalletId) + .onRight { router.push(AppRoute.WalletSettings(userWalletId)) } + .onLeft { error -> + Timber.e("Failed to unlock wallet $userWalletId: $error") + error.handle( + onUserCancelled = {}, + isFromUnlockAll = false, + onAlreadyUnlocked = { router.push(AppRoute.WalletSettings(userWalletId)) }, + analyticsEventHandler = analyticsEventHandler, + showMessage = messageSender::send, + ) + } } } } \ No newline at end of file diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/UserWalletSaver.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/UserWalletSaver.kt index 04d7e91736..7133bc0d73 100644 --- a/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/UserWalletSaver.kt +++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/UserWalletSaver.kt @@ -24,7 +24,6 @@ import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.redux.ReduxStateHolder import com.tangem.domain.wallets.builder.ColdUserWalletBuilder import com.tangem.domain.wallets.usecase.SaveWalletUseCase -import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsSyncUseCase import com.tangem.features.details.impl.R import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch @@ -38,7 +37,6 @@ internal class UserWalletSaver @Inject constructor( private val scanCardProcessor: ScanCardProcessor, private val saveWalletUseCase: SaveWalletUseCase, private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory, - private val shouldSaveUserWalletsSyncUseCase: ShouldSaveUserWalletsSyncUseCase, private val reduxStateHolder: ReduxStateHolder, private val messageSender: UiMessageSender, private val router: Router, @@ -79,11 +77,7 @@ internal class UserWalletSaver @Inject constructor( recover = { error -> when (error) { is SaveWalletError.WalletAlreadySaved -> { - if (shouldSaveUserWalletsSyncUseCase()) { - selectUserWallet() - } else { - router.popTo() - } + selectUserWallet() } is SaveWalletError.DataError -> { val messageRef = ensureNotNull(error.messageId?.let(::resourceReference)) { @@ -111,7 +105,7 @@ internal class UserWalletSaver @Inject constructor( ) } - private suspend fun Raise.createUserWallet(response: ScanResponse): UserWallet { + private fun Raise.createUserWallet(response: ScanResponse): UserWallet { val userWallet = coldUserWalletBuilderFactory.create(scanResponse = response).build() return ensureNotNull(userWallet) { Error.Unknown } diff --git a/features/home/impl/src/main/kotlin/com/tangem/features/home/impl/DefaultHomeComponent.kt b/features/home/impl/src/main/kotlin/com/tangem/features/home/impl/DefaultHomeComponent.kt index 7c210b9af7..f1450a1f61 100644 --- a/features/home/impl/src/main/kotlin/com/tangem/features/home/impl/DefaultHomeComponent.kt +++ b/features/home/impl/src/main/kotlin/com/tangem/features/home/impl/DefaultHomeComponent.kt @@ -9,7 +9,6 @@ import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.features.home.api.HomeComponent import com.tangem.features.home.impl.model.HomeModel import com.tangem.features.home.impl.ui.Home -import com.tangem.features.hotwallet.HotWalletFeatureToggles import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -17,7 +16,6 @@ import dagger.assisted.AssistedInject internal class DefaultHomeComponent @AssistedInject constructor( @Assisted appComponentContext: AppComponentContext, @Assisted params: HomeComponent.Params, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, ) : HomeComponent, AppComponentContext by appComponentContext { private val model: HomeModel = getOrCreateModel(params) @@ -26,11 +24,7 @@ internal class DefaultHomeComponent @AssistedInject constructor( override fun Content(modifier: Modifier) { val state by model.uiState.collectAsStateWithLifecycle() - Home( - state = state, - modifier = modifier, - isV2StoriesEnabled = hotWalletFeatureToggles.isHotWalletEnabled, - ) + Home(state = state, modifier = modifier) } @AssistedFactory diff --git a/features/home/impl/src/main/kotlin/com/tangem/features/home/impl/model/HomeModel.kt b/features/home/impl/src/main/kotlin/com/tangem/features/home/impl/model/HomeModel.kt index e650912dc6..099a3e49c3 100644 --- a/features/home/impl/src/main/kotlin/com/tangem/features/home/impl/model/HomeModel.kt +++ b/features/home/impl/src/main/kotlin/com/tangem/features/home/impl/model/HomeModel.kt @@ -35,14 +35,12 @@ import com.tangem.domain.settings.usercountry.GetUserCountryUseCase import com.tangem.domain.settings.usercountry.models.UserCountry import com.tangem.domain.settings.usercountry.models.needApplyFCARestrictions import com.tangem.domain.wallets.builder.ColdUserWalletBuilder -import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.usecase.GenerateBuyTangemCardLinkUseCase import com.tangem.domain.wallets.usecase.SaveWalletUseCase import com.tangem.features.home.api.HomeComponent import com.tangem.features.home.impl.ui.state.HomeUM import com.tangem.features.home.impl.ui.state.Stories import com.tangem.features.home.impl.ui.state.getRestrictedStories -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.delay @@ -70,8 +68,6 @@ internal class HomeModel @Inject constructor( private val saveWalletUseCase: SaveWalletUseCase, private val generateBuyTangemCardLinkUseCase: GenerateBuyTangemCardLinkUseCase, private val urlOpener: UrlOpener, - private val userWalletsListManager: UserWalletsListManager, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, private val userWalletsListRepository: UserWalletsListRepository, private val reduxStateHolder: ReduxStateHolder, @GlobalUiMessageSender private val uiMessageSender: UiMessageSender, @@ -216,7 +212,7 @@ internal class HomeModel @Inject constructor( currency = currency, batch = scanResponse.card.batchId, signInType = SignInType.Card, - walletsCount = getWalletsCount().toString(), + walletsCount = userWalletsListRepository.userWalletsSync().size.toString(), isImported = isImported, hasBackup = scanResponse.card.backupStatus?.isActive, ), @@ -224,14 +220,6 @@ internal class HomeModel @Inject constructor( } } - private suspend fun getWalletsCount(): Int { - return if (hotWalletFeatureToggles.isHotWalletEnabled) { - userWalletsListRepository.userWalletsSync().size - } else { - userWalletsListManager.walletsCount - } - } - private fun setLoading(isLoading: Boolean) { _uiState.update { it.copy(scanInProgress = isLoading) } } diff --git a/features/home/impl/src/main/kotlin/com/tangem/features/home/impl/ui/Home.kt b/features/home/impl/src/main/kotlin/com/tangem/features/home/impl/ui/Home.kt index 7277504058..b245ef97b4 100644 --- a/features/home/impl/src/main/kotlin/com/tangem/features/home/impl/ui/Home.kt +++ b/features/home/impl/src/main/kotlin/com/tangem/features/home/impl/ui/Home.kt @@ -5,29 +5,18 @@ import androidx.compose.ui.Modifier import com.tangem.core.ui.components.SystemBarsIconsDisposable import com.tangem.core.ui.res.TangemColorPalette import com.tangem.core.ui.utils.ChangeRootBackgroundColorEffect -import com.tangem.features.home.impl.ui.compose.StoriesScreen import com.tangem.features.home.impl.ui.compose.StoriesScreenV2 import com.tangem.features.home.impl.ui.state.HomeUM @Composable -internal fun Home(state: HomeUM, isV2StoriesEnabled: Boolean, modifier: Modifier = Modifier) { +internal fun Home(state: HomeUM, modifier: Modifier = Modifier) { SystemBarsIconsDisposable(darkIcons = false) - if (isV2StoriesEnabled) { - StoriesScreenV2( - modifier = modifier, - state = state, - onGetStartedClick = state.onGetStartedClick, - ) - } else { - StoriesScreen( - modifier = modifier, - state = state, - onScanButtonClick = state.onScanClick, - onShopButtonClick = state.onShopClick, - onSearchTokensClick = state.onSearchTokensClick, - ) - } + StoriesScreenV2( + modifier = modifier, + state = state, + onGetStartedClick = state.onGetStartedClick, + ) ChangeRootBackgroundColorEffect(TangemColorPalette.Black) } \ No newline at end of file diff --git a/features/home/impl/src/main/kotlin/com/tangem/features/home/impl/ui/compose/StoriesScreen.kt b/features/home/impl/src/main/kotlin/com/tangem/features/home/impl/ui/compose/StoriesScreen.kt deleted file mode 100644 index 8eab486edb..0000000000 --- a/features/home/impl/src/main/kotlin/com/tangem/features/home/impl/ui/compose/StoriesScreen.kt +++ /dev/null @@ -1,271 +0,0 @@ -@file:Suppress("MagicNumber") - -package com.tangem.features.home.impl.ui.compose - -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.gestures.detectTapGestures -import androidx.compose.foundation.layout.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.input.pointer.pointerInput -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.testTag -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.core.ui.test.StoriesScreenTestTags -import com.tangem.features.home.impl.ui.compose.content.* -import com.tangem.features.home.impl.ui.compose.views.HomeButtons -import com.tangem.features.home.impl.ui.compose.views.SearchCurrenciesButton -import com.tangem.features.home.impl.ui.compose.views.StoriesProgressBar -import com.tangem.features.home.impl.ui.state.Stories -import com.tangem.core.ui.R -import com.tangem.features.home.impl.ui.state.HomeUM -import kotlin.math.max - -@Composable -internal fun StoriesScreen( - state: HomeUM, - onScanButtonClick: () -> Unit, - onShopButtonClick: () -> Unit, - onSearchTokensClick: () -> Unit, - modifier: Modifier = Modifier, -) { - var currentStory by remember { mutableStateOf(state.firstStory) } - val currentStoryIndex by rememberUpdatedState(newValue = state.stepOf(currentStory)) - - LaunchedEffect(currentStoryIndex) { - if (currentStoryIndex < 0) { - currentStory = state.firstStory - } - } - - val goToPreviousStory = remember(currentStory, currentStoryIndex) { - { currentStory = state.stories[max(0, currentStoryIndex - 1)] } - } - val goToNextStory = remember(currentStory, currentStoryIndex) { - { - currentStory = if (currentStoryIndex >= 0 && currentStoryIndex < state.stories.lastIndex) { - state.stories[currentStoryIndex + 1] - } else { - state.firstStory - } - } - } - - // todo refactor [REDACTED_TASK_KEY] - StoriesScreenContent( - modifier = modifier - .fillMaxSize() - .testTag(StoriesScreenTestTags.SCREEN_CONTAINER), - config = StoriesScreenContentConfig( - storiesSize = state.stories.lastIndex, - currentStoryIndex = currentStoryIndex, - currentStory = currentStory, - isScanInProgress = state.scanInProgress, - onGoToPreviousStory = goToPreviousStory, - onGoToNextStory = goToNextStory, - onSearchTokensClick = onSearchTokensClick, - onScanButtonClick = onScanButtonClick, - onShopButtonClick = onShopButtonClick, - ), - ) -} - -@Deprecated("Use StoriesContainer from core/ui") -@Suppress("LongMethod") -@Composable -private fun StoriesScreenContent(config: StoriesScreenContentConfig, modifier: Modifier = Modifier) { - var isPressed by remember { mutableStateOf(value = false) } - - val isPaused = isPressed || config.isScanInProgress - val currentStoryDuration = config.currentStory.duration - - Box( - modifier = modifier.background(Color(0xFF010101)), - ) { - Row( - modifier = Modifier.fillMaxSize(), - ) { - Box( - Modifier - .weight(1f) - .fillMaxHeight() - .pointerInput(Unit) { - detectTapGestures( - onPress = { - val pressStartTime = System.currentTimeMillis() - isPressed = true - this.tryAwaitRelease() - val pressEndTime = System.currentTimeMillis() - val totalPressTime = pressEndTime - pressStartTime - if (totalPressTime < 200) config.onGoToPreviousStory() - isPressed = false - }, - ) - }, - ) - Box( - Modifier - .weight(1f) - .fillMaxHeight() - .pointerInput(Unit) { - detectTapGestures( - onPress = { - val pressStartTime = System.currentTimeMillis() - isPressed = true - this.tryAwaitRelease() - val pressEndTime = System.currentTimeMillis() - val totalPressTime = pressEndTime - pressStartTime - if (totalPressTime < 200) config.onGoToNextStory() - isPressed = false - }, - ) - }, - ) - } - - Column( - modifier = Modifier - .statusBarsPadding() - .fillMaxSize(), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center, - ) { - StoriesProgressBar( - steps = config.storiesSize, - currentStep = config.currentStoryIndex, - stepDuration = currentStoryDuration, - paused = isPaused, - onStepFinish = config.onGoToNextStory, - ) - Image( - painter = painterResource(id = R.drawable.ic_tangem_logo), - contentDescription = null, - contentScale = ContentScale.FillHeight, - modifier = Modifier - .padding( - start = TangemTheme.dimens.spacing16, - top = TangemTheme.dimens.spacing16, - ) - .height(TangemTheme.dimens.size18) - .align(Alignment.Start), - ) - when (config.currentStory) { - Stories.TangemIntro -> FirstStoriesContent( - isPaused = isPaused, - duration = currentStoryDuration, - ) - Stories.RevolutionaryWallet -> StoriesRevolutionaryWallet() - Stories.UltraSecureBackup -> StoriesUltraSecureBackup( - isPaused = isPaused, - stepDuration = currentStoryDuration, - ) - Stories.Currencies -> StoriesCurrencies(isPaused, currentStoryDuration) - Stories.Web3 -> StoriesWeb3(isPaused, currentStoryDuration) - Stories.WalletForEveryone -> StoriesWalletForEveryone(currentStoryDuration) - } - } - Column( - modifier = Modifier - .navigationBarsPadding() - .padding(bottom = TangemTheme.dimens.spacing16) - .padding(horizontal = TangemTheme.dimens.spacing16) - .align(Alignment.BottomCenter) - .fillMaxWidth(), - verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12), - ) { - AnimatedVisibility( - visible = config.currentStory == Stories.Currencies, - enter = fadeIn(), - exit = fadeOut(), - ) { - SearchCurrenciesButton( - modifier = Modifier.fillMaxWidth(), - onClick = config.onSearchTokensClick, - ) - } - - HomeButtons( - modifier = Modifier.fillMaxWidth(), - btnScanStateInProgress = config.isScanInProgress, - onScanButtonClick = config.onScanButtonClick, - onShopButtonClick = config.onShopButtonClick, - ) - } - } -} - -private data class StoriesScreenContentConfig( - val storiesSize: Int, - val currentStoryIndex: Int, - val currentStory: Stories, - val isScanInProgress: Boolean, - val onGoToPreviousStory: () -> Unit = {}, - val onGoToNextStory: () -> Unit = {}, - val onSearchTokensClick: () -> Unit = {}, - val onScanButtonClick: () -> Unit = {}, - val onShopButtonClick: () -> Unit = {}, -) - -// region Preview -@Preview(showBackground = true, widthDp = 360) -@Composable -private fun StoriesScreenContentPreview( - @PreviewParameter(StoriesScreenContentConfigProvider::class) config: StoriesScreenContentConfig, -) { - TangemThemePreview { - StoriesScreenContent(config = config) - } -} - -private class StoriesScreenContentConfigProvider : CollectionPreviewParameterProvider( - collection = listOf( - StoriesScreenContentConfig( - storiesSize = 6, - currentStoryIndex = 0, - currentStory = Stories.TangemIntro, - isScanInProgress = true, - ), - StoriesScreenContentConfig( - storiesSize = 6, - currentStoryIndex = 1, - currentStory = Stories.RevolutionaryWallet, - isScanInProgress = false, - ), - StoriesScreenContentConfig( - storiesSize = 6, - currentStoryIndex = 2, - currentStory = Stories.UltraSecureBackup, - isScanInProgress = false, - ), - StoriesScreenContentConfig( - storiesSize = 6, - currentStoryIndex = 3, - currentStory = Stories.Currencies, - isScanInProgress = false, - ), - StoriesScreenContentConfig( - storiesSize = 6, - currentStoryIndex = 4, - currentStory = Stories.Web3, - isScanInProgress = false, - ), - StoriesScreenContentConfig( - storiesSize = 6, - currentStoryIndex = 5, - currentStory = Stories.WalletForEveryone, - isScanInProgress = false, - ), - ), -) -// endregion Preview \ No newline at end of file diff --git a/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/HotWalletFeatureToggles.kt b/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/HotWalletFeatureToggles.kt index 02cc6b1973..551b32f7e5 100644 --- a/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/HotWalletFeatureToggles.kt +++ b/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/HotWalletFeatureToggles.kt @@ -1,7 +1,5 @@ package com.tangem.features.hotwallet interface HotWalletFeatureToggles { - val isHotWalletEnabled: Boolean val isWalletCreationRestrictionEnabled: Boolean - val isHotWalletVisible: Boolean } \ No newline at end of file diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/DefaultHotWalletFeatureToggles.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/DefaultHotWalletFeatureToggles.kt index 9659ed2c61..1eadc2342d 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/DefaultHotWalletFeatureToggles.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/DefaultHotWalletFeatureToggles.kt @@ -5,11 +5,7 @@ import com.tangem.core.configtoggle.feature.FeatureTogglesManager internal class DefaultHotWalletFeatureToggles( private val featureTogglesManager: FeatureTogglesManager, ) : HotWalletFeatureToggles { - override val isHotWalletEnabled: Boolean - get() = featureTogglesManager.isFeatureEnabled(name = "HOT_WALLET_ENABLED") + override val isWalletCreationRestrictionEnabled: Boolean - get() = isHotWalletEnabled && - featureTogglesManager.isFeatureEnabled(name = "HOT_WALLET_CREATION_RESTRICTION_ENABLED") - override val isHotWalletVisible: Boolean - get() = featureTogglesManager.isFeatureEnabled(name = "HOT_WALLET_VISIBLE") + get() = featureTogglesManager.isFeatureEnabled(name = "HOT_WALLET_CREATION_RESTRICTION_ENABLED") } \ No newline at end of file diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/di/HotWalletFeatureModule.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/di/HotWalletFeatureModule.kt index feec2263d5..ccb6fb049a 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/di/HotWalletFeatureModule.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/di/HotWalletFeatureModule.kt @@ -3,9 +3,6 @@ package com.tangem.features.hotwallet.di import com.tangem.core.configtoggle.feature.FeatureTogglesManager import com.tangem.features.hotwallet.DefaultHotWalletFeatureToggles import com.tangem.features.hotwallet.HotWalletFeatureToggles -import com.tangem.features.hotwallet.MnemonicRepository -import com.tangem.features.hotwallet.common.repository.DefaultMnemonicRepository -import dagger.Binds import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -18,15 +15,7 @@ internal object HotWalletFeatureModule { @Provides @Singleton - fun provideFeatureToggles(featureTogglesManager: FeatureTogglesManager): HotWalletFeatureToggles { + fun provideHotWalletFeatureToggles(featureTogglesManager: FeatureTogglesManager): HotWalletFeatureToggles { return DefaultHotWalletFeatureToggles(featureTogglesManager) } -} - -@Module -@InstallIn(SingletonComponent::class) -internal interface HotWalletFeatureModuleBinds { - @Binds - @Singleton - fun provideMnemonicRepository(repository: DefaultMnemonicRepository): MnemonicRepository } \ No newline at end of file diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/di/MnemonicRepositoryModule.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/di/MnemonicRepositoryModule.kt new file mode 100644 index 0000000000..3b46484973 --- /dev/null +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/di/MnemonicRepositoryModule.kt @@ -0,0 +1,18 @@ +package com.tangem.features.hotwallet.di + +import com.tangem.features.hotwallet.MnemonicRepository +import com.tangem.features.hotwallet.common.repository.DefaultMnemonicRepository +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +internal interface MnemonicRepositoryModule { + + @Binds + @Singleton + fun provideMnemonicRepository(repository: DefaultMnemonicRepository): MnemonicRepository +} \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/model/OnboardingEntryModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/model/OnboardingEntryModel.kt index 6f3f8945e9..d3a679ae26 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/model/OnboardingEntryModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/model/OnboardingEntryModel.kt @@ -17,10 +17,7 @@ import com.tangem.domain.models.scan.ProductType import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.settings.repositories.SettingsRepository -import com.tangem.domain.wallets.legacy.UserWalletsListManager -import com.tangem.domain.wallets.legacy.asLockable import com.tangem.features.biometry.AskBiometryComponent -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.features.onboarding.v2.TitleProvider import com.tangem.features.onboarding.v2.common.ui.CantLeaveBackupDialog import com.tangem.features.onboarding.v2.done.api.OnboardingDoneComponent @@ -47,8 +44,6 @@ internal class OnboardingEntryModel @Inject constructor( private val settingsRepository: SettingsRepository, private val analyticsEventHandler: AnalyticsEventHandler, private val uiMessageSender: UiMessageSender, - private val userWalletsListManager: UserWalletsListManager, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, private val userWalletsListRepository: UserWalletsListRepository, ) : Model() { @@ -215,29 +210,12 @@ internal class OnboardingEntryModel @Inject constructor( } private fun exitComponentScreen() { - // new flow - if (hotWalletFeatureToggles.isHotWalletEnabled) { - modelScope.launch { - if (userWalletsListRepository.userWalletsSync().isEmpty()) { - router.replaceAll(AppRoute.Home()) - } else { - router.replaceAll(AppRoute.Wallet) - } - } - return - } - - // legacy flow - if (userWalletsListManager.hasUserWallets) { - val isLocked = runCatching { userWalletsListManager.asLockable()?.isLocked!! }.getOrElse { false } - - if (isLocked) { - router.replaceAll(AppRoute.Welcome()) + modelScope.launch { + if (userWalletsListRepository.userWalletsSync().isEmpty()) { + router.replaceAll(AppRoute.Home()) } else { router.replaceAll(AppRoute.Wallet) } - } else { - router.replaceAll(AppRoute.Home()) } } diff --git a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/WalletCardItemDelegate.kt b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/WalletCardItemDelegate.kt index 8162044ed2..ae1378d60d 100644 --- a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/WalletCardItemDelegate.kt +++ b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/WalletCardItemDelegate.kt @@ -6,49 +6,37 @@ import com.tangem.core.ui.components.block.model.BlockUM import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringReference import com.tangem.domain.models.wallet.UserWallet -import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsSyncUseCase import com.tangem.feature.walletsettings.entity.DialogConfig import com.tangem.feature.walletsettings.entity.WalletSettingsItemUM import com.tangem.feature.walletsettings.impl.R -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.features.wallet.utils.UserWalletImageFetcher import com.tangem.operations.attestation.ArtworkSize import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.map internal class WalletCardItemDelegate @AssistedInject constructor( - private val getShouldSaveUserWalletsSyncUseCase: ShouldSaveUserWalletsSyncUseCase, private val walletImageFetcher: UserWalletImageFetcher, @Assisted private val dialogNavigation: SlotNavigation, @Assisted private val onUpgradeHotWalletClick: () -> Unit, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, ) { - fun cardItemFlow(wallet: UserWallet): Flow = combine( - flow = walletImageFetcher.walletImage(wallet, ArtworkSize.SMALL), - flow2 = if (!hotWalletFeatureToggles.isHotWalletEnabled) { - flow { emit(getShouldSaveUserWalletsSyncUseCase()) } - } else { - flowOf(true) - }, - transform = { imageState, isRenameAvailable -> + fun cardItemFlow(wallet: UserWallet): Flow { + return walletImageFetcher.walletImage(wallet, ArtworkSize.SMALL).map { imageState -> val walletName = wallet.name WalletSettingsItemUM.CardBlock( id = "wallet_name", title = resourceReference(id = R.string.user_wallet_list_rename_popup_placeholder), text = stringReference(walletName), - isEnabled = isRenameAvailable, + isEnabled = true, onClick = { openRenameWalletDialog(wallet) }, imageState = imageState, additionalBlock = buildUpgradeToHardwareWalletBlockOrNull(wallet), ) - }, - ) + } + } private fun buildUpgradeToHardwareWalletBlockOrNull(wallet: UserWallet): BlockUM? { return BlockUM( diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt index 8618fdb312..67c8c2384d 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt @@ -43,7 +43,6 @@ import com.tangem.feature.wallet.presentation.wallet.ui.components.visa.KycRejec import com.tangem.feature.wallet.presentation.wallet.utils.ScreenLifecycleProvider import com.tangem.features.biometry.AskBiometryComponent import com.tangem.features.feed.entry.featuretoggle.FeedFeatureToggle -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.features.pushnotifications.api.PushNotificationsModelCallbacks import com.tangem.features.tangempay.TangemPayFeatureToggles import com.tangem.features.wallet.deeplink.WalletDeepLinkActionListener @@ -88,9 +87,7 @@ internal class WalletModel @Inject constructor( private val notificationsRepository: NotificationsRepository, private val getWalletsListForEnablingUseCase: GetWalletsForAutomaticallyPushEnablingUseCase, private val setNotificationsEnabledUseCase: SetNotificationsEnabledUseCase, - private val shouldSaveUserWalletsSyncUseCase: ShouldSaveUserWalletsSyncUseCase, private val getIsHuaweiDeviceWithoutGoogleServicesUseCase: GetIsHuaweiDeviceWithoutGoogleServicesUseCase, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, private val userWalletsListRepository: UserWalletsListRepository, private val tangemPayFeatureToggles: TangemPayFeatureToggles, private val yieldSupplyApyUpdateUseCase: YieldSupplyApyUpdateUseCase, @@ -210,49 +207,39 @@ internal class WalletModel @Inject constructor( } private fun trackScreenOpened() { - if (hotWalletFeatureToggles.isHotWalletEnabled) { - modelScope.launch { - userWalletsListRepository - .selectedUserWalletSync() - ?.let { selectedWallet -> - val hasMobileWallet = userWalletsListRepository.userWalletsSync() - .any { it is UserWallet.Hot } + modelScope.launch { + userWalletsListRepository + .selectedUserWalletSync() + ?.let { selectedWallet -> + val hasMobileWallet = userWalletsListRepository.userWalletsSync() + .any { it is UserWallet.Hot } - val accountsCount = if (isAccountsModeEnabledUseCase.invokeSync()) { - singleAccountListSupplier(selectedWallet.walletId) - .first() - .accounts - .size - } else { - null - } - val result = getAppThemeModeUseCase().firstOrNull() - val theme = result?.getOrElse { AppThemeMode.FOLLOW_SYSTEM } ?: AppThemeMode.FOLLOW_SYSTEM - analyticsEventsHandler.send( - WalletScreenAnalyticsEvent.MainScreen.ScreenOpened( - hasMobileWallet = hasMobileWallet, - accountsCount = accountsCount, - theme = theme.value, - isImported = selectedWallet.isImported(), - ), - ) + val accountsCount = if (isAccountsModeEnabledUseCase.invokeSync()) { + singleAccountListSupplier(selectedWallet.walletId) + .first() + .accounts + .size + } else { + null } - } - } else { - analyticsEventsHandler.send( - WalletScreenAnalyticsEvent.MainScreen.ScreenOpenedLegacy(), - ) + val result = getAppThemeModeUseCase().firstOrNull() + val theme = result?.getOrElse { AppThemeMode.FOLLOW_SYSTEM } ?: AppThemeMode.FOLLOW_SYSTEM + analyticsEventsHandler.send( + WalletScreenAnalyticsEvent.MainScreen.ScreenOpened( + hasMobileWallet = hasMobileWallet, + accountsCount = accountsCount, + theme = theme.value, + isImported = selectedWallet.isImported(), + ), + ) + } } } private suspend fun shouldShowAskBiometryBottomSheet(): Boolean { - return if (hotWalletFeatureToggles.isHotWalletEnabled) { - userWalletsListRepository.userWalletsSync().any { it is UserWallet.Cold } && - shouldShowAskBiometryUseCase() && - canUseBiometryUseCase() - } else { - innerWalletRouter.isWalletLastScreen() && shouldShowAskBiometryUseCase() && canUseBiometryUseCase() - } + return userWalletsListRepository.userWalletsSync().any { it is UserWallet.Cold } && + shouldShowAskBiometryUseCase() && + canUseBiometryUseCase() } private fun subscribeToUserWalletsUpdates() = channelFlow { @@ -298,20 +285,16 @@ internal class WalletModel @Inject constructor( modelScope.launch { val shouldAskNotificationPermissionsViaBs = notificationsRepository.shouldAskNotificationPermissionsViaBs() val shouldShow = notificationsRepository.shouldShowSubscribeOnNotificationsAfterUpdate() - val isBiometricsEnabled = shouldSaveUserWalletsSyncUseCase() val isHuaweiDevice = getIsHuaweiDeviceWithoutGoogleServicesUseCase() Timber.d( "push BS afterUpdate: $shouldShow," + - "isBiometricsEnabled $isBiometricsEnabled," + "isHuaweiDevice $isHuaweiDevice", ) if (!shouldAskNotificationPermissionsViaBs) { notificationsRepository.setShouldAskNotificationPermissionsViaBs(true) return@launch } - if (!hotWalletFeatureToggles.isHotWalletEnabled && !isBiometricsEnabled) { - return@launch - } + if (!shouldShow) { return@launch } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletCardClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletCardClickIntents.kt index ba738c15b9..ee8831d35c 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletCardClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletCardClickIntents.kt @@ -1,56 +1,23 @@ package com.tangem.feature.wallet.child.wallet.model.intents -import arrow.core.getOrElse import com.arkivanov.decompose.router.slot.activate -import com.tangem.common.routing.AppRoute -import com.tangem.common.routing.AppRouter import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.decompose.di.ModelScoped -import com.tangem.domain.card.DeleteSavedAccessCodesUseCase -import com.tangem.domain.redux.ReduxStateHolder -import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.domain.wallets.usecase.DeleteWalletUseCase -import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase -import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent.MainScreen -import com.tangem.feature.wallet.presentation.wallet.domain.MultiWalletTokenListStore -import com.tangem.feature.wallet.presentation.wallet.loaders.WalletScreenContentLoader import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController -import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAlertState import com.tangem.feature.wallet.presentation.wallet.state.model.WalletDialogConfig -import com.tangem.feature.wallet.presentation.wallet.state.model.WalletEvent -import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletEventSender -import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import kotlinx.coroutines.launch -import timber.log.Timber import javax.inject.Inject internal interface WalletCardClickIntents { fun onRenameBeforeConfirmationClick(userWalletId: UserWalletId) - - fun onDeleteBeforeConfirmationClick(userWalletId: UserWalletId) - - fun onDeleteAfterConfirmationClick(userWalletId: UserWalletId) } -// TODO: Refactor -@Suppress("LongParameterList") @ModelScoped internal class WalletCardClickIntentsImplementor @Inject constructor( private val stateHolder: WalletStateController, - private val tokenListStore: MultiWalletTokenListStore, - private val walletEventSender: WalletEventSender, - private val walletScreenContentLoader: WalletScreenContentLoader, - private val getUserWalletUseCase: GetUserWalletUseCase, - private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, - private val deleteWalletUseCase: DeleteWalletUseCase, - private val deleteSavedAccessCodesUseCase: DeleteSavedAccessCodesUseCase, private val analyticsEventHandler: AnalyticsEventHandler, - private val reduxStateHolder: ReduxStateHolder, - private val appRouter: AppRouter, - private val dispatchers: CoroutineDispatcherProvider, ) : BaseWalletClickIntents(), WalletCardClickIntents { override fun onRenameBeforeConfirmationClick(userWalletId: UserWalletId) { @@ -63,47 +30,4 @@ internal class WalletCardClickIntentsImplementor @Inject constructor( ), ) } - - override fun onDeleteBeforeConfirmationClick(userWalletId: UserWalletId) { - analyticsEventHandler.send(MainScreen.DeleteWalletTapped()) - - walletEventSender.send( - event = WalletEvent.ShowAlert( - state = WalletAlertState.RemoveWalletAlert( - onConfirmClick = { onDeleteAfterConfirmationClick(userWalletId) }, - ), - ), - ) - } - - override fun onDeleteAfterConfirmationClick(userWalletId: UserWalletId) { - modelScope.launch(dispatchers.main) { - walletScreenContentLoader.cancel(userWalletId) - tokenListStore.remove(userWalletId) - - val walletToDelete = getUserWalletUseCase(userWalletId).getOrNull() ?: return@launch - val hasUserWallets = deleteWalletUseCase(userWalletId).getOrElse { - Timber.e("Unable to delete user wallet: $it") - return@launch - } - - if (walletToDelete is UserWallet.Cold) { - deleteSavedAccessCodesUseCase(cardId = walletToDelete.cardId).onLeft { - Timber.e("Unable to delete user wallet access code: $it") - } - } - - if (hasUserWallets) { - val selectedWallet = getSelectedWalletSyncUseCase().getOrElse { - error("Unable to find selected wallet: $it") - } - - reduxStateHolder.onUserWalletSelected(selectedWallet) - } else { - tokenListStore.clear() - stateHolder.clear() - appRouter.replaceAll(AppRoute.Home()) - } - } - } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletContentClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletContentClickIntents.kt index b9373e40e8..05ca37c44e 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletContentClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletContentClickIntents.kt @@ -13,7 +13,6 @@ import com.tangem.domain.models.currency.CryptoCurrencyStatus import com.tangem.domain.models.staking.StakingBalance import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.domain.models.wallet.isLocked import com.tangem.domain.nft.analytics.NFTAnalyticsEvent import com.tangem.domain.settings.ShouldShowMarketsTooltipUseCase import com.tangem.domain.tokens.GetCryptoCurrencyActionsUseCase @@ -33,7 +32,6 @@ import com.tangem.feature.wallet.presentation.wallet.state.transformers.CloseBot import com.tangem.feature.wallet.presentation.wallet.state.transformers.OpenBottomSheetTransformer import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.MultiWalletCurrencyActionsConverter import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletEventSender -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.take @@ -90,7 +88,6 @@ internal interface WalletContentClickIntents { internal class WalletContentClickIntentsImplementor @Inject constructor( private val stateHolder: WalletStateController, private val currencyActionsClickIntents: WalletCurrencyActionsClickIntentsImplementor, - private val walletWarningsClickIntents: WalletWarningsClickIntentsImplementor, private val onrampStatusFactory: OnrampStatusFactory, private val getUserWalletUseCase: GetUserWalletUseCase, private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase, @@ -100,44 +97,13 @@ internal class WalletContentClickIntentsImplementor @Inject constructor( private val dispatchers: CoroutineDispatcherProvider, private val walletEventSender: WalletEventSender, private val analyticsEventHandler: AnalyticsEventHandler, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, private val accountDependencies: AccountDependencies, private val yieldSupplySetShouldShowMainPromoUseCase: YieldSupplySetShouldShowMainPromoUseCase, private val tokenListAnalyticsSender: TokenListAnalyticsSender, ) : BaseWalletClickIntents(), WalletContentClickIntents { override fun onDetailsClick() { - if (hotWalletFeatureToggles.isHotWalletEnabled) { - router.openDetailsScreen(stateHolder.getSelectedWalletId()) - return - } - - // Will be removed after Hot Wallet release - modelScope.launch(dispatchers.main) { - val userWalletId = stateHolder.getSelectedWalletId() - val userWallet = getUserWalletUseCase(userWalletId).getOrElse { - Timber.e( - """ - Unable to get user wallet - |- ID: $userWalletId - |- Exception: $it - """.trimIndent(), - ) - - return@launch - } - - if (userWallet.isLocked) { - stateHolder.showBottomSheet( - WalletBottomSheetConfig.UnlockWallets( - onUnlockClick = walletWarningsClickIntents::onUnlockWalletClick, - onScanClick = walletWarningsClickIntents::onScanToUnlockWalletClick, - ), - ) - } else { - router.openDetailsScreen(stateHolder.getSelectedWalletId()) - } - } + router.openDetailsScreen(stateHolder.getSelectedWalletId()) } override fun onOrganizeTokensClick() { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt index ed19a09083..b4a257bd42 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt @@ -35,8 +35,6 @@ import com.tangem.domain.staking.multi.MultiStakingBalanceFetcher import com.tangem.domain.tokens.model.analytics.PromoAnalyticsEvent import com.tangem.domain.tokens.model.analytics.PromoAnalyticsEvent.Program import com.tangem.domain.tokens.model.analytics.PromoAnalyticsEvent.PromotionBannerClicked -import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType -import com.tangem.domain.wallets.models.UnlockWalletsError import com.tangem.domain.wallets.usecase.* import com.tangem.feature.wallet.impl.R import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent @@ -46,11 +44,8 @@ import com.tangem.feature.wallet.presentation.wallet.domain.ScanCardToUnlockWall import com.tangem.feature.wallet.presentation.wallet.domain.ScanCardToUnlockWalletError import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAlertState -import com.tangem.feature.wallet.presentation.wallet.state.model.WalletBottomSheetConfig import com.tangem.feature.wallet.presentation.wallet.state.model.WalletEvent -import com.tangem.feature.wallet.presentation.wallet.state.transformers.CloseBottomSheetTransformer import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletEventSender -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.features.pushnotifications.api.analytics.PushNotificationAnalyticEvents import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.async @@ -71,12 +66,8 @@ internal interface WalletWarningsClickIntents { fun onOpenUnlockWalletsBottomSheetClick() - fun onUnlockWalletClick() - fun onUnlockVisaAccessClick() - fun onScanToUnlockWalletClick() - fun onLikeAppClick() fun onDislikeAppClick() @@ -117,7 +108,6 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( private val remindToRateAppLaterUseCase: RemindToRateAppLaterUseCase, private val getUserWalletUseCase: GetUserWalletUseCase, private val scanCardToUnlockWalletClickHandler: ScanCardToUnlockWalletClickHandler, - private val unlockWalletsUseCase: UnlockWalletsUseCase, private val nonBiometricUnlockWalletUseCase: NonBiometricUnlockWalletUseCase, private val analyticsEventHandler: AnalyticsEventHandler, private val dispatchers: CoroutineDispatcherProvider, @@ -131,7 +121,6 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( private val multiStakingBalanceFetcher: MultiStakingBalanceFetcher, private val stakingIdFactory: StakingIdFactory, private val appRouter: AppRouter, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, private val userWalletsListRepository: UserWalletsListRepository, private val setShouldShowNotificationUseCase: SetShouldShowNotificationUseCase, private val notificationsRepository: NotificationsRepository, @@ -189,43 +178,21 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( override fun onOpenUnlockWalletsBottomSheetClick() { analyticsEventHandler.send(MainScreen.WalletUnlockTapped()) - if (hotWalletFeatureToggles.isHotWalletEnabled) { - modelScope.launch { - userWalletsListRepository.unlockAllWallets() - .onLeft { - val selectedUserWalletId = stateHolder.getSelectedWalletId() - nonBiometricUnlockWalletUseCase(selectedUserWalletId) - .onLeft { error -> - error.handle( - onAlreadyUnlocked = {}, - onUserCancelled = {}, - analyticsEventHandler = analyticsEventHandler, - isFromUnlockAll = true, - showMessage = uiMessageSender::send, - ) - } - } - } - return - } - - // Will be removed after hot wallet release - stateHolder.showBottomSheet( - WalletBottomSheetConfig.UnlockWallets( - onUnlockClick = this::onUnlockWalletClick, - onScanClick = this::onScanToUnlockWalletClick, - ), - ) - } - - @Deprecated("Will be removed with hot wallet release") - override fun onUnlockWalletClick() { - analyticsEventHandler.send(MainScreen.UnlockAllWithBiometrics()) - - modelScope.launch(dispatchers.main) { - unlockWalletsUseCase(type = UnlockType.ALL_WITHOUT_SELECT) - .onRight { stateHolder.update(CloseBottomSheetTransformer(stateHolder.getSelectedWalletId())) } - .onLeft(::handleUnlockWalletsError) + modelScope.launch { + userWalletsListRepository.unlockAllWallets() + .onLeft { + val selectedUserWalletId = stateHolder.getSelectedWalletId() + nonBiometricUnlockWalletUseCase(selectedUserWalletId) + .onLeft { error -> + error.handle( + onAlreadyUnlocked = {}, + onUserCancelled = {}, + analyticsEventHandler = analyticsEventHandler, + isFromUnlockAll = true, + showMessage = uiMessageSender::send, + ) + } + } } } @@ -233,25 +200,6 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( openScanCardDialog() } - private fun handleUnlockWalletsError(error: UnlockWalletsError) { - val event = when (error) { - is UnlockWalletsError.DataError, - is UnlockWalletsError.UnableToUnlockWallets, - -> WalletEvent.ShowError(resourceReference(R.string.user_wallet_list_error_unable_to_unlock)) - is UnlockWalletsError.NoUserWalletSelected, - is UnlockWalletsError.NotAllUserWalletsUnlocked, - -> WalletEvent.ShowAlert(WalletAlertState.RescanWallets) - } - - walletEventSender.send(event) - } - - @Deprecated("Will be removed with hot wallet release") - override fun onScanToUnlockWalletClick() { - analyticsEventHandler.send(MainScreen.UnlockWithCardScan()) - openScanCardDialog() - } - private fun openScanCardDialog() { modelScope.launch(dispatchers.main) { scanCardToUnlockWalletClickHandler(walletId = stateHolder.getSelectedWalletId()) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletNameMigrationUseCase.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletNameMigrationUseCase.kt index 064c5030cf..c6754b834f 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletNameMigrationUseCase.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletNameMigrationUseCase.kt @@ -2,14 +2,11 @@ package com.tangem.feature.wallet.presentation.wallet.domain import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.models.wallet.copy -import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.repository.WalletNamesMigrationRepository import timber.log.Timber class WalletNameMigrationUseCase( - private val userWalletsListManager: UserWalletsListManager, private val userWalletsListRepository: UserWalletsListRepository, - private val useNewListRepository: Boolean, private val walletNamesMigrationRepository: WalletNamesMigrationRepository, ) { @@ -18,28 +15,15 @@ class WalletNameMigrationUseCase( return } - if (useNewListRepository) { - val wallets = userWalletsListRepository.userWalletsSync() - val existingNames: MutableSet = mutableSetOf() - wallets.forEach { - val defaultName = it.name - val suggestedWalletName = suggestedWalletName(defaultName, existingNames) - if (defaultName != suggestedWalletName) { - userWalletsListRepository.saveWithoutLock(it.copy(name = suggestedWalletName), canOverride = true) - } - Timber.tag("Migrated names").e(it.walletId.toString() + " " + suggestedWalletName) - } - } else { - val wallets = userWalletsListManager.userWalletsSync - val existingNames: MutableSet = mutableSetOf() - wallets.indices.forEach { i -> - val defaultName = wallets[i].name - val suggestedWalletName = suggestedWalletName(defaultName, existingNames) - if (defaultName != suggestedWalletName) { - userWalletsListManager.update(wallets[i].walletId) { it.copy(name = suggestedWalletName) } - } - Timber.tag("Migrated names").e(i.toString() + " " + suggestedWalletName) + val wallets = userWalletsListRepository.userWalletsSync() + val existingNames: MutableSet = mutableSetOf() + wallets.forEach { + val defaultName = it.name + val suggestedWalletName = suggestedWalletName(defaultName, existingNames) + if (defaultName != suggestedWalletName) { + userWalletsListRepository.saveWithoutLock(it.copy(name = suggestedWalletName), canOverride = true) } + Timber.tag("Migrated names").e(it.walletId.toString() + " " + suggestedWalletName) } walletNamesMigrationRepository.setMigrationDone() diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoader.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoader.kt index 020e48bbb2..c71fb95879 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoader.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoader.kt @@ -9,7 +9,6 @@ import com.tangem.domain.staking.usecase.StakingAvailabilityListUseCase import com.tangem.domain.tokens.ApplyTokenListSortingUseCase import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.wallets.repository.WalletsRepository -import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase import com.tangem.domain.yield.supply.usecase.YieldSupplyGetShouldShowMainPromoUseCase import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents @@ -21,7 +20,6 @@ import com.tangem.feature.wallet.presentation.wallet.domain.MultiWalletTokenList import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController import com.tangem.feature.wallet.presentation.wallet.subscribers.* -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.features.tangempay.TangemPayFeatureToggles @Suppress("LongParameterList") @@ -40,14 +38,12 @@ internal class MultiWalletContentLoader( private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, private val applyTokenListSortingUseCase: ApplyTokenListSortingUseCase, private val getMultiWalletWarningsFactory: GetMultiWalletWarningsFactory, - private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase, private val getStoryContentUseCase: GetStoryContentUseCase, private val walletsRepository: WalletsRepository, private val currenciesRepository: CurrenciesRepository, private val yieldSupplyApyFlowUseCase: YieldSupplyApyFlowUseCase, private val stakingAvailabilityListUseCase: StakingAvailabilityListUseCase, private val yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, private val tangemPayFeatureToggles: TangemPayFeatureToggles, private val tangemPayMainSubscriberFactory: TangemPayMainSubscriber.Factory, ) : WalletContentLoader(id = userWallet.walletId) { @@ -92,13 +88,6 @@ internal class MultiWalletContentLoader( getStoryContentUseCase = getStoryContentUseCase, ).let(::add) - WalletDropDownItemsSubscriber( - stateHolder = stateHolder, - shouldSaveUserWalletsUseCase = shouldSaveUserWalletsUseCase, - clickIntents = clickIntents, - hotWalletFeatureToggles = hotWalletFeatureToggles, - ).let(::add) - if (tangemPayFeatureToggles.isTangemPayEnabled) { add(tangemPayMainSubscriberFactory.create(userWallet)) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoaderFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoaderFactory.kt index 083c1cdd5b..525899d92e 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoaderFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoaderFactory.kt @@ -9,7 +9,6 @@ import com.tangem.domain.staking.usecase.StakingAvailabilityListUseCase import com.tangem.domain.tokens.ApplyTokenListSortingUseCase import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.wallets.repository.WalletsRepository -import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase import com.tangem.domain.yield.supply.usecase.YieldSupplyGetShouldShowMainPromoUseCase import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents @@ -21,7 +20,6 @@ import com.tangem.feature.wallet.presentation.wallet.domain.MultiWalletTokenList import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController import com.tangem.feature.wallet.presentation.wallet.subscribers.TangemPayMainSubscriber -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.features.tangempay.TangemPayFeatureToggles import javax.inject.Inject @@ -38,7 +36,6 @@ internal class MultiWalletContentLoaderFactory @Inject constructor( private val applyTokenListSortingUseCase: ApplyTokenListSortingUseCase, private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender, private val walletWarningsSingleEventSender: WalletWarningsSingleEventSender, - private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase, private val getStoryContentUseCase: GetStoryContentUseCase, private val walletsRepository: WalletsRepository, private val getNFTCollectionsUseCase: GetNFTCollectionsUseCase, @@ -46,7 +43,6 @@ internal class MultiWalletContentLoaderFactory @Inject constructor( private val yieldSupplyApyFlowUseCase: YieldSupplyApyFlowUseCase, private val stakingAvailabilityListUseCase: StakingAvailabilityListUseCase, private val yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, private val tangemPayFeatureToggles: TangemPayFeatureToggles, private val tangemPayMainSubscriberFactory: TangemPayMainSubscriber.Factory, ) { @@ -65,13 +61,11 @@ internal class MultiWalletContentLoaderFactory @Inject constructor( walletWarningsSingleEventSender = walletWarningsSingleEventSender, applyTokenListSortingUseCase = applyTokenListSortingUseCase, getStoryContentUseCase = getStoryContentUseCase, - shouldSaveUserWalletsUseCase = shouldSaveUserWalletsUseCase, walletsRepository = walletsRepository, getNFTCollectionsUseCase = getNFTCollectionsUseCase, currenciesRepository = currenciesRepository, yieldSupplyApyFlowUseCase = yieldSupplyApyFlowUseCase, stakingAvailabilityListUseCase = stakingAvailabilityListUseCase, - hotWalletFeatureToggles = hotWalletFeatureToggles, tangemPayFeatureToggles = tangemPayFeatureToggles, tangemPayMainSubscriberFactory = tangemPayMainSubscriberFactory, yieldSupplyGetShouldShowMainPromoUseCase = yieldSupplyGetShouldShowMainPromoUseCase, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoaderV2.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoaderV2.kt index df43ae0292..fea4a02329 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoaderV2.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/MultiWalletContentLoaderV2.kt @@ -2,14 +2,12 @@ package com.tangem.feature.wallet.presentation.wallet.loaders.implementors import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.promo.GetStoryContentUseCase -import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsSingleEventSender import com.tangem.feature.wallet.presentation.wallet.domain.GetMultiWalletWarningsFactory import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController import com.tangem.feature.wallet.presentation.wallet.subscribers.* -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.features.tangempay.TangemPayFeatureToggles import dagger.assisted.Assisted import dagger.assisted.AssistedFactory @@ -25,10 +23,8 @@ internal class MultiWalletContentLoaderV2 @AssistedInject constructor( private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender, private val walletWarningsSingleEventSender: WalletWarningsSingleEventSender, private val getMultiWalletWarningsFactory: GetMultiWalletWarningsFactory, - private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase, private val getStoryContentUseCase: GetStoryContentUseCase, private val checkWalletWithFundsSubscriberFactory: CheckWalletWithFundsSubscriber.Factory, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, private val tangemPayFeatureToggles: TangemPayFeatureToggles, private val tangemPayMainSubscriberFactory: TangemPayMainSubscriber.Factory, ) : WalletContentLoader(id = userWallet.walletId) { @@ -50,12 +46,6 @@ internal class MultiWalletContentLoaderV2 @AssistedInject constructor( stateHolder = stateController, getStoryContentUseCase = getStoryContentUseCase, ), - WalletDropDownItemsSubscriber( - stateHolder = stateController, - shouldSaveUserWalletsUseCase = shouldSaveUserWalletsUseCase, - clickIntents = clickIntents, - hotWalletFeatureToggles = hotWalletFeatureToggles, - ), if (tangemPayFeatureToggles.isTangemPayEnabled) { tangemPayMainSubscriberFactory.create(userWallet) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletContentLoader.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletContentLoader.kt index e21e22a688..34c986c644 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletContentLoader.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletContentLoader.kt @@ -10,13 +10,11 @@ import com.tangem.domain.tokens.GetCryptoCurrencyActionsUseCase import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase -import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender import com.tangem.feature.wallet.presentation.wallet.domain.GetSingleWalletWarningsFactory import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController import com.tangem.feature.wallet.presentation.wallet.subscribers.* -import com.tangem.features.hotwallet.HotWalletFeatureToggles @Suppress("LongParameterList") internal class SingleWalletContentLoader( @@ -33,10 +31,8 @@ internal class SingleWalletContentLoader( private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, private val getOnrampTransactionsUseCase: GetOnrampTransactionsUseCase, private val onrampRemoveTransactionUseCase: OnrampRemoveTransactionUseCase, - private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase, private val analyticsEventHandler: AnalyticsEventHandler, private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, ) : WalletContentLoader(id = userWallet.walletId) { override fun create(): List { @@ -63,12 +59,6 @@ internal class SingleWalletContentLoader( getSingleWalletWarningsFactory = getSingleWalletWarningsFactory, walletWarningsAnalyticsSender = walletWarningsAnalyticsSender, ), - WalletDropDownItemsSubscriber( - stateHolder = stateHolder, - shouldSaveUserWalletsUseCase = shouldSaveUserWalletsUseCase, - clickIntents = clickIntents, - hotWalletFeatureToggles = hotWalletFeatureToggles, - ), SingleWalletExpressStatusesSubscriber( userWallet = userWallet, stateHolder = stateHolder, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletContentLoaderFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletContentLoaderFactory.kt index 641029ddb5..4340bf544b 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletContentLoaderFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletContentLoaderFactory.kt @@ -11,12 +11,10 @@ import com.tangem.domain.tokens.GetCryptoCurrencyActionsUseCase import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase -import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender import com.tangem.feature.wallet.presentation.wallet.domain.GetSingleWalletWarningsFactory import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController -import com.tangem.features.hotwallet.HotWalletFeatureToggles import javax.inject.Inject @ModelScoped @@ -33,10 +31,8 @@ internal class SingleWalletContentLoaderFactory @Inject constructor( private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, private val getOnrampTransactionsUseCase: GetOnrampTransactionsUseCase, private val onrampRemoveTransactionUseCase: OnrampRemoveTransactionUseCase, - private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase, private val analyticsEventHandler: AnalyticsEventHandler, private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, ) { fun create(userWallet: UserWallet.Cold, clickIntents: WalletClickIntents, isRefresh: Boolean): WalletContentLoader { @@ -56,8 +52,6 @@ internal class SingleWalletContentLoaderFactory @Inject constructor( walletWarningsAnalyticsSender = walletWarningsAnalyticsSender, getOnrampTransactionsUseCase = getOnrampTransactionsUseCase, onrampRemoveTransactionUseCase = onrampRemoveTransactionUseCase, - shouldSaveUserWalletsUseCase = shouldSaveUserWalletsUseCase, - hotWalletFeatureToggles = hotWalletFeatureToggles, ) } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletContentLoaderV2.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletContentLoaderV2.kt index 2440b54dae..6c4711cb5f 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletContentLoaderV2.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletContentLoaderV2.kt @@ -8,7 +8,6 @@ import com.tangem.domain.onramp.GetOnrampTransactionsUseCase import com.tangem.domain.onramp.OnrampRemoveTransactionUseCase import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase -import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents import com.tangem.feature.wallet.presentation.account.AccountDependencies import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender @@ -16,7 +15,6 @@ import com.tangem.feature.wallet.presentation.wallet.domain.GetSingleWalletWarni import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController import com.tangem.feature.wallet.presentation.wallet.subscribers.* -import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.assisted.Assisted import dagger.assisted.AssistedFactory @@ -35,13 +33,11 @@ internal class SingleWalletContentLoaderV2 @AssistedInject constructor( private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, private val getOnrampTransactionsUseCase: GetOnrampTransactionsUseCase, private val onrampRemoveTransactionUseCase: OnrampRemoveTransactionUseCase, - private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase, private val analyticsEventHandler: AnalyticsEventHandler, private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender, private val accountDependencies: AccountDependencies, private val walletWithFundsChecker: WalletWithFundsChecker, private val dispatchers: CoroutineDispatcherProvider, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, ) : WalletContentLoader(id = userWallet.walletId) { override fun create(): List = listOf( @@ -66,12 +62,6 @@ internal class SingleWalletContentLoaderV2 @AssistedInject constructor( getSingleWalletWarningsFactory = getSingleWalletWarningsFactory, walletWarningsAnalyticsSender = walletWarningsAnalyticsSender, ), - WalletDropDownItemsSubscriber( - stateHolder = stateHolder, - shouldSaveUserWalletsUseCase = shouldSaveUserWalletsUseCase, - clickIntents = clickIntents, - hotWalletFeatureToggles = hotWalletFeatureToggles, - ), SingleWalletExpressStatusesSubscriberV2( userWallet = userWallet, singleAccountStatusListSupplier = accountDependencies.singleAccountStatusListSupplier, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletWithTokenContentLoader.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletWithTokenContentLoader.kt index b5c79b14b9..a43c2c130e 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletWithTokenContentLoader.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletWithTokenContentLoader.kt @@ -4,7 +4,6 @@ import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.promo.GetStoryContentUseCase import com.tangem.domain.staking.usecase.StakingAvailabilityListUseCase -import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase import com.tangem.domain.yield.supply.usecase.YieldSupplyGetShouldShowMainPromoUseCase import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents @@ -15,8 +14,10 @@ import com.tangem.feature.wallet.presentation.wallet.domain.GetMultiWalletWarnin import com.tangem.feature.wallet.presentation.wallet.domain.MultiWalletTokenListStore import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController -import com.tangem.feature.wallet.presentation.wallet.subscribers.* -import com.tangem.features.hotwallet.HotWalletFeatureToggles +import com.tangem.feature.wallet.presentation.wallet.subscribers.MultiWalletActionButtonsSubscriber +import com.tangem.feature.wallet.presentation.wallet.subscribers.MultiWalletWarningsSubscriber +import com.tangem.feature.wallet.presentation.wallet.subscribers.SingleWalletWithTokenListSubscriber +import com.tangem.feature.wallet.presentation.wallet.subscribers.WalletSubscriber @Deprecated("Use SingleWalletWithTokenContentLoaderV2 instead") @Suppress("LongParameterList") @@ -31,11 +32,9 @@ internal class SingleWalletWithTokenContentLoader( private val getMultiWalletWarningsFactory: GetMultiWalletWarningsFactory, private val tokenListStore: MultiWalletTokenListStore, private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, - private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase, private val getStoryContentUseCase: GetStoryContentUseCase, private val yieldSupplyApyFlowUseCase: YieldSupplyApyFlowUseCase, private val stakingAvailabilityListUseCase: StakingAvailabilityListUseCase, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, private val yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase, ) : WalletContentLoader(id = userWallet.walletId) { @@ -66,12 +65,6 @@ internal class SingleWalletWithTokenContentLoader( stateHolder = stateHolder, getStoryContentUseCase = getStoryContentUseCase, ).let(::add) - WalletDropDownItemsSubscriber( - stateHolder = stateHolder, - shouldSaveUserWalletsUseCase = shouldSaveUserWalletsUseCase, - clickIntents = clickIntents, - hotWalletFeatureToggles = hotWalletFeatureToggles, - ).let(::add) } } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletWithTokenContentLoaderFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletWithTokenContentLoaderFactory.kt index bcf4c535a4..a0fcbbd771 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletWithTokenContentLoaderFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletWithTokenContentLoaderFactory.kt @@ -5,7 +5,6 @@ import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.promo.GetStoryContentUseCase import com.tangem.domain.staking.usecase.StakingAvailabilityListUseCase -import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase import com.tangem.domain.yield.supply.usecase.YieldSupplyGetShouldShowMainPromoUseCase import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents @@ -16,7 +15,6 @@ import com.tangem.feature.wallet.presentation.wallet.domain.GetMultiWalletWarnin import com.tangem.feature.wallet.presentation.wallet.domain.MultiWalletTokenListStore import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController -import com.tangem.features.hotwallet.HotWalletFeatureToggles import javax.inject.Inject // TODO: Refactor @@ -32,11 +30,9 @@ internal class SingleWalletWithTokenContentLoaderFactory @Inject constructor( private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender, private val walletWarningsSingleEventSender: WalletWarningsSingleEventSender, - private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase, private val getStoryContentUseCase: GetStoryContentUseCase, private val yieldSupplyApyFlowUseCase: YieldSupplyApyFlowUseCase, private val stakingAvailabilityListUseCase: StakingAvailabilityListUseCase, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, private val yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase, ) { @@ -53,10 +49,8 @@ internal class SingleWalletWithTokenContentLoaderFactory @Inject constructor( walletWarningsAnalyticsSender = walletWarningsAnalyticsSender, walletWarningsSingleEventSender = walletWarningsSingleEventSender, getStoryContentUseCase = getStoryContentUseCase, - shouldSaveUserWalletsUseCase = shouldSaveUserWalletsUseCase, yieldSupplyApyFlowUseCase = yieldSupplyApyFlowUseCase, stakingAvailabilityListUseCase = stakingAvailabilityListUseCase, - hotWalletFeatureToggles = hotWalletFeatureToggles, yieldSupplyGetShouldShowMainPromoUseCase = yieldSupplyGetShouldShowMainPromoUseCase, ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletWithTokenContentLoaderV2.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletWithTokenContentLoaderV2.kt index f230baa27b..f11999ca24 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletWithTokenContentLoaderV2.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/loaders/implementors/SingleWalletWithTokenContentLoaderV2.kt @@ -1,14 +1,15 @@ package com.tangem.feature.wallet.presentation.wallet.loaders.implementors import com.tangem.domain.models.wallet.UserWallet -import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsSingleEventSender import com.tangem.feature.wallet.presentation.wallet.domain.GetMultiWalletWarningsFactory import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController -import com.tangem.feature.wallet.presentation.wallet.subscribers.* -import com.tangem.features.hotwallet.HotWalletFeatureToggles +import com.tangem.feature.wallet.presentation.wallet.subscribers.CheckWalletWithFundsSubscriber +import com.tangem.feature.wallet.presentation.wallet.subscribers.MultiWalletWarningsSubscriber +import com.tangem.feature.wallet.presentation.wallet.subscribers.SingleWalletWithTokenSubscriber +import com.tangem.feature.wallet.presentation.wallet.subscribers.WalletSubscriber import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -23,8 +24,6 @@ internal class SingleWalletWithTokenContentLoaderV2 @AssistedInject constructor( private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender, private val walletWarningsSingleEventSender: WalletWarningsSingleEventSender, private val getMultiWalletWarningsFactory: GetMultiWalletWarningsFactory, - private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, ) : WalletContentLoader(id = userWallet.walletId) { override fun create(): List = listOf( @@ -37,12 +36,6 @@ internal class SingleWalletWithTokenContentLoaderV2 @AssistedInject constructor( walletWarningsAnalyticsSender = walletWarningsAnalyticsSender, walletWarningsSingleEventSender = walletWarningsSingleEventSender, ), - WalletDropDownItemsSubscriber( - stateHolder = stateController, - shouldSaveUserWalletsUseCase = shouldSaveUserWalletsUseCase, - clickIntents = clickIntents, - hotWalletFeatureToggles = hotWalletFeatureToggles, - ), checkWalletWithFundsSubscriberFactory.create(userWallet), ) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletAlertState.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletAlertState.kt index 3e34289d7f..3846271993 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletAlertState.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletAlertState.kt @@ -38,13 +38,6 @@ internal sealed interface WalletAlertState { override val onConfirmClick: (() -> Unit)?, ) : Basic() - data class RemoveWalletAlert(override val onConfirmClick: (() -> Unit)?) : Basic() { - override val title: TextReference? = null - override val message: TextReference = resourceReference(id = R.string.user_wallet_list_delete_prompt) - override val confirmButtonText: TextReference = resourceReference(id = R.string.common_delete) - override val isWarningConfirmButton: Boolean = true - } - data class VisaLimitsInfo( val totalLimit: String, val otherLimit: String, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetWalletCardDropDownItemsTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetWalletCardDropDownItemsTransformer.kt deleted file mode 100644 index 84cccf33f8..0000000000 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/SetWalletCardDropDownItemsTransformer.kt +++ /dev/null @@ -1,73 +0,0 @@ -package com.tangem.feature.wallet.presentation.wallet.state.transformers - -import com.tangem.core.ui.extensions.resourceReference -import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.feature.wallet.child.wallet.model.intents.WalletCardClickIntents -import com.tangem.feature.wallet.impl.R -import com.tangem.feature.wallet.presentation.wallet.state.model.WalletDropDownItems -import com.tangem.feature.wallet.presentation.wallet.state.model.WalletScreenState -import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState -import com.tangem.features.hotwallet.HotWalletFeatureToggles -import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.persistentListOf -import kotlinx.collections.immutable.toImmutableList - -internal class SetWalletCardDropDownItemsTransformer( - private val dropdownEnabled: Boolean, - private val clickIntents: WalletCardClickIntents, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, -) : WalletScreenStateTransformer { - override fun transform(prevState: WalletScreenState): WalletScreenState { - return prevState.copy(wallets = prevState.wallets.map(::transformWalletState).toImmutableList()) - } - - private fun transformWalletState(prevState: WalletState): WalletState { - return when (prevState) { - is WalletState.MultiCurrency.Content -> prevState.copy( - walletCardState = prevState.walletCardState.copySealed( - dropDownItems = constructDropDownItems(prevState.walletCardState.id), - ), - ) - is WalletState.SingleCurrency.Content -> prevState.copy( - walletCardState = prevState.walletCardState.copySealed( - dropDownItems = constructDropDownItems(prevState.walletCardState.id), - ), - ) - is WalletState.MultiCurrency.Locked -> prevState.copy( - walletCardState = prevState.walletCardState.copySealed( - dropDownItems = constructDropDownItems(prevState.walletCardState.id), - ), - ) - is WalletState.SingleCurrency.Locked -> prevState.copy( - walletCardState = prevState.walletCardState.copySealed( - dropDownItems = constructDropDownItems(prevState.walletCardState.id), - ), - ) - } - } - - private fun constructDropDownItems(userWalletId: UserWalletId): ImmutableList { - return if (dropdownEnabled) { - buildList { - add( - WalletDropDownItems( - text = resourceReference(id = R.string.common_rename), - icon = R.drawable.ic_edit_24, - onClick = { clickIntents.onRenameBeforeConfirmationClick(userWalletId) }, - ), - ) - if (!hotWalletFeatureToggles.isHotWalletEnabled) { - add( - WalletDropDownItems( - text = resourceReference(id = R.string.common_delete), - icon = R.drawable.ic_trash_24, - onClick = { clickIntents.onDeleteBeforeConfirmationClick(userWalletId) }, - ), - ) - } - }.toImmutableList() - } else { - persistentListOf() - } - } -} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletLoadingStateFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletLoadingStateFactory.kt index c7baf4f61d..b38da828a2 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletLoadingStateFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/WalletLoadingStateFactory.kt @@ -4,12 +4,17 @@ import com.tangem.core.analytics.models.event.MainScreenAnalyticsEvent.Companion import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig import com.tangem.core.ui.components.marketprice.MarketPriceBlockState import com.tangem.core.ui.components.transactions.state.TxHistoryState +import com.tangem.core.ui.extensions.resourceReference import com.tangem.domain.card.common.util.cardTypesResolver import com.tangem.domain.models.wallet.UserWallet +import com.tangem.domain.models.wallet.UserWalletId +import com.tangem.domain.models.wallet.isMultiCurrency import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents +import com.tangem.feature.wallet.impl.R import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory import com.tangem.feature.wallet.presentation.wallet.domain.WalletImageResolver import com.tangem.feature.wallet.presentation.wallet.state.model.* +import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.flow.MutableStateFlow @@ -41,13 +46,7 @@ internal class WalletLoadingStateFactory( private fun createLoadingHotWalletContent(userWallet: UserWallet.Hot): WalletState.MultiCurrency.Content { return WalletState.MultiCurrency.Content( pullToRefreshConfig = createPullToRefreshConfig(), - walletCardState = WalletCardState.Loading( - id = userWallet.walletId, - title = userWallet.name, - additionalInfo = WalletAdditionalInfoFactory.resolve(wallet = userWallet), - imageResId = null, - dropDownItems = persistentListOf(), - ), + walletCardState = createLoadingWalletCardState(userWallet), buttons = createMultiWalletActions(userWallet), warnings = persistentListOf(), bottomSheetConfig = null, @@ -61,7 +60,7 @@ internal class WalletLoadingStateFactory( private fun createLoadingMultiCurrencyContent(userWallet: UserWallet.Cold): WalletState.MultiCurrency.Content { return WalletState.MultiCurrency.Content( pullToRefreshConfig = createPullToRefreshConfig(), - walletCardState = userWallet.toLoadingWalletCardState(), + walletCardState = createLoadingWalletCardState(userWallet), buttons = createMultiWalletActions(userWallet), warnings = persistentListOf(), bottomSheetConfig = null, @@ -76,7 +75,7 @@ internal class WalletLoadingStateFactory( val currencySymbol = userWallet.scanResponse.cardTypesResolver.getBlockchain().currency return WalletState.SingleCurrency.Content( pullToRefreshConfig = createPullToRefreshConfig(), - walletCardState = userWallet.toLoadingWalletCardState(), + walletCardState = createLoadingWalletCardState(userWallet), warnings = persistentListOf(), bottomSheetConfig = null, buttons = createDimmedButtons(), @@ -98,13 +97,21 @@ internal class WalletLoadingStateFactory( ) } - private fun UserWallet.Cold.toLoadingWalletCardState(): WalletCardState { + private fun createLoadingWalletCardState(userWallet: UserWallet): WalletCardState { return WalletCardState.Loading( - id = walletId, - title = name, - additionalInfo = if (isMultiCurrency) WalletAdditionalInfoFactory.resolve(wallet = this) else null, - imageResId = walletImageResolver.resolve(userWallet = this), - dropDownItems = persistentListOf(), + id = userWallet.walletId, + title = userWallet.name, + additionalInfo = if (!userWallet.isMultiCurrency) { + null + } else { + WalletAdditionalInfoFactory.resolve(wallet = userWallet) + }, + imageResId = if (userWallet is UserWallet.Cold) { + walletImageResolver.resolve(userWallet) + } else { + null + }, + dropDownItems = createDropDownItems(userWalletId = userWallet.walletId), ) } @@ -150,4 +157,14 @@ internal class WalletLoadingStateFactory( WalletManageButton.Sell(enabled = true, dimContent = true, onClick = {}), ) } + + private fun createDropDownItems(userWalletId: UserWalletId): ImmutableList { + return persistentListOf( + WalletDropDownItems( + text = resourceReference(id = R.string.common_rename), + icon = R.drawable.ic_edit_24, + onClick = { clickIntents.onRenameBeforeConfirmationClick(userWalletId) }, + ), + ) + } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/WalletDropDownItemsSubscriber.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/WalletDropDownItemsSubscriber.kt deleted file mode 100644 index bf8a6b47cb..0000000000 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/WalletDropDownItemsSubscriber.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.tangem.feature.wallet.presentation.wallet.subscribers - -import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase -import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents -import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController -import com.tangem.feature.wallet.presentation.wallet.state.transformers.SetWalletCardDropDownItemsTransformer -import com.tangem.features.hotwallet.HotWalletFeatureToggles -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.flow.onEach - -internal class WalletDropDownItemsSubscriber( - private val stateHolder: WalletStateController, - private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase, - private val clickIntents: WalletClickIntents, - private val hotWalletFeatureToggles: HotWalletFeatureToggles, -) : WalletSubscriber() { - override fun create(coroutineScope: CoroutineScope): Flow<*> { - if (!hotWalletFeatureToggles.isHotWalletEnabled) { - return shouldSaveUserWalletsUseCase.invoke() - .distinctUntilChanged() - .onEach { shouldSaveUserWallets -> - stateHolder.update( - SetWalletCardDropDownItemsTransformer( - dropdownEnabled = shouldSaveUserWallets, - clickIntents = clickIntents, - hotWalletFeatureToggles = hotWalletFeatureToggles, - ), - ) - } - } else { - return flow { - stateHolder.update( - SetWalletCardDropDownItemsTransformer( - dropdownEnabled = true, - clickIntents = clickIntents, - hotWalletFeatureToggles = hotWalletFeatureToggles, - ), - ) - } - } - } -} \ No newline at end of file diff --git a/features/welcome/impl/src/main/kotlin/com/tangem/features/welcome/impl/model/WelcomeModel.kt b/features/welcome/impl/src/main/kotlin/com/tangem/features/welcome/impl/model/WelcomeModel.kt index 4179ffefe8..5712dbb7ff 100644 --- a/features/welcome/impl/src/main/kotlin/com/tangem/features/welcome/impl/model/WelcomeModel.kt +++ b/features/welcome/impl/src/main/kotlin/com/tangem/features/welcome/impl/model/WelcomeModel.kt @@ -255,7 +255,7 @@ internal class WelcomeModel @Inject constructor( return canUseBiometryUseCase() && walletsRepository.useBiometricAuthentication() } - suspend fun nonBiometricUnlockWallet(userWalletId: UserWalletId) { + private suspend fun nonBiometricUnlockWallet(userWalletId: UserWalletId) { nonBiometricUnlockWalletUseCase(userWalletId) .onRight { routedOut = true