diff --git a/app/src/main/java/com/tangem/tap/common/analytics/appsflyer/AppsFlyerReferralParamsHandler.kt b/app/src/main/java/com/tangem/tap/common/analytics/appsflyer/AppsFlyerReferralParamsHandler.kt index ed1ca3be0a..68a63f0c00 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/appsflyer/AppsFlyerReferralParamsHandler.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/appsflyer/AppsFlyerReferralParamsHandler.kt @@ -3,6 +3,7 @@ package com.tangem.tap.common.analytics.appsflyer import com.appsflyer.deeplink.DeepLink import com.tangem.datasource.local.appsflyer.AppsFlyerStore import com.tangem.domain.wallets.models.AppsFlyerConversionData +import com.tangem.feature.referral.domain.SetShouldShowMobileWalletPromoUseCase import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob @@ -18,6 +19,7 @@ import kotlin.contracts.contract @Singleton class AppsFlyerReferralParamsHandler @Inject constructor( private val appsFlyerStore: AppsFlyerStore, + private val setShouldShowMobileWalletPromoUseCase: SetShouldShowMobileWalletPromoUseCase, dispatchers: CoroutineDispatcherProvider, ) { @@ -69,6 +71,8 @@ class AppsFlyerReferralParamsHandler @Inject constructor( private fun storeConversionData(refcode: String, campaign: String?) { coroutineScope.launch { mutex.withLock { + setShouldShowMobileWalletPromoUseCase() + .onLeft { Timber.e(it) } appsFlyerStore.storeIfAbsent( value = AppsFlyerConversionData(refcode = refcode, campaign = campaign), ) diff --git a/app/src/test/kotlin/com/tangem/tap/common/analytics/appsflyer/AppsFlyerReferralParamsHandlerTest.kt b/app/src/test/kotlin/com/tangem/tap/common/analytics/appsflyer/AppsFlyerReferralParamsHandlerTest.kt index 5b7dfd4403..c804791992 100644 --- a/app/src/test/kotlin/com/tangem/tap/common/analytics/appsflyer/AppsFlyerReferralParamsHandlerTest.kt +++ b/app/src/test/kotlin/com/tangem/tap/common/analytics/appsflyer/AppsFlyerReferralParamsHandlerTest.kt @@ -3,9 +3,12 @@ package com.tangem.tap.common.analytics.appsflyer import com.appsflyer.deeplink.DeepLink import com.tangem.datasource.local.appsflyer.AppsFlyerStore import com.tangem.domain.wallets.models.AppsFlyerConversionData +import com.tangem.feature.referral.domain.SetShouldShowMobileWalletPromoUseCase import com.tangem.test.core.ProvideTestModels import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider +import arrow.core.right import io.mockk.clearMocks +import io.mockk.coEvery import io.mockk.coVerify import io.mockk.every import io.mockk.mockk @@ -22,9 +25,13 @@ import org.junit.jupiter.params.ParameterizedTest class AppsFlyerReferralParamsHandlerTest { private val appsFlyerStore: AppsFlyerStore = mockk(relaxUnitFun = true) + private val setShouldShowMobileWalletPromoUseCase: SetShouldShowMobileWalletPromoUseCase = mockk { + coEvery { this@mockk.invoke() } returns Unit.right() + } private val handler = AppsFlyerReferralParamsHandler( appsFlyerStore = appsFlyerStore, dispatchers = TestingCoroutineDispatcherProvider(), + setShouldShowMobileWalletPromoUseCase = setShouldShowMobileWalletPromoUseCase, ) @AfterEach @@ -43,6 +50,7 @@ class AppsFlyerReferralParamsHandlerTest { if (model.shouldStore) { val value = AppsFlyerConversionData(refcode = SUCCESS_REFCODE, campaign = SUCCESS_CAMPAIGN) + coVerify { appsFlyerStore.storeIfAbsent(value = value) } } else { coVerify(inverse = true) { appsFlyerStore.storeIfAbsent(value = any()) } diff --git a/features/home/impl/build.gradle.kts b/features/home/impl/build.gradle.kts index d06bedde20..bd620457d9 100644 --- a/features/home/impl/build.gradle.kts +++ b/features/home/impl/build.gradle.kts @@ -27,6 +27,7 @@ dependencies { implementation(projects.common.routing) /** Domain */ + implementation(projects.domain.common) implementation(projects.domain.models) implementation(projects.domain.core) implementation(projects.domain.card) @@ -37,6 +38,10 @@ dependencies { implementation(projects.domain.legacy) implementation(projects.domain.feedback) implementation(projects.domain.feedback.models) + implementation(projects.domain.referral) + + /** Referral */ + implementation(projects.features.referral.domain) /** AndroidX libraries */ implementation(deps.androidx.activity.compose) 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 b261bf588d..91d539dcc8 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 @@ -42,8 +42,10 @@ 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.feature.referral.domain.ShouldShowMobileWalletPromoUseCase import com.tangem.features.hotwallet.HotWalletFeatureToggles import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import com.tangem.utils.coroutines.Debouncer import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.delay import kotlinx.coroutines.flow.* @@ -74,9 +76,12 @@ internal class HomeModel @Inject constructor( private val hotWalletFeatureToggles: HotWalletFeatureToggles, private val userWalletsListRepository: UserWalletsListRepository, private val reduxStateHolder: ReduxStateHolder, + private val shouldShowMobileWalletPromoUseCase: ShouldShowMobileWalletPromoUseCase, @GlobalUiMessageSender private val uiMessageSender: UiMessageSender, ) : Model() { + private val debouncer = Debouncer() + val params = paramsContainer.require() private val _uiState = MutableStateFlow( @@ -145,7 +150,16 @@ internal class HomeModel @Inject constructor( } private fun onGetStartedClick() { - router.push(AppRoute.CreateWalletStart(mode = AppRoute.CreateWalletStart.Mode.ColdWallet)) + debouncer.debounce(modelScope) { + modelScope.launch { + val mode = if (shouldShowMobileWalletPromoUseCase()) { + AppRoute.CreateWalletStart.Mode.HotWallet + } else { + AppRoute.CreateWalletStart.Mode.ColdWallet + } + router.push(AppRoute.CreateWalletStart(mode = mode)) + } + } } private fun scanCard() { diff --git a/features/referral/data/build.gradle.kts b/features/referral/data/build.gradle.kts index 85cd526d9f..ac60688bc4 100644 --- a/features/referral/data/build.gradle.kts +++ b/features/referral/data/build.gradle.kts @@ -18,8 +18,10 @@ dependencies { /** Data modules */ implementation(projects.data.common) + implementation(deps.androidx.datastore) /** Domain modules */ + implementation(projects.domain.common) implementation(projects.domain.legacy) implementation(projects.libs.blockchainSdk) implementation(projects.domain.models) diff --git a/features/referral/data/src/main/java/com/tangem/feature/referral/data/DefaultMobileWalletPromoRepository.kt b/features/referral/data/src/main/java/com/tangem/feature/referral/data/DefaultMobileWalletPromoRepository.kt new file mode 100644 index 0000000000..56a482e96d --- /dev/null +++ b/features/referral/data/src/main/java/com/tangem/feature/referral/data/DefaultMobileWalletPromoRepository.kt @@ -0,0 +1,26 @@ +package com.tangem.feature.referral.data + +import androidx.datastore.preferences.core.booleanPreferencesKey +import com.tangem.datasource.local.preferences.AppPreferencesStore +import com.tangem.datasource.local.preferences.utils.getSyncOrDefault +import com.tangem.feature.referral.domain.MobileWalletPromoRepository +import javax.inject.Inject + +internal class DefaultMobileWalletPromoRepository @Inject constructor( + private val appPreferencesStore: AppPreferencesStore, +) : MobileWalletPromoRepository { + + override suspend fun shouldShowMobileWalletPromo(): Boolean { + return appPreferencesStore.getSyncOrDefault(key = SHOULD_SHOW_MOBILE_WALLET_PROMO_KEY, default = false) + } + + override suspend fun setShouldShowMobileWalletPromo(value: Boolean) { + appPreferencesStore.editData { preferences -> + preferences[SHOULD_SHOW_MOBILE_WALLET_PROMO_KEY] = value + } + } + + private companion object { + val SHOULD_SHOW_MOBILE_WALLET_PROMO_KEY = booleanPreferencesKey("should_show_mobile_wallet_promo") + } +} \ No newline at end of file diff --git a/features/referral/data/src/main/java/com/tangem/feature/referral/di/ReferralRepositoryModule.kt b/features/referral/data/src/main/java/com/tangem/feature/referral/di/ReferralRepositoryModule.kt index 8d2c4cdfd4..2170e1651d 100644 --- a/features/referral/data/src/main/java/com/tangem/feature/referral/di/ReferralRepositoryModule.kt +++ b/features/referral/data/src/main/java/com/tangem/feature/referral/di/ReferralRepositoryModule.kt @@ -2,10 +2,13 @@ package com.tangem.feature.referral.di import com.tangem.blockchainsdk.utils.ExcludedBlockchains import com.tangem.datasource.api.tangemTech.TangemTechApi +import com.tangem.datasource.local.preferences.AppPreferencesStore import com.tangem.datasource.local.userwallet.UserWalletsStore import com.tangem.feature.referral.converters.ReferralConverter +import com.tangem.feature.referral.data.DefaultMobileWalletPromoRepository import com.tangem.feature.referral.data.ExternalReferralRepository import com.tangem.feature.referral.data.ReferralRepositoryImpl +import com.tangem.feature.referral.domain.MobileWalletPromoRepository import com.tangem.feature.referral.domain.ReferralRepository import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.Module @@ -53,4 +56,11 @@ class ReferralRepositoryModule { excludedBlockchains = excludedBlockchains, ) } + + @Provides + @Singleton + fun provideMobileWalletPromoRepository(appPreferencesStore: AppPreferencesStore): MobileWalletPromoRepository = + DefaultMobileWalletPromoRepository( + appPreferencesStore = appPreferencesStore, + ) } \ No newline at end of file diff --git a/features/referral/domain/build.gradle.kts b/features/referral/domain/build.gradle.kts index b9bec0d9f3..3604d3a6be 100644 --- a/features/referral/domain/build.gradle.kts +++ b/features/referral/domain/build.gradle.kts @@ -21,6 +21,7 @@ dependencies { /** Domain modules */ implementation(projects.domain.account.status) implementation(projects.domain.card) + implementation(projects.domain.common) implementation(projects.domain.models) implementation(projects.domain.tokens) implementation(projects.domain.tokens.models) diff --git a/features/referral/domain/src/main/java/com/tangem/feature/referral/domain/MobileWalletPromoRepository.kt b/features/referral/domain/src/main/java/com/tangem/feature/referral/domain/MobileWalletPromoRepository.kt new file mode 100644 index 0000000000..642ab878c7 --- /dev/null +++ b/features/referral/domain/src/main/java/com/tangem/feature/referral/domain/MobileWalletPromoRepository.kt @@ -0,0 +1,8 @@ +package com.tangem.feature.referral.domain + +interface MobileWalletPromoRepository { + + suspend fun shouldShowMobileWalletPromo(): Boolean + + suspend fun setShouldShowMobileWalletPromo(value: Boolean) +} \ No newline at end of file diff --git a/features/referral/domain/src/main/java/com/tangem/feature/referral/domain/SetShouldShowMobileWalletPromoUseCase.kt b/features/referral/domain/src/main/java/com/tangem/feature/referral/domain/SetShouldShowMobileWalletPromoUseCase.kt new file mode 100644 index 0000000000..9049cc72bb --- /dev/null +++ b/features/referral/domain/src/main/java/com/tangem/feature/referral/domain/SetShouldShowMobileWalletPromoUseCase.kt @@ -0,0 +1,18 @@ +package com.tangem.feature.referral.domain + +import arrow.core.Either +import com.tangem.domain.common.wallets.UserWalletsListRepository +import javax.inject.Inject + +class SetShouldShowMobileWalletPromoUseCase @Inject constructor( + private val mobileWalletPromoRepository: MobileWalletPromoRepository, + private val userWalletsListRepository: UserWalletsListRepository, +) { + + suspend operator fun invoke(): Either = Either.catch { + val wallets = userWalletsListRepository.userWallets.value + if (wallets.isNullOrEmpty()) { + mobileWalletPromoRepository.setShouldShowMobileWalletPromo(true) + } + } +} \ No newline at end of file diff --git a/features/referral/domain/src/main/java/com/tangem/feature/referral/domain/ShouldShowMobileWalletPromoUseCase.kt b/features/referral/domain/src/main/java/com/tangem/feature/referral/domain/ShouldShowMobileWalletPromoUseCase.kt new file mode 100644 index 0000000000..09a3b358cc --- /dev/null +++ b/features/referral/domain/src/main/java/com/tangem/feature/referral/domain/ShouldShowMobileWalletPromoUseCase.kt @@ -0,0 +1,12 @@ +package com.tangem.feature.referral.domain + +import javax.inject.Inject + +class ShouldShowMobileWalletPromoUseCase @Inject constructor( + private val mobileWalletPromoRepository: MobileWalletPromoRepository, +) { + + suspend operator fun invoke(): Boolean { + return mobileWalletPromoRepository.shouldShowMobileWalletPromo() + } +} \ No newline at end of file