From 8565d7463840cb97cc3e00dbbea7f8ecc3be9832 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 10 Feb 2025 11:08:23 +0500 Subject: [PATCH] Updated on 2026-08-14 --- features/wallet/impl/build.gradle.kts | 1 + .../implementors/MultiWalletContentLoader.kt | 11 ++++++ .../MultiWalletContentLoaderFactory.kt | 6 ++++ .../SingleWalletWithTokenContentLoader.kt | 11 ++++++ ...ngleWalletWithTokenContentLoaderFactory.kt | 6 ++++ .../wallet/state/model/WalletManageButton.kt | 2 ++ ...MultiWalletActionButtonBadgeTransformer.kt | 19 ++++++++++ .../state/utils/MultiWalletActionsExt.kt | 11 ++++++ .../MultiWalletActionButtonsSubscriber.kt | 30 ++++++++++++++++ .../WalletCurrencyActionsClickIntents.kt | 35 ++++++++++++++++--- 10 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/UpdateMultiWalletActionButtonBadgeTransformer.kt create mode 100644 features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/MultiWalletActionButtonsSubscriber.kt diff --git a/features/wallet/impl/build.gradle.kts b/features/wallet/impl/build.gradle.kts index 0681996220..3749a2f4a1 100644 --- a/features/wallet/impl/build.gradle.kts +++ b/features/wallet/impl/build.gradle.kts @@ -105,6 +105,7 @@ dependencies { implementation(projects.features.markets.api) implementation(projects.features.onramp.api) implementation(projects.features.onboardingV2.api) + implementation(projects.features.swap.api) /** Common modules */ implementation(projects.common) 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 97031f4f76..87438f6260 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 @@ -2,6 +2,7 @@ package com.tangem.feature.wallet.presentation.wallet.loaders.implementors import com.tangem.core.deeplink.DeepLinksRegistry import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase +import com.tangem.domain.promo.ShouldShowSwapStoriesUseCase import com.tangem.domain.tokens.ApplyTokenListSortingUseCase import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase import com.tangem.domain.wallets.models.UserWallet @@ -12,10 +13,12 @@ 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.MultiWalletActionButtonsSubscriber import com.tangem.feature.wallet.presentation.wallet.subscribers.MultiWalletTokenListSubscriber import com.tangem.feature.wallet.presentation.wallet.subscribers.MultiWalletWarningsSubscriber import com.tangem.feature.wallet.presentation.wallet.subscribers.WalletSubscriber import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntents +import com.tangem.features.swap.SwapFeatureToggles @Suppress("LongParameterList") internal class MultiWalletContentLoader( @@ -31,6 +34,8 @@ internal class MultiWalletContentLoader( private val applyTokenListSortingUseCase: ApplyTokenListSortingUseCase, private val getMultiWalletWarningsFactory: GetMultiWalletWarningsFactory, private val runPolkadotAccountHealthCheckUseCase: RunPolkadotAccountHealthCheckUseCase, + private val shouldShowSwapStoriesUseCase: ShouldShowSwapStoriesUseCase, + private val swapFeatureToggles: SwapFeatureToggles, private val deepLinksRegistry: DeepLinksRegistry, ) : WalletContentLoader(id = userWallet.walletId) { @@ -56,6 +61,12 @@ internal class MultiWalletContentLoader( walletWarningsAnalyticsSender = walletWarningsAnalyticsSender, walletWarningsSingleEventSender = walletWarningsSingleEventSender, ), + MultiWalletActionButtonsSubscriber( + userWallet = userWallet, + stateHolder = stateHolder, + shouldShowSwapStoriesUseCase = shouldShowSwapStoriesUseCase, + swapFeatureToggles = swapFeatureToggles, + ), ) } } \ No newline at end of file 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 8f3777af4d..3107bd8568 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 @@ -2,6 +2,7 @@ package com.tangem.feature.wallet.presentation.wallet.loaders.implementors import com.tangem.core.deeplink.DeepLinksRegistry import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase +import com.tangem.domain.promo.ShouldShowSwapStoriesUseCase import com.tangem.domain.tokens.ApplyTokenListSortingUseCase import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase import com.tangem.domain.wallets.models.UserWallet @@ -13,6 +14,7 @@ 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.viewmodels.intents.WalletClickIntents +import com.tangem.features.swap.SwapFeatureToggles import dagger.hilt.android.scopes.ViewModelScoped import javax.inject.Inject @@ -29,6 +31,8 @@ internal class MultiWalletContentLoaderFactory @Inject constructor( private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender, private val walletWarningsSingleEventSender: WalletWarningsSingleEventSender, private val runPolkadotAccountHealthCheckUseCase: RunPolkadotAccountHealthCheckUseCase, + private val shouldShowSwapStoriesUseCase: ShouldShowSwapStoriesUseCase, + private val swapFeatureToggles: SwapFeatureToggles, private val deepLinksRegistry: DeepLinksRegistry, ) { @@ -46,6 +50,8 @@ internal class MultiWalletContentLoaderFactory @Inject constructor( walletWarningsSingleEventSender = walletWarningsSingleEventSender, applyTokenListSortingUseCase = applyTokenListSortingUseCase, runPolkadotAccountHealthCheckUseCase = runPolkadotAccountHealthCheckUseCase, + shouldShowSwapStoriesUseCase = shouldShowSwapStoriesUseCase, + swapFeatureToggles = swapFeatureToggles, deepLinksRegistry = deepLinksRegistry, ) } 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 6e494de5b7..f8c8dc9ea5 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 @@ -2,6 +2,7 @@ package com.tangem.feature.wallet.presentation.wallet.loaders.implementors import com.tangem.core.deeplink.DeepLinksRegistry import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase +import com.tangem.domain.promo.ShouldShowSwapStoriesUseCase import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase import com.tangem.domain.wallets.models.UserWallet import com.tangem.feature.wallet.presentation.wallet.analytics.utils.TokenListAnalyticsSender @@ -11,10 +12,12 @@ 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.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 import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntents +import com.tangem.features.swap.SwapFeatureToggles @Suppress("LongParameterList") internal class SingleWalletWithTokenContentLoader( @@ -29,6 +32,8 @@ internal class SingleWalletWithTokenContentLoader( private val tokenListStore: MultiWalletTokenListStore, private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, private val runPolkadotAccountHealthCheckUseCase: RunPolkadotAccountHealthCheckUseCase, + private val shouldShowSwapStoriesUseCase: ShouldShowSwapStoriesUseCase, + private val swapFeatureToggles: SwapFeatureToggles, private val deepLinksRegistry: DeepLinksRegistry, ) : WalletContentLoader(id = userWallet.walletId) { @@ -53,6 +58,12 @@ internal class SingleWalletWithTokenContentLoader( walletWarningsAnalyticsSender = walletWarningsAnalyticsSender, walletWarningsSingleEventSender = walletWarningsSingleEventSender, ), + MultiWalletActionButtonsSubscriber( + userWallet = userWallet, + stateHolder = stateHolder, + shouldShowSwapStoriesUseCase = shouldShowSwapStoriesUseCase, + swapFeatureToggles = swapFeatureToggles, + ), ) } } \ 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 fb2790cc51..8d16529907 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 @@ -2,6 +2,7 @@ package com.tangem.feature.wallet.presentation.wallet.loaders.implementors import com.tangem.core.deeplink.DeepLinksRegistry import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase +import com.tangem.domain.promo.ShouldShowSwapStoriesUseCase import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase import com.tangem.domain.wallets.models.UserWallet import com.tangem.feature.wallet.presentation.wallet.analytics.utils.TokenListAnalyticsSender @@ -12,6 +13,7 @@ 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.viewmodels.intents.WalletClickIntents +import com.tangem.features.swap.SwapFeatureToggles import javax.inject.Inject // TODO: Refactor @@ -26,6 +28,8 @@ internal class SingleWalletWithTokenContentLoaderFactory @Inject constructor( private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender, private val walletWarningsSingleEventSender: WalletWarningsSingleEventSender, private val runPolkadotAccountHealthCheckUseCase: RunPolkadotAccountHealthCheckUseCase, + private val shouldShowSwapStoriesUseCase: ShouldShowSwapStoriesUseCase, + private val swapFeatureToggles: SwapFeatureToggles, private val deepLinksRegistry: DeepLinksRegistry, ) { @@ -42,6 +46,8 @@ internal class SingleWalletWithTokenContentLoaderFactory @Inject constructor( walletWarningsAnalyticsSender = walletWarningsAnalyticsSender, walletWarningsSingleEventSender = walletWarningsSingleEventSender, runPolkadotAccountHealthCheckUseCase = runPolkadotAccountHealthCheckUseCase, + shouldShowSwapStoriesUseCase = shouldShowSwapStoriesUseCase, + swapFeatureToggles = swapFeatureToggles, deepLinksRegistry = deepLinksRegistry, ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletManageButton.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletManageButton.kt index 515041aec5..af52d510ec 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletManageButton.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletManageButton.kt @@ -143,6 +143,7 @@ internal sealed class WalletManageButton(val config: ActionButtonConfig) { override val dimContent: Boolean, override val onClick: () -> Unit, val isInProgress: Boolean = false, + val showBadge: Boolean = false, ) : WalletManageButton( config = ActionButtonConfig( text = TextReference.Res(id = R.string.swapping_swap_action), @@ -151,6 +152,7 @@ internal sealed class WalletManageButton(val config: ActionButtonConfig) { enabled = enabled, dimContent = dimContent, isInProgress = isInProgress, + showBadge = showBadge, ), ) } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/UpdateMultiWalletActionButtonBadgeTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/UpdateMultiWalletActionButtonBadgeTransformer.kt new file mode 100644 index 0000000000..dc39424862 --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/UpdateMultiWalletActionButtonBadgeTransformer.kt @@ -0,0 +1,19 @@ +package com.tangem.feature.wallet.presentation.wallet.state.transformers + +import com.tangem.domain.wallets.models.UserWalletId +import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState +import com.tangem.feature.wallet.presentation.wallet.state.utils.showSwapBadge + +internal class UpdateMultiWalletActionButtonBadgeTransformer( + private val showSwapBadge: Boolean, + userWalletId: UserWalletId, +) : WalletStateTransformer(userWalletId) { + override fun transform(prevState: WalletState): WalletState { + return when (prevState) { + is WalletState.MultiCurrency.Content -> { + prevState.copy(buttons = prevState.showSwapBadge(showBadge = showSwapBadge)) + } + else -> prevState + } + } +} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/MultiWalletActionsExt.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/MultiWalletActionsExt.kt index e109933f15..b89808ca72 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/MultiWalletActionsExt.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/utils/MultiWalletActionsExt.kt @@ -24,4 +24,15 @@ private fun WalletState.MultiCurrency.Content.changeAvailability(enabled: Boolea } } .toPersistentList() +} + +internal fun WalletState.MultiCurrency.Content.showSwapBadge(showBadge: Boolean): PersistentList { + return buttons + .map { action -> + when (action) { + is WalletManageButton.Swap -> action.copy(showBadge = showBadge) + else -> action + } + } + .toPersistentList() } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/MultiWalletActionButtonsSubscriber.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/MultiWalletActionButtonsSubscriber.kt new file mode 100644 index 0000000000..9c44ec3c2e --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/MultiWalletActionButtonsSubscriber.kt @@ -0,0 +1,30 @@ +package com.tangem.feature.wallet.presentation.wallet.subscribers + +import com.tangem.domain.promo.ShouldShowSwapStoriesUseCase +import com.tangem.domain.wallets.models.UserWallet +import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController +import com.tangem.feature.wallet.presentation.wallet.state.transformers.UpdateMultiWalletActionButtonBadgeTransformer +import com.tangem.features.swap.SwapFeatureToggles +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.map + +internal class MultiWalletActionButtonsSubscriber( + private val userWallet: UserWallet, + private val stateHolder: WalletStateController, + private val shouldShowSwapStoriesUseCase: ShouldShowSwapStoriesUseCase, + private val swapFeatureToggles: SwapFeatureToggles, +) : WalletSubscriber() { + override fun create(coroutineScope: CoroutineScope): Flow<*> = shouldShowSwapStoriesUseCase() + .distinctUntilChanged() + .map { showSwapBadge -> + val showBadge = swapFeatureToggles.isPromoStoriesEnabled && showSwapBadge + stateHolder.update( + UpdateMultiWalletActionButtonBadgeTransformer( + userWalletId = userWallet.walletId, + showSwapBadge = showBadge, + ), + ) + } +} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletCurrencyActionsClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletCurrencyActionsClickIntents.kt index db4d42f963..1e4152a1a0 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletCurrencyActionsClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletCurrencyActionsClickIntents.kt @@ -28,6 +28,8 @@ import com.tangem.domain.demo.IsDemoCardUseCase import com.tangem.domain.exchange.RampStateManager import com.tangem.domain.markets.TokenMarketParams import com.tangem.domain.onramp.model.OnrampSource +import com.tangem.domain.promo.ShouldShowSwapStoriesUseCase +import com.tangem.domain.promo.models.StoryContentIds import com.tangem.domain.redux.ReduxStateHolder import com.tangem.domain.staking.model.stakekit.Yield import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase @@ -51,6 +53,7 @@ import com.tangem.feature.wallet.presentation.wallet.state.model.WalletTokensLis import com.tangem.feature.wallet.presentation.wallet.state.transformers.CloseBottomSheetTransformer import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletEventSender import com.tangem.features.onramp.OnrampFeatureToggles +import com.tangem.features.swap.SwapFeatureToggles import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.hilt.android.scopes.ViewModelScoped import kotlinx.collections.immutable.toImmutableList @@ -110,6 +113,7 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor( private val removeCurrencyUseCase: RemoveCurrencyUseCase, private val getExploreUrlUseCase: GetExploreUrlUseCase, private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, + private val shouldShowSwapStoriesUseCase: ShouldShowSwapStoriesUseCase, private val analyticsEventHandler: AnalyticsEventHandler, private val dispatchers: CoroutineDispatcherProvider, private val reduxStateHolder: ReduxStateHolder, @@ -119,6 +123,7 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor( private val appRouter: AppRouter, private val rampStateManager: RampStateManager, private val onrampFeatureToggles: OnrampFeatureToggles, + private val swapFeatureToggles: SwapFeatureToggles, ) : BaseWalletClickIntents(), WalletCurrencyActionsClickIntents { override fun onSendClick( @@ -430,11 +435,16 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor( return } - onMultiWalletActionClick( - statusFlow = rampStateManager.getExpressInitializationStatus(userWalletId), - route = AppRoute.SwapCrypto(userWalletId = userWalletId), - eventCreator = MainScreenAnalyticsEvent::ButtonSwap, - ) + viewModelScope.launch { + val swapRoute = getSwapRoute( + AppRoute.SwapCrypto(userWalletId = userWalletId), + ) + onMultiWalletActionClick( + statusFlow = rampStateManager.getExpressInitializationStatus(userWalletId), + route = swapRoute, + eventCreator = MainScreenAnalyticsEvent::ButtonSwap, + ) + } } override fun onMultiWalletBuyClick(userWalletId: UserWalletId) { @@ -597,4 +607,19 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor( event = WalletEvent.ShowAlert(state = WalletAlertState.ProvidersStillLoading), ) } + + private suspend fun getSwapRoute(targetRoute: AppRoute): AppRoute { + val isSwapStoriesEnabled = swapFeatureToggles.isPromoStoriesEnabled + val shouldShowSwapStories = shouldShowSwapStoriesUseCase.invokeSync() + val showSwapStories = shouldShowSwapStories && isSwapStoriesEnabled + + return if (showSwapStories) { + AppRoute.Stories( + storyId = StoryContentIds.STORY_FIRST_TIME_SWAP.id, + nextScreen = targetRoute, + ) + } else { + targetRoute + } + } } \ No newline at end of file