Updated on 2026-08-14
This commit is contained in:
parent
f1a4be49b3
commit
ce948a71ae
51 changed files with 20 additions and 1186 deletions
|
|
@ -24,8 +24,6 @@ import com.tangem.datasource.local.preferences.AppPreferencesStore
|
|||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.walletmanager.WalletManagersStore
|
||||
import com.tangem.datasource.utils.WireMockRedirectInterceptor
|
||||
import com.tangem.domain.promo.PromoRepository
|
||||
import com.tangem.domain.promo.models.PromoId
|
||||
import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase
|
||||
import com.tangem.features.pushnotifications.api.utils.PUSH_PERMISSION
|
||||
import com.tangem.tap.MainActivity
|
||||
|
|
@ -59,9 +57,6 @@ abstract class BaseTestCase : TestCase(
|
|||
@Inject
|
||||
lateinit var appPreferencesStore: AppPreferencesStore
|
||||
|
||||
@Inject
|
||||
lateinit var promoRepository: PromoRepository
|
||||
|
||||
@Inject
|
||||
lateinit var walletManagersStore: WalletManagersStore
|
||||
|
||||
|
|
@ -136,7 +131,6 @@ abstract class BaseTestCase : TestCase(
|
|||
value = false
|
||||
)
|
||||
}
|
||||
promoRepository.setNeverToShowWalletPromo(PromoId.Sepa)
|
||||
}
|
||||
apiEnvironmentRule.setup(apiConfigsManager)
|
||||
ActivityScenario.launch(MainActivity::class.java)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import com.tangem.domain.offramp.GetOfframpUrlUseCase
|
|||
import com.tangem.domain.offramp.repository.OfframpRepository
|
||||
import com.tangem.domain.onramp.*
|
||||
import com.tangem.domain.onramp.repositories.*
|
||||
import com.tangem.domain.promo.PromoRepository
|
||||
import com.tangem.domain.settings.repositories.SettingsRepository
|
||||
import com.tangem.tap.data.DefaultOfframpRepository
|
||||
import com.tangem.tap.network.exchangeServices.SellService
|
||||
|
|
@ -269,14 +268,12 @@ internal object OnrampDomainModule {
|
|||
onrampErrorResolver: OnrampErrorResolver,
|
||||
onrampTransactionRepository: OnrampTransactionRepository,
|
||||
settingsRepository: SettingsRepository,
|
||||
promoRepository: PromoRepository,
|
||||
): GetOnrampOffersUseCase {
|
||||
return GetOnrampOffersUseCase(
|
||||
onrampRepository = onrampRepository,
|
||||
errorResolver = onrampErrorResolver,
|
||||
onrampTransactionRepository = onrampTransactionRepository,
|
||||
settingsRepository = settingsRepository,
|
||||
promoRepository = promoRepository,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,11 +2,8 @@ package com.tangem.tap.di.domain
|
|||
|
||||
import com.tangem.domain.promo.GetStoryContentUseCase
|
||||
import com.tangem.domain.promo.PromoRepository
|
||||
import com.tangem.domain.promo.ShouldShowPromoTokenUseCase
|
||||
import com.tangem.domain.promo.ShouldShowPromoWalletUseCase
|
||||
import com.tangem.domain.promo.ShouldShowStoriesUseCase
|
||||
import com.tangem.domain.settings.repositories.SettingsRepository
|
||||
import com.tangem.features.promobanners.api.NewPromoBannersFeatureToggles
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -17,26 +14,6 @@ import javax.inject.Singleton
|
|||
@InstallIn(SingletonComponent::class)
|
||||
internal object PromoDomainModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideShouldShowSwapPromoWalletUseCase(
|
||||
promoRepository: PromoRepository,
|
||||
settingsRepository: SettingsRepository,
|
||||
newPromoBannersFeatureToggles: NewPromoBannersFeatureToggles,
|
||||
): ShouldShowPromoWalletUseCase {
|
||||
return ShouldShowPromoWalletUseCase(
|
||||
promoRepository,
|
||||
settingsRepository,
|
||||
newPromoBannersFeatureToggles.isNewPromoBannersEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideShouldShowSwapPromoTokenUseCase(promoRepository: PromoRepository): ShouldShowPromoTokenUseCase {
|
||||
return ShouldShowPromoTokenUseCase(promoRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideShouldShowSwapStoriesUseCase(promoRepository: PromoRepository): ShouldShowStoriesUseCase {
|
||||
|
|
|
|||
|
|
@ -27,10 +27,6 @@
|
|||
"name": "DYNAMIC_ADDRESSES_ENABLED",
|
||||
"version": "undefined"
|
||||
},
|
||||
{
|
||||
"name": "NEW_PROMO_BANNERS_ENABLED",
|
||||
"version": "5.37"
|
||||
},
|
||||
{
|
||||
"name": "VIRTUAL_ACCOUNTS_ENABLED",
|
||||
"version": "undefined"
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
package com.tangem.datasource.api.promotion.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class PromoBannerResponse(
|
||||
@Json(name = "name") val name: String,
|
||||
@Json(name = "all") val bannerState: BannerState?,
|
||||
) {
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class BannerState(
|
||||
@Json(name = "timeline") val timeline: Timeline,
|
||||
@Json(name = "status") val status: String,
|
||||
@Json(name = "link") val link: String?,
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Timeline(
|
||||
@Json(name = "start") val start: String,
|
||||
@Json(name = "end") val end: String,
|
||||
)
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
package com.tangem.datasource.api.promotion.models
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class PromoBannerV2Response(
|
||||
@Json(name = "promotions")
|
||||
val promotions: List<PromoBannerResponse>,
|
||||
)
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
package com.tangem.datasource.api.tangemTech
|
||||
|
||||
import com.tangem.datasource.api.common.response.ApiResponse
|
||||
import com.tangem.datasource.api.promotion.models.PromoBannerResponse
|
||||
import com.tangem.datasource.api.promotion.models.PromoBannerV2Response
|
||||
import com.tangem.datasource.api.promotion.models.StoryContentResponse
|
||||
import com.tangem.datasource.api.tangemTech.models.*
|
||||
import com.tangem.datasource.api.tangemTech.models.promobanners.PromoBannerDisplaysResponse
|
||||
|
|
@ -172,20 +170,6 @@ interface TangemTechApi {
|
|||
): ApiResponse<GetWalletArchivedAccountsResponse>
|
||||
// endregion
|
||||
|
||||
// region promo banners
|
||||
@GET("/v1/promotion")
|
||||
suspend fun getPromoBanner(
|
||||
@Query("programName") name: String,
|
||||
@Header("Cache-Control") cacheControl: String = "max-age=600",
|
||||
): ApiResponse<PromoBannerResponse>
|
||||
|
||||
@GET("/v2/promotion")
|
||||
suspend fun getPromoBannersV2(
|
||||
@Query("walletId") walletId: String,
|
||||
@Header("Cache-Control") cacheControl: String = "max-age=600",
|
||||
): ApiResponse<PromoBannerV2Response>
|
||||
// endregion
|
||||
|
||||
// region promo banners
|
||||
@GET("v1/banner/displays")
|
||||
suspend fun getPromoBannerDisplays(
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
package com.tangem.datasource.di
|
||||
|
||||
import com.tangem.datasource.local.datastore.RuntimeDataStore
|
||||
import com.tangem.datasource.local.datastore.RuntimeSharedStore
|
||||
import com.tangem.datasource.local.promo.DefaultPromoBannerStore
|
||||
import com.tangem.datasource.local.promo.DefaultPromoStoriesStore
|
||||
import com.tangem.datasource.local.promo.PromoBannerStore
|
||||
import com.tangem.datasource.local.promo.PromoStoriesStore
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
|
|
@ -21,10 +18,4 @@ object PromoStoreModule {
|
|||
fun providePromoStoriesStore(): PromoStoriesStore {
|
||||
return DefaultPromoStoriesStore(dataStore = RuntimeDataStore())
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providePromoBannerStore(): PromoBannerStore {
|
||||
return DefaultPromoBannerStore(dataStore = RuntimeSharedStore())
|
||||
}
|
||||
}
|
||||
|
|
@ -172,8 +172,6 @@ object PreferencesKeys {
|
|||
|
||||
// region Promo
|
||||
fun getShouldShowStoriesKey(storyId: String) = booleanPreferencesKey("shouldShowStories_$storyId")
|
||||
|
||||
fun getShouldShowPromoKey(promoId: String) = booleanPreferencesKey("shouldShowPromo_$promoId")
|
||||
// endregion
|
||||
|
||||
// region Permission
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
package com.tangem.datasource.local.promo
|
||||
|
||||
import com.tangem.datasource.api.promotion.models.PromoBannerResponse
|
||||
import com.tangem.datasource.local.datastore.RuntimeSharedStore
|
||||
|
||||
internal class DefaultPromoBannerStore(
|
||||
private val dataStore: RuntimeSharedStore<Map<String, PromoBannerResponse>>,
|
||||
) : PromoBannerStore {
|
||||
|
||||
override suspend fun getSyncOrNull(promoId: String): PromoBannerResponse? {
|
||||
return dataStore.getSyncOrNull()?.get(promoId)
|
||||
}
|
||||
|
||||
override suspend fun store(promoId: String, promoBanner: PromoBannerResponse) {
|
||||
dataStore.update(emptyMap()) { current ->
|
||||
current + (promoId to promoBanner)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
package com.tangem.datasource.local.promo
|
||||
|
||||
import com.tangem.datasource.api.promotion.models.PromoBannerResponse
|
||||
|
||||
interface PromoBannerStore {
|
||||
|
||||
suspend fun getSyncOrNull(promoId: String): PromoBannerResponse?
|
||||
|
||||
suspend fun store(promoId: String, promoBanner: PromoBannerResponse)
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 18 KiB |
|
|
@ -1,29 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="24dp" android:viewportHeight="1232.1" android:viewportWidth="2516" android:width="49.00901dp">
|
||||
|
||||
<path android:fillColor="#FF000000" android:pathData="m740.2,0L23.5,0c-4.4,0 -8.7,1.6 -11.8,4.6 -3.1,2.9 -4.9,6.9 -4.9,11v670.6c0,4.1 1.8,8.1 4.9,11 3.1,2.9 7.4,4.6 11.8,4.6h716.7c4.4,0 8.7,-1.6 11.8,-4.6 3.1,-2.9 4.9,-6.9 4.9,-11L756.9,15.6c0,-4.1 -1.8,-8.1 -4.9,-11 -3.1,-2.9 -7.4,-4.6 -11.8,-4.6ZM506.9,452.3c0,4.1 -1.8,8.1 -4.9,11 -3.1,2.9 -7.4,4.6 -11.8,4.6h-216.7c-4.4,0 -8.7,-1.6 -11.8,-4.6 -3.1,-2.9 -4.9,-6.9 -4.9,-11v-202.8c0,-4.1 1.8,-8.1 4.9,-11 3.1,-2.9 7.4,-4.6 11.8,-4.6h216.7c4.4,0 8.7,1.6 11.8,4.6 3.1,2.9 4.9,6.9 4.9,11v202.8Z"/>
|
||||
|
||||
<path android:fillColor="#FF000000" android:pathData="m2240.6,234h-216.7c-9.2,0 -16.7,7 -16.7,15.6v202.8c0,8.6 7.5,15.6 16.7,15.6h216.7c9.2,0 16.7,-7 16.7,-15.6v-202.8c0,-8.6 -7.5,-15.6 -16.7,-15.6h0Z"/>
|
||||
|
||||
<path android:fillColor="#FF000000" android:pathData="m1990.7,0h-216.7c-9.2,0 -16.7,7 -16.7,15.6v202.8c0,8.6 7.5,15.6 16.7,15.6h216.7c9.2,0 16.7,-7 16.7,-15.6V15.6c0,-8.6 -7.5,-15.6 -16.7,-15.6Z"/>
|
||||
|
||||
<path android:fillColor="#FF000000" android:pathData="m2490.8,0h-216.7c-9.2,0 -16.7,7 -16.7,15.6v202.8c0,8.6 7.5,15.6 16.7,15.6h216.7c9.2,0 16.7,-7 16.7,-15.6V15.6c0,-8.6 -7.5,-15.6 -16.7,-15.6Z"/>
|
||||
|
||||
<path android:fillColor="#FF000000" android:pathData="m1990.7,467.9h-216.7c-9.2,0 -16.7,7 -16.7,15.6v202.8c0,8.6 7.5,15.6 16.7,15.6h216.7c9.2,0 16.7,-7 16.7,-15.6v-202.8c0,-8.6 -7.5,-15.6 -16.7,-15.6Z"/>
|
||||
|
||||
<path android:fillColor="#FF000000" android:pathData="m2490.8,467.9h-216.7c-9.2,0 -16.7,7 -16.7,15.6v202.8c0,8.6 7.5,15.6 16.7,15.6h216.7c9.2,0 16.7,-7 16.7,-15.6v-202.8c0,-8.6 -7.5,-15.6 -16.7,-15.6Z"/>
|
||||
|
||||
<path android:fillColor="#FF000000" android:pathData="m1615.3,0h-216.7c-9.2,0 -16.7,7 -16.7,15.6v202.8c0,8.6 7.5,15.6 16.7,15.6h216.7c9.2,0 16.7,-7 16.7,-15.6V15.6c0,-8.6 -7.5,-15.6 -16.7,-15.6Z"/>
|
||||
|
||||
<path android:fillColor="#FF000000" android:pathData="m1615.3,467.9h-216.7c-9.2,0 -16.7,7 -16.7,15.6v202.8c0,8.6 7.5,15.6 16.7,15.6h216.7c9.2,0 16.7,-7 16.7,-15.6v-202.8c0,-8.6 -7.5,-15.6 -16.7,-15.6Z"/>
|
||||
|
||||
<path android:fillColor="#FF000000" android:pathData="m1381.9,249.4c0,-4.1 -1.8,-8.1 -4.9,-11 -3.1,-2.9 -7.4,-4.6 -11.8,-4.6h-233.4V15.6c0,-4.1 -1.8,-8.1 -4.9,-11 -3.1,-2.9 -7.4,-4.6 -11.8,-4.6h-216.7c-4.4,0 -8.7,1.6 -11.8,4.6 -3.1,2.9 -4.9,6.9 -4.9,11v670.3c0,4.1 1.8,8.1 4.9,11 3.1,2.9 7.4,4.6 11.8,4.6h216.7c4.4,0 8.7,-1.6 11.8,-4.6 3.1,-2.9 4.9,-6.9 4.9,-11v-218.2h233.4c4.4,0 8.7,-1.6 11.8,-4.6 3.1,-2.9 4.9,-6.9 4.9,-11v-202.8Z"/>
|
||||
|
||||
<path android:fillColor="#FF000000" android:pathData="m1675.2,885c33.8,0 64.5,6.8 92,20.4 27.5,13.6 49.2,33.4 65.2,59.5 16,26.1 24,57.2 24,93.2s-8,67.2 -24,93.4c-16,26.3 -37.6,46.2 -65,60 -27.4,13.8 -58.1,20.6 -92.2,20.6h-125.2v-347.1h125.2ZM1666.2,1163.8c34.5,0 60.5,-9.2 78.3,-27.5 17.7,-18.3 26.6,-44.4 26.6,-78.3s-8.9,-59.4 -26.8,-77.5c-17.9,-18.2 -43.9,-27.3 -78,-27.3h-35.1v210.6h35.1Z"/>
|
||||
|
||||
<path android:fillColor="#FF000000" android:pathData="m2125.7,1092.2h-135.6v69.7h157v70.2h-238.1v-347.1h232.4v69.7h-151.3v68.3h135.6v69.2Z"/>
|
||||
|
||||
<path android:fillColor="#FF000000" android:pathData="m2509.8,885l-121.4,168.4 127.6,178.8h-100.1l-77.3,-112.9 -78.7,112.9h-92.9l127.6,-176.9 -121.4,-170.3h99.1l71.6,104.3 72.6,-104.3h93.4Z"/>
|
||||
|
||||
<path android:fillColor="#FF000000" android:pathData="M0,1033.9h1381.6v49h-1381.6z"/>
|
||||
|
||||
</vector>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 23 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB |
|
|
@ -13,8 +13,6 @@ android {
|
|||
dependencies {
|
||||
implementation(deps.androidx.datastore)
|
||||
|
||||
implementation(deps.jodatime)
|
||||
|
||||
implementation(deps.hilt.android)
|
||||
kapt(deps.hilt.kapt)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,25 +1,17 @@
|
|||
package com.tangem.data.promo
|
||||
|
||||
import com.tangem.data.promo.converters.PromoBannerConverter
|
||||
import com.tangem.data.promo.converters.StoryContentResponseConverter
|
||||
import com.tangem.datasource.api.common.response.getOrThrow
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys.getShouldShowStoriesKey
|
||||
import com.tangem.datasource.local.preferences.utils.get
|
||||
import com.tangem.datasource.local.preferences.utils.getSyncOrDefault
|
||||
import com.tangem.datasource.local.preferences.utils.store
|
||||
import com.tangem.datasource.local.promo.PromoBannerStore
|
||||
import com.tangem.datasource.local.promo.PromoStoriesStore
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.promo.PromoRepository
|
||||
import com.tangem.domain.promo.models.PromoBanner
|
||||
import com.tangem.domain.promo.models.PromoId
|
||||
import com.tangem.domain.promo.models.StoryContent
|
||||
import com.tangem.feature.referral.domain.ReferralRepository
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.runCatching
|
||||
import com.tangem.utils.coroutines.runSuspendCatching
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.withContext
|
||||
|
|
@ -29,84 +21,10 @@ internal class DefaultPromoRepository(
|
|||
private val tangemApi: TangemTechApi,
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val promoStoriesStore: PromoStoriesStore,
|
||||
private val promoBannerStore: PromoBannerStore,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val referralRepository: ReferralRepository,
|
||||
) : PromoRepository {
|
||||
|
||||
private val storyContentConverter = StoryContentResponseConverter()
|
||||
private val promoBannerConverter = PromoBannerConverter()
|
||||
|
||||
override fun isReadyToShowWalletPromo(userWalletId: UserWalletId, promoId: PromoId): Flow<Boolean> {
|
||||
return appPreferencesStore.get(
|
||||
key = PreferencesKeys.getShouldShowPromoKey(promoId = promoId.name),
|
||||
default = true,
|
||||
)
|
||||
.distinctUntilChanged()
|
||||
.map { shouldShow ->
|
||||
when (promoId) {
|
||||
PromoId.Referral -> runSuspendCatching {
|
||||
!referralRepository.isReferralParticipant(userWalletId) && shouldShow
|
||||
}.getOrDefault(false)
|
||||
PromoId.Sepa -> {
|
||||
val isActive = getSepaPromoBanner()?.isActive == true
|
||||
|
||||
isActive && shouldShow
|
||||
}
|
||||
PromoId.VisaPresale -> {
|
||||
val isActive = getVisaPromoBanner()?.isActive == true
|
||||
|
||||
isActive && shouldShow
|
||||
}
|
||||
PromoId.BlackFriday -> {
|
||||
val isActive = getBlackFridayPromoBanner()?.isActive == true
|
||||
|
||||
isActive && shouldShow
|
||||
}
|
||||
PromoId.OnePlusOne -> {
|
||||
val isActive = getOnePlusOnePromoBanner()?.isActive == true
|
||||
|
||||
isActive && shouldShow
|
||||
}
|
||||
PromoId.YieldPromo -> {
|
||||
val isActive = getYieldPromoBanner(userWalletId)?.isActive == true
|
||||
|
||||
isActive && shouldShow
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun isReadyToShowTokenPromo(promoId: PromoId): Flow<Boolean> {
|
||||
return when (promoId) {
|
||||
PromoId.Referral -> flowOf(false)
|
||||
PromoId.Sepa -> flowOf(false)
|
||||
PromoId.VisaPresale -> flowOf(false)
|
||||
PromoId.BlackFriday -> flowOf(false)
|
||||
PromoId.OnePlusOne -> flowOf(false)
|
||||
PromoId.YieldPromo -> flowOf(false)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun setNeverToShowWalletPromo(promoId: PromoId) {
|
||||
appPreferencesStore.store(PreferencesKeys.getShouldShowPromoKey(promoId = promoId.name), false)
|
||||
}
|
||||
|
||||
override suspend fun setNeverToShowTokenPromo(promoId: PromoId) {
|
||||
appPreferencesStore.store(PreferencesKeys.getShouldShowPromoKey(promoId = promoId.name), false)
|
||||
}
|
||||
|
||||
override suspend fun isMoonpayPromoActive(): Boolean {
|
||||
val banner = runCatching(dispatchers.io) {
|
||||
val response = promoBannerStore.getSyncOrNull(MOONPAY_NAME) ?: run {
|
||||
val apiResponse = tangemApi.getPromoBanner(MOONPAY_NAME).getOrThrow()
|
||||
promoBannerStore.store(MOONPAY_NAME, apiResponse)
|
||||
apiResponse
|
||||
}
|
||||
promoBannerConverter.convert(response)
|
||||
}.getOrNull()
|
||||
return banner?.isActive == true
|
||||
}
|
||||
|
||||
override fun getStoryById(id: String): Flow<StoryContent?> = isReadyToShowStories(id).mapLatest {
|
||||
getStoryByIdSync(id = id, refresh = false)
|
||||
|
|
@ -136,68 +54,21 @@ internal class DefaultPromoRepository(
|
|||
}
|
||||
|
||||
override fun isReadyToShowStories(storyId: String): Flow<Boolean> {
|
||||
return appPreferencesStore.get(getShouldShowStoriesKey(storyId), true)
|
||||
return appPreferencesStore.get(PreferencesKeys.getShouldShowStoriesKey(storyId), true)
|
||||
}
|
||||
|
||||
override suspend fun isReadyToShowStoriesSync(storyId: String): Boolean {
|
||||
return appPreferencesStore.getSyncOrDefault(getShouldShowStoriesKey(storyId), true)
|
||||
return appPreferencesStore.getSyncOrDefault(PreferencesKeys.getShouldShowStoriesKey(storyId), true)
|
||||
}
|
||||
|
||||
override suspend fun setNeverToShowStories(storyId: String) {
|
||||
appPreferencesStore.store(
|
||||
key = getShouldShowStoriesKey(storyId),
|
||||
key = PreferencesKeys.getShouldShowStoriesKey(storyId),
|
||||
value = false,
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun getSepaPromoBanner(): PromoBanner? {
|
||||
return runCatching(dispatchers.io) {
|
||||
promoBannerConverter.convert(
|
||||
tangemApi.getPromoBanner(SEPA_NAME).getOrThrow(),
|
||||
)
|
||||
}.getOrNull()
|
||||
}
|
||||
|
||||
private suspend fun getVisaPromoBanner(): PromoBanner? {
|
||||
return runCatching(dispatchers.io) {
|
||||
promoBannerConverter.convert(
|
||||
tangemApi.getPromoBanner(VISA_NAME).getOrThrow(),
|
||||
)
|
||||
}.getOrNull()
|
||||
}
|
||||
|
||||
private suspend fun getBlackFridayPromoBanner(): PromoBanner? {
|
||||
return runCatching(dispatchers.io) {
|
||||
promoBannerConverter.convert(
|
||||
tangemApi.getPromoBanner(BLACK_FRIDAY_NAME).getOrThrow(),
|
||||
)
|
||||
}.getOrNull()
|
||||
}
|
||||
|
||||
private suspend fun getOnePlusOnePromoBanner(): PromoBanner? {
|
||||
return runCatching(dispatchers.io) {
|
||||
promoBannerConverter.convert(
|
||||
tangemApi.getPromoBanner(ONE_PLUS_ONE_NAME).getOrThrow(),
|
||||
)
|
||||
}.getOrNull()
|
||||
}
|
||||
|
||||
private suspend fun getYieldPromoBanner(userWalletId: UserWalletId): PromoBanner? {
|
||||
return runCatching(dispatchers.io) {
|
||||
val response = tangemApi.getPromoBannersV2(userWalletId.stringValue).getOrThrow()
|
||||
val yieldPromotion = response.promotions.find { it.name == YIELD_PROMO_NAME }
|
||||
?: return@runCatching null
|
||||
promoBannerConverter.convert(yieldPromotion)
|
||||
}.getOrNull()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val SEPA_NAME = "sepa"
|
||||
const val VISA_NAME = "visa-waitlist"
|
||||
const val BLACK_FRIDAY_NAME = "black-friday"
|
||||
const val MOONPAY_NAME = "moonpay"
|
||||
const val ONE_PLUS_ONE_NAME = "one-plus-one"
|
||||
const val YIELD_PROMO_NAME = "promo-yield"
|
||||
const val STORIES_LOAD_DELAY = 1000L
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
package com.tangem.data.promo.converters
|
||||
|
||||
import com.tangem.datasource.api.promotion.models.PromoBannerResponse
|
||||
import com.tangem.domain.promo.models.PromoBanner
|
||||
import com.tangem.utils.converter.Converter
|
||||
import org.joda.time.DateTime
|
||||
|
||||
class PromoBannerConverter : Converter<PromoBannerResponse, PromoBanner?> {
|
||||
|
||||
override fun convert(value: PromoBannerResponse): PromoBanner? {
|
||||
val bannerState = value.bannerState ?: return null
|
||||
return PromoBanner(
|
||||
name = value.name,
|
||||
bannerState = PromoBanner.BannerState(
|
||||
status = bannerState.status,
|
||||
link = bannerState.link,
|
||||
timeline = PromoBanner.Timeline(
|
||||
start = DateTime.parse(bannerState.timeline.start),
|
||||
end = DateTime.parse(bannerState.timeline.end),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,10 +3,8 @@ package com.tangem.data.promo.di
|
|||
import com.tangem.data.promo.DefaultPromoRepository
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.promo.PromoBannerStore
|
||||
import com.tangem.datasource.local.promo.PromoStoriesStore
|
||||
import com.tangem.domain.promo.PromoRepository
|
||||
import com.tangem.feature.referral.domain.ReferralRepository
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
|
|
@ -24,17 +22,13 @@ internal object PromoDataModule {
|
|||
tangemTechApi: TangemTechApi,
|
||||
appPreferencesStore: AppPreferencesStore,
|
||||
promoStoriesStore: PromoStoriesStore,
|
||||
promoBannerStore: PromoBannerStore,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
referralRepository: ReferralRepository,
|
||||
): PromoRepository {
|
||||
return DefaultPromoRepository(
|
||||
tangemApi = tangemTechApi,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
promoStoriesStore = promoStoriesStore,
|
||||
dispatchers = dispatchers,
|
||||
referralRepository = referralRepository,
|
||||
promoBannerStore = promoBannerStore,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -6,5 +6,4 @@ enum class OnrampSource(val analyticsName: String) {
|
|||
TOKEN_LONG_TAP("Long Tap"),
|
||||
TOKEN_DETAILS("Token"),
|
||||
MARKETS("Markets"),
|
||||
SEPA_BANNER("SEPA Banner"),
|
||||
}
|
||||
|
|
@ -11,11 +11,9 @@ import com.tangem.domain.onramp.repositories.OnrampRepository
|
|||
import com.tangem.domain.onramp.repositories.OnrampTransactionRepository
|
||||
import com.tangem.domain.onramp.utils.calculateRateDif
|
||||
import com.tangem.domain.onramp.utils.compareOffersByRateSpeedAndPriority
|
||||
import com.tangem.domain.promo.PromoRepository
|
||||
import com.tangem.domain.settings.repositories.SettingsRepository
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
class GetOnrampOffersUseCase(
|
||||
|
|
@ -23,16 +21,14 @@ class GetOnrampOffersUseCase(
|
|||
private val onrampTransactionRepository: OnrampTransactionRepository,
|
||||
private val errorResolver: OnrampErrorResolver,
|
||||
private val settingsRepository: SettingsRepository,
|
||||
private val promoRepository: PromoRepository,
|
||||
) {
|
||||
|
||||
operator fun invoke(): EitherFlow<OnrampError, List<OnrampOffersBlock>> {
|
||||
return combine(
|
||||
onrampRepository.getQuotes(),
|
||||
onrampTransactionRepository.getAllTransactions(),
|
||||
flow { emit(promoRepository.isMoonpayPromoActive()) },
|
||||
) { quotes, transactions, isMoonpayPromoActive ->
|
||||
processOffers(quotes, transactions, isMoonpayPromoActive)
|
||||
) { quotes, transactions ->
|
||||
processOffers(quotes, transactions)
|
||||
}
|
||||
.map { offers -> offers.right() }
|
||||
.catch { throwable -> errorResolver.resolve(throwable).left() }
|
||||
|
|
@ -41,7 +37,6 @@ class GetOnrampOffersUseCase(
|
|||
private suspend fun processOffers(
|
||||
quotes: List<OnrampQuote>,
|
||||
transactions: List<OnrampTransaction>,
|
||||
isMoonpayPromoActive: Boolean,
|
||||
): List<OnrampOffersBlock> {
|
||||
val validQuotes = quotes.filterIsInstance<OnrampQuote.Data>()
|
||||
if (validQuotes.isEmpty()) return emptyList()
|
||||
|
|
@ -62,7 +57,7 @@ class GetOnrampOffersUseCase(
|
|||
|
||||
val recentOffer = findRecentOffer(offers, transactions)
|
||||
val bestRateOffer = findBestRateOffer(offers, isGooglePayAvailable)
|
||||
val fastestOffer = findFastestOffer(offers, isGooglePayAvailable, isMoonpayPromoActive)
|
||||
val fastestOffer = findFastestOffer(offers, isGooglePayAvailable)
|
||||
|
||||
return buildOffersBlocks(
|
||||
recentOffer = recentOffer,
|
||||
|
|
@ -90,23 +85,8 @@ class GetOnrampOffersUseCase(
|
|||
return offers.maxWithOrNull(offerComparator(isGooglePayAvailable))
|
||||
}
|
||||
|
||||
private fun findFastestOffer(
|
||||
offers: List<OnrampOffer>,
|
||||
isGooglePayAvailable: Boolean,
|
||||
isMoonpayPromoActive: Boolean,
|
||||
): OnrampOffer? {
|
||||
val moonpayPromoOffers = if (isMoonpayPromoActive) {
|
||||
offers.filter { offer ->
|
||||
offer.quote.provider.id == MOONPAY_PROMO_PROVIDER_ID &&
|
||||
offer.quote.paymentMethod.type == PaymentMethodType.GOOGLE_PAY
|
||||
}
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
|
||||
val instantOffers = moonpayPromoOffers.ifEmpty {
|
||||
offers.filter { it.quote.paymentMethod.type.isInstant() }
|
||||
}
|
||||
private fun findFastestOffer(offers: List<OnrampOffer>, isGooglePayAvailable: Boolean): OnrampOffer? {
|
||||
val instantOffers = offers.filter { it.quote.paymentMethod.type.isInstant() }
|
||||
|
||||
return if (instantOffers.isNotEmpty()) {
|
||||
instantOffers.maxWithOrNull(fastestOfferComparator(isGooglePayAvailable))
|
||||
|
|
@ -308,8 +288,4 @@ class GetOnrampOffersUseCase(
|
|||
-> true
|
||||
}
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val MOONPAY_PROMO_PROVIDER_ID = "moonpay"
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,6 @@ import com.tangem.domain.onramp.model.cache.OnrampTransaction
|
|||
import com.tangem.domain.onramp.repositories.OnrampErrorResolver
|
||||
import com.tangem.domain.onramp.repositories.OnrampRepository
|
||||
import com.tangem.domain.onramp.repositories.OnrampTransactionRepository
|
||||
import com.tangem.domain.promo.PromoRepository
|
||||
import com.tangem.domain.settings.repositories.SettingsRepository
|
||||
import io.mockk.*
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
|
|
@ -25,7 +24,6 @@ class GetOnrampOffersUseCaseTest {
|
|||
private val errorResolver: OnrampErrorResolver = mockk(relaxUnitFun = true)
|
||||
private val settingsRepository: SettingsRepository = mockk(relaxUnitFun = true)
|
||||
private val cryptoCurrencyId: CryptoCurrency.ID = mockk(relaxUnitFun = true)
|
||||
private val promoRepository: PromoRepository = mockk(relaxUnitFun = true)
|
||||
|
||||
private lateinit var useCase: GetOnrampOffersUseCase
|
||||
|
||||
|
|
@ -37,7 +35,6 @@ class GetOnrampOffersUseCaseTest {
|
|||
onrampTransactionRepository = onrampTransactionRepository,
|
||||
errorResolver = errorResolver,
|
||||
settingsRepository = settingsRepository,
|
||||
promoRepository = promoRepository,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -228,7 +225,6 @@ class GetOnrampOffersUseCaseTest {
|
|||
|
||||
val transactions = emptyList<OnrampTransaction>()
|
||||
|
||||
coEvery { promoRepository.isMoonpayPromoActive() } returns false
|
||||
coEvery { settingsRepository.isGooglePayAvailability() } returns false
|
||||
coEvery { onrampRepository.getQuotes() } returns flowOf(quotes)
|
||||
coEvery { onrampTransactionRepository.getAllTransactions() } returns flowOf(
|
||||
|
|
@ -249,107 +245,6 @@ class GetOnrampOffersUseCaseTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `invoke should fallback to standard instant offers when promo is active but no Moonpay offers exist`() =
|
||||
runTest {
|
||||
val instantMethod = createMockPaymentMethod("gpay", "Google Pay", PaymentMethodType.GOOGLE_PAY)
|
||||
val slowMethod = createMockPaymentMethod("bank", "Bank Transfer", PaymentMethodType.CARD)
|
||||
val provider = createMockProvider("other", "Other Provider")
|
||||
|
||||
val quotes = listOf(
|
||||
createMockQuote(instantMethod, provider, BigDecimal("95.0")),
|
||||
createMockQuote(slowMethod, provider, BigDecimal("100.0")),
|
||||
)
|
||||
|
||||
val transactions = emptyList<OnrampTransaction>()
|
||||
|
||||
coEvery { promoRepository.isMoonpayPromoActive() } returns true
|
||||
coEvery { settingsRepository.isGooglePayAvailability() } returns true
|
||||
coEvery { onrampRepository.getQuotes() } returns flowOf(quotes)
|
||||
coEvery { onrampTransactionRepository.getAllTransactions() } returns flowOf(transactions)
|
||||
|
||||
val result = useCase()
|
||||
|
||||
result.collect { either ->
|
||||
Truth.assertThat(either.isRight()).isTrue()
|
||||
either.fold(
|
||||
ifLeft = { error -> Truth.assertThat(error).isNull() },
|
||||
ifRight = { offers ->
|
||||
Truth.assertThat(offers).hasSize(1)
|
||||
|
||||
val recommendedBlock = offers.find { it.category == OnrampOfferCategory.Recommended }
|
||||
Truth.assertThat(recommendedBlock).isNotNull()
|
||||
Truth.assertThat(recommendedBlock?.offers).hasSize(2)
|
||||
|
||||
val fastestOffer =
|
||||
recommendedBlock?.offers?.find { it.advantages == OnrampOfferAdvantages.Fastest }
|
||||
Truth.assertThat(fastestOffer).isNotNull()
|
||||
|
||||
when (val quote = fastestOffer?.quote) {
|
||||
is OnrampQuote.Data -> {
|
||||
Truth.assertThat(quote.provider.id).isNotEqualTo("moonpay")
|
||||
Truth.assertThat(quote.paymentMethod.type).isEqualTo(PaymentMethodType.GOOGLE_PAY)
|
||||
}
|
||||
else -> Truth.assertThat(false).isTrue()
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `invoke should show Moonpay fastest offer when promo is active`() = runTest {
|
||||
val moonpayGooglePayMethod = createMockPaymentMethod("moonpay-gpay", "Google Pay", PaymentMethodType.GOOGLE_PAY)
|
||||
val otherGooglePayMethod = createMockPaymentMethod(
|
||||
"other-gpay",
|
||||
"Other Google Pay",
|
||||
PaymentMethodType.GOOGLE_PAY,
|
||||
)
|
||||
val slowMethod = createMockPaymentMethod("bank", "Bank Transfer", PaymentMethodType.CARD)
|
||||
val moonpayProvider = createMockProvider("moonpay", "Moonpay")
|
||||
val otherProvider = createMockProvider("other", "Other Provider")
|
||||
|
||||
val quotes = listOf(
|
||||
createMockQuote(moonpayGooglePayMethod, moonpayProvider, BigDecimal("100.0")),
|
||||
createMockQuote(otherGooglePayMethod, otherProvider, BigDecimal("95.0")),
|
||||
createMockQuote(slowMethod, otherProvider, BigDecimal("105.0")),
|
||||
)
|
||||
|
||||
val transactions = emptyList<OnrampTransaction>()
|
||||
|
||||
coEvery { promoRepository.isMoonpayPromoActive() } returns true
|
||||
coEvery { settingsRepository.isGooglePayAvailability() } returns true
|
||||
coEvery { onrampRepository.getQuotes() } returns flowOf(quotes)
|
||||
coEvery { onrampTransactionRepository.getAllTransactions() } returns flowOf(transactions)
|
||||
|
||||
val result = useCase()
|
||||
|
||||
result.collect { either ->
|
||||
Truth.assertThat(either.isRight()).isTrue()
|
||||
either.fold(
|
||||
ifLeft = { error -> Truth.assertThat(error).isNull() },
|
||||
ifRight = { offers ->
|
||||
Truth.assertThat(offers).hasSize(1)
|
||||
|
||||
val recommendedBlock = offers.find { it.category == OnrampOfferCategory.Recommended }
|
||||
Truth.assertThat(recommendedBlock).isNotNull()
|
||||
|
||||
val fastestOffer = recommendedBlock?.offers?.find { it.advantages == OnrampOfferAdvantages.Fastest }
|
||||
Truth.assertThat(fastestOffer).isNotNull()
|
||||
|
||||
when (val quote = fastestOffer?.quote) {
|
||||
is OnrampQuote.Data -> {
|
||||
Truth.assertThat(quote.provider.id).isEqualTo("moonpay")
|
||||
Truth.assertThat(quote.paymentMethod.type).isEqualTo(PaymentMethodType.GOOGLE_PAY)
|
||||
Truth.assertThat(quote.toAmount.value).isEqualTo(BigDecimal("100.0"))
|
||||
}
|
||||
else -> Truth.assertThat(false).isTrue()
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createMockPaymentMethod(
|
||||
id: String,
|
||||
name: String,
|
||||
|
|
|
|||
|
|
@ -5,5 +5,4 @@ plugins {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation(deps.jodatime)
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
package com.tangem.domain.promo.models
|
||||
|
||||
import org.joda.time.DateTime
|
||||
|
||||
data class PromoBanner(
|
||||
val name: String,
|
||||
val bannerState: BannerState,
|
||||
) {
|
||||
|
||||
val isActive = bannerState.status == ACTIVE_STATUS && bannerState.timeline.end.isAfterNow
|
||||
|
||||
data class BannerState(
|
||||
val timeline: Timeline,
|
||||
val status: String,
|
||||
val link: String?,
|
||||
)
|
||||
|
||||
data class Timeline(
|
||||
val start: DateTime,
|
||||
val end: DateTime,
|
||||
)
|
||||
|
||||
private companion object {
|
||||
const val ACTIVE_STATUS = "active"
|
||||
}
|
||||
}
|
||||
|
||||
enum class PromoId {
|
||||
Referral,
|
||||
Sepa,
|
||||
VisaPresale,
|
||||
BlackFriday,
|
||||
OnePlusOne,
|
||||
YieldPromo,
|
||||
}
|
||||
|
|
@ -1,24 +1,10 @@
|
|||
package com.tangem.domain.promo
|
||||
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.promo.models.PromoId
|
||||
import com.tangem.domain.promo.models.StoryContent
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface PromoRepository {
|
||||
|
||||
// region Promo
|
||||
fun isReadyToShowWalletPromo(userWalletId: UserWalletId, promoId: PromoId): Flow<Boolean>
|
||||
|
||||
fun isReadyToShowTokenPromo(promoId: PromoId): Flow<Boolean>
|
||||
|
||||
suspend fun setNeverToShowWalletPromo(promoId: PromoId)
|
||||
|
||||
suspend fun setNeverToShowTokenPromo(promoId: PromoId)
|
||||
|
||||
suspend fun isMoonpayPromoActive(): Boolean
|
||||
// endregion
|
||||
|
||||
// region Stories
|
||||
fun getStoryById(id: String): Flow<StoryContent?>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
package com.tangem.domain.promo
|
||||
|
||||
import com.tangem.domain.promo.models.PromoId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
class ShouldShowPromoTokenUseCase(private val promoRepository: PromoRepository) {
|
||||
|
||||
operator fun invoke(promoId: PromoId): Flow<Boolean> = promoRepository.isReadyToShowTokenPromo(promoId)
|
||||
|
||||
suspend fun neverToShow(promoId: PromoId) = promoRepository.setNeverToShowTokenPromo(promoId)
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
package com.tangem.domain.promo
|
||||
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.promo.models.PromoId
|
||||
import com.tangem.domain.settings.repositories.SettingsRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.emitAll
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.map
|
||||
import java.util.Calendar
|
||||
|
||||
class ShouldShowPromoWalletUseCase(
|
||||
private val promoRepository: PromoRepository,
|
||||
private val settingsRepository: SettingsRepository,
|
||||
private val isNewPromoBannersEnabled: Boolean,
|
||||
) {
|
||||
|
||||
operator fun invoke(userWalletId: UserWalletId, promoId: PromoId): Flow<Boolean> {
|
||||
if (isNewPromoBannersEnabled) return flowOf(false)
|
||||
|
||||
return flow {
|
||||
emit(false)
|
||||
|
||||
val promoFlow = promoRepository.isReadyToShowWalletPromo(userWalletId, promoId)
|
||||
.map { applyWalletFirstUsageCondition(promoId, it) }
|
||||
|
||||
emitAll(promoFlow)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun applyWalletFirstUsageCondition(promoId: PromoId, isReady: Boolean): Boolean {
|
||||
if (!isReady) return false
|
||||
|
||||
return when (promoId) {
|
||||
PromoId.Referral,
|
||||
PromoId.VisaPresale,
|
||||
PromoId.BlackFriday,
|
||||
PromoId.OnePlusOne,
|
||||
PromoId.YieldPromo,
|
||||
-> true
|
||||
PromoId.Sepa -> {
|
||||
val walletFirstUsageDate = settingsRepository.getWalletFirstUsageDate()
|
||||
if (walletFirstUsageDate == 0L) return false
|
||||
|
||||
val currentDate = Calendar.getInstance().timeInMillis
|
||||
currentDate - walletFirstUsageDate > ONE_DAY_IN_MILLIS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun neverToShow(promoId: PromoId) = promoRepository.setNeverToShowWalletPromo(promoId)
|
||||
|
||||
private companion object {
|
||||
const val ONE_DAY_IN_MILLIS = 1 * 24 * 60 * 60 * 1000L
|
||||
}
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
package com.tangem.domain.tokens.model.analytics
|
||||
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
|
||||
sealed class PromoAnalyticsEvent(
|
||||
event: String,
|
||||
params: Map<String, String> = emptyMap(),
|
||||
) : AnalyticsEvent(category = "Promotion", event = event, params = params) {
|
||||
data class NoticePromotionBanner(
|
||||
private val source: AnalyticsParam.ScreensSources,
|
||||
private val program: Program,
|
||||
) : PromoAnalyticsEvent(
|
||||
event = "Notice - Promotion Banner",
|
||||
params = mapOf(
|
||||
AnalyticsParam.SOURCE to source.value,
|
||||
"Program Name" to program.programName,
|
||||
),
|
||||
)
|
||||
|
||||
data class PromotionBannerClicked(
|
||||
private val source: AnalyticsParam.ScreensSources,
|
||||
private val program: Program,
|
||||
private val action: BannerAction,
|
||||
) : PromoAnalyticsEvent(
|
||||
event = "Promo Banner Clicked",
|
||||
params = mapOf(
|
||||
AnalyticsParam.SOURCE to source.value,
|
||||
"Program Name" to program.programName,
|
||||
"Action" to action.action,
|
||||
),
|
||||
) {
|
||||
sealed class BannerAction(val action: String) {
|
||||
class Clicked : BannerAction(action = "Clicked")
|
||||
class Closed : BannerAction(action = "Closed")
|
||||
}
|
||||
}
|
||||
|
||||
// region visa waitlist promo
|
||||
class VisaWaitlistPromo : PromoAnalyticsEvent(event = "Visa Waitlist")
|
||||
|
||||
class VisaWaitlistPromoJoin : PromoAnalyticsEvent(
|
||||
event = "Button - Join Now",
|
||||
params = mapOf(
|
||||
"Program Name" to "Visa Waitlist",
|
||||
),
|
||||
)
|
||||
|
||||
class VisaWaitlistPromoDismiss : PromoAnalyticsEvent(
|
||||
event = "Button - Close",
|
||||
params = mapOf(
|
||||
"Program Name" to "Visa Waitlist",
|
||||
),
|
||||
)
|
||||
//endregion
|
||||
|
||||
// Use it on new promo action
|
||||
enum class Program(val programName: String) {
|
||||
Empty("Empty"),
|
||||
Sepa("Sepa"),
|
||||
BlackFriday("Black Friday"),
|
||||
OnePlusOne("One-Plus-One"),
|
||||
YieldPromo("Yield Promo"),
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
package com.tangem.domain.tokens.model.warnings
|
||||
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.promo.models.PromoId
|
||||
import org.joda.time.DateTime
|
||||
import java.math.BigDecimal
|
||||
|
||||
sealed class CryptoCurrencyWarning {
|
||||
|
|
@ -47,12 +45,6 @@ sealed class CryptoCurrencyWarning {
|
|||
val cryptoCurrency: CryptoCurrency,
|
||||
) : CryptoCurrencyWarning()
|
||||
|
||||
data class SwapPromo(
|
||||
val promoId: PromoId,
|
||||
val startDateTime: DateTime,
|
||||
val endDateTime: DateTime,
|
||||
) : CryptoCurrencyWarning()
|
||||
|
||||
data object BeaconChainShutdown : CryptoCurrencyWarning()
|
||||
|
||||
data object MigrationMaticToPol : CryptoCurrencyWarning()
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ import com.tangem.features.feed.components.market.list.DefaultMarketsTokenListCo
|
|||
import com.tangem.features.feed.components.news.details.DefaultNewsDetailsComponent
|
||||
import com.tangem.features.feed.components.news.list.DefaultNewsListComponent
|
||||
import com.tangem.features.feed.components.search.DefaultSearchComponent
|
||||
import com.tangem.features.promobanners.api.NewPromoBannersFeatureToggles
|
||||
import com.tangem.features.promobanners.api.PromoBannersBlockComponent
|
||||
import kotlinx.serialization.Serializable
|
||||
import javax.inject.Inject
|
||||
|
|
@ -30,7 +29,6 @@ internal class FeedEntryChildFactory @Inject constructor(
|
|||
private val portfolioBlockComponentFactory: PortfolioBlockComponent.Factory,
|
||||
private val addToPortfolioComponentFactory: AddToPortfolioComponent.Factory,
|
||||
private val promoBannersBlockComponentFactory: PromoBannersBlockComponent.Factory,
|
||||
private val newPromoBannersFeatureToggles: NewPromoBannersFeatureToggles,
|
||||
private val designFeatureToggles: DesignFeatureToggles,
|
||||
) {
|
||||
|
||||
|
|
@ -121,7 +119,6 @@ internal class FeedEntryChildFactory @Inject constructor(
|
|||
params = FeedParams(feedClickIntents = feedEntryClickIntents),
|
||||
addToPortfolioComponentFactory = addToPortfolioComponentFactory,
|
||||
promoBannersBlockComponentFactory = promoBannersBlockComponentFactory,
|
||||
newPromoBannersFeatureToggles = newPromoBannersFeatureToggles,
|
||||
)
|
||||
}
|
||||
is Child.Earn -> {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import com.tangem.features.feed.model.feed.FeedComponentModel
|
|||
import com.tangem.features.feed.model.feed.FeedModelClickIntents
|
||||
import com.tangem.features.feed.ui.feed.FeedList
|
||||
import com.tangem.features.feed.ui.feed.FeedListHeader
|
||||
import com.tangem.features.promobanners.api.NewPromoBannersFeatureToggles
|
||||
import com.tangem.features.promobanners.api.PromoBannersBlockComponent
|
||||
|
||||
internal class DefaultFeedComponent(
|
||||
|
|
@ -32,13 +31,11 @@ internal class DefaultFeedComponent(
|
|||
private val params: FeedParams,
|
||||
private val addToPortfolioComponentFactory: AddToPortfolioComponent.Factory,
|
||||
private val promoBannersBlockComponentFactory: PromoBannersBlockComponent.Factory,
|
||||
private val newPromoBannersFeatureToggles: NewPromoBannersFeatureToggles,
|
||||
) : ComposableModularBottomSheetContentComponent, AppComponentContext by appComponentContext {
|
||||
|
||||
private val feedComponentModel = getOrCreateModel<FeedComponentModel, FeedParams>(params = params)
|
||||
|
||||
private val promoBannersBlockComponent: PromoBannersBlockComponent? by lazy {
|
||||
if (!newPromoBannersFeatureToggles.isNewPromoBannersEnabled) return@lazy null
|
||||
private val promoBannersBlockComponent: PromoBannersBlockComponent by lazy {
|
||||
promoBannersBlockComponentFactory.create(
|
||||
context = child("promoBannersBlockComponent"),
|
||||
params = PromoBannersBlockComponent.Params(
|
||||
|
|
@ -72,7 +69,7 @@ internal class DefaultFeedComponent(
|
|||
) {
|
||||
val isExpanded = bottomSheetState.value == BottomSheetState.EXPANDED
|
||||
LaunchedEffect(isExpanded) {
|
||||
promoBannersBlockComponent?.setVisibleOnScreen(isExpanded)
|
||||
promoBannersBlockComponent.setVisibleOnScreen(isExpanded)
|
||||
}
|
||||
|
||||
LifecycleStartEffect(Unit) {
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
package com.tangem.features.promobanners.api
|
||||
|
||||
interface NewPromoBannersFeatureToggles {
|
||||
val isNewPromoBannersEnabled: Boolean
|
||||
}
|
||||
|
|
@ -4,13 +4,11 @@ import com.tangem.core.decompose.di.ModelComponent
|
|||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.local.datastore.RuntimeSharedStore
|
||||
import com.tangem.features.promobanners.api.NewPromoBannersFeatureToggles
|
||||
import com.tangem.features.promobanners.api.PromoBannersBlockComponent
|
||||
import com.tangem.features.promobanners.impl.DefaultPromoBannersBlockComponent
|
||||
import com.tangem.features.promobanners.impl.model.PromoBannersBlockModel
|
||||
import com.tangem.features.promobanners.impl.repository.DefaultPromoBannersRepository
|
||||
import com.tangem.features.promobanners.impl.repository.PromoBannersRepository
|
||||
import com.tangem.features.promobanners.impl.toggles.DefaultNewPromoBannersFeatureToggles
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
|
|
@ -31,10 +29,6 @@ internal interface PromoBannersFeatureModule {
|
|||
factory: DefaultPromoBannersBlockComponent.Factory,
|
||||
): PromoBannersBlockComponent.Factory
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindFeatureToggles(impl: DefaultNewPromoBannersFeatureToggles): NewPromoBannersFeatureToggles
|
||||
|
||||
companion object {
|
||||
|
||||
@Provides
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
package com.tangem.features.promobanners.impl.toggles
|
||||
|
||||
import com.tangem.core.configtoggle.FeatureToggles
|
||||
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||
import com.tangem.features.promobanners.api.NewPromoBannersFeatureToggles
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class DefaultNewPromoBannersFeatureToggles @Inject constructor(
|
||||
private val featureTogglesManager: FeatureTogglesManager,
|
||||
) : NewPromoBannersFeatureToggles {
|
||||
|
||||
override val isNewPromoBannersEnabled: Boolean
|
||||
get() = featureTogglesManager.isFeatureEnabled(toggle = FeatureToggles.NEW_PROMO_BANNERS_ENABLED)
|
||||
}
|
||||
|
|
@ -2,9 +2,7 @@ package com.tangem.feature.tokendetails.presentation.tokendetails.analytics
|
|||
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.analytics.PromoAnalyticsEvent
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsNotification
|
||||
import com.tangem.features.yield.supply.api.analytics.YieldSupplyAnalytics
|
||||
|
|
@ -39,10 +37,6 @@ internal class TokenDetailsNotificationsAnalyticsSender(
|
|||
currency = cryptoCurrency,
|
||||
source = TokenDetailsAnalyticsEvent.Notice.NotEnoughFee.Source.DetailedScreen,
|
||||
)
|
||||
is TokenDetailsNotification.SwapPromo -> PromoAnalyticsEvent.NoticePromotionBanner(
|
||||
program = PromoAnalyticsEvent.Program.Empty, // Use it on new promo action
|
||||
source = AnalyticsParam.ScreensSources.Token,
|
||||
)
|
||||
is TokenDetailsNotification.KaspaIncompleteTransactionWarning -> TokenDetailsAnalyticsEvent.Notice.Reveal(
|
||||
currency = cryptoCurrency,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package com.tangem.feature.tokendetails.presentation.tokendetails.model
|
|||
import com.tangem.common.ui.bottomsheet.receive.AddressModel
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.promo.models.PromoId
|
||||
import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenBalanceSegmentedButtonConfig
|
||||
|
||||
|
|
@ -42,10 +41,6 @@ interface TokenDetailsClickIntents {
|
|||
|
||||
fun onCloseRentInfoNotification()
|
||||
|
||||
fun onSwapPromoDismiss(promoId: PromoId)
|
||||
|
||||
fun onSwapPromoClick(promoId: PromoId)
|
||||
|
||||
fun onGenerateExtendedKey()
|
||||
|
||||
fun onDynamicAddressesClick()
|
||||
|
|
@ -143,10 +138,6 @@ internal class EmptyTokenDetailsClickIntents : TokenDetailsClickIntents {
|
|||
|
||||
override fun onCloseRentInfoNotification() { /* no op */ }
|
||||
|
||||
override fun onSwapPromoDismiss(promoId: PromoId) { /* no op */ }
|
||||
|
||||
override fun onSwapPromoClick(promoId: PromoId) { /* no op */ }
|
||||
|
||||
override fun onRetryIncompleteTransactionClick() { /* no op */ }
|
||||
|
||||
override fun onOpenTrustlineClick() { /* no op */ }
|
||||
|
|
|
|||
|
|
@ -58,15 +58,12 @@ import com.tangem.domain.models.wallet.UserWallet
|
|||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.offramp.GetOfframpUrlUseCase
|
||||
import com.tangem.domain.onramp.model.OnrampSource
|
||||
import com.tangem.domain.promo.ShouldShowPromoTokenUseCase
|
||||
import com.tangem.domain.promo.models.PromoId
|
||||
import com.tangem.domain.staking.GetStakingAvailabilityUseCase
|
||||
import com.tangem.domain.staking.GetStakingEntryInfoUseCase
|
||||
import com.tangem.domain.staking.model.StakingAvailability
|
||||
import com.tangem.domain.tokens.*
|
||||
import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason
|
||||
import com.tangem.domain.tokens.model.TokenActionsState
|
||||
import com.tangem.domain.tokens.model.analytics.PromoAnalyticsEvent
|
||||
import com.tangem.domain.tokens.model.analytics.TokenReceiveCopyActionSource
|
||||
import com.tangem.domain.tokens.model.analytics.TokenReceiveNewAnalyticsEvent
|
||||
import com.tangem.domain.tokens.model.analytics.TokenScreenAnalyticsEvent
|
||||
|
|
@ -136,7 +133,6 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
private val getCurrencyWarningsUseCase: GetCurrencyWarningsUseCase,
|
||||
private val getExplorerTransactionUrlUseCase: GetExplorerTransactionUrlUseCase,
|
||||
private val shouldShowPromoTokenUseCase: ShouldShowPromoTokenUseCase,
|
||||
private val getExtendedPublicKeyForCurrencyUseCase: GetExtendedPublicKeyForCurrencyUseCase,
|
||||
private val getStakingEntryInfoUseCase: GetStakingEntryInfoUseCase,
|
||||
private val getStakingAvailabilityUseCase: GetStakingAvailabilityUseCase,
|
||||
|
|
@ -829,33 +825,6 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
uiState.value = stateFactory.getStateWithRemovedRentNotification()
|
||||
}
|
||||
|
||||
override fun onSwapPromoDismiss(promoId: PromoId) {
|
||||
modelScope.launch(dispatchers.main) {
|
||||
shouldShowPromoTokenUseCase.neverToShow(promoId)
|
||||
analyticsEventsHandler.send(
|
||||
PromoAnalyticsEvent.PromotionBannerClicked(
|
||||
source = AnalyticsParam.ScreensSources.Token,
|
||||
program = PromoAnalyticsEvent.Program.Empty, // Use it on new promo action
|
||||
action = PromoAnalyticsEvent.PromotionBannerClicked.BannerAction.Closed(),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSwapPromoClick(promoId: PromoId) {
|
||||
modelScope.launch(dispatchers.main) {
|
||||
shouldShowPromoTokenUseCase.neverToShow(promoId)
|
||||
analyticsEventsHandler.send(
|
||||
PromoAnalyticsEvent.PromotionBannerClicked(
|
||||
source = AnalyticsParam.ScreensSources.Token,
|
||||
program = PromoAnalyticsEvent.Program.Empty, // Use it on new promo action
|
||||
action = PromoAnalyticsEvent.PromotionBannerClicked.BannerAction.Clicked(),
|
||||
),
|
||||
)
|
||||
}
|
||||
onSwapClick(ScenarioUnavailabilityReason.None)
|
||||
}
|
||||
|
||||
override fun onCopyAddress(): TextReference? {
|
||||
val networkAddress = cryptoCurrencyStatus?.value?.networkAddress ?: return null
|
||||
val addresses = networkAddress.availableAddresses.mapToAddressModels(cryptoCurrency).toImmutableList()
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import com.tangem.domain.models.currency.CryptoCurrency
|
|||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
|
||||
import com.tangem.features.tokendetails.impl.R
|
||||
import org.joda.time.DateTime
|
||||
|
||||
@Immutable
|
||||
internal sealed class TokenDetailsNotification(val config: NotificationConfig) {
|
||||
|
|
@ -47,24 +46,6 @@ internal sealed class TokenDetailsNotification(val config: NotificationConfig) {
|
|||
),
|
||||
)
|
||||
|
||||
data class SwapPromo(
|
||||
val startDateTime: DateTime,
|
||||
val endDateTime: DateTime,
|
||||
val onSwapClick: () -> Unit,
|
||||
val onCloseClick: () -> Unit,
|
||||
) : TokenDetailsNotification(
|
||||
config = NotificationConfig(
|
||||
title = resourceReference(id = R.string.swap_promo_title),
|
||||
subtitle = resourceReference(id = R.string.swap_promo_text),
|
||||
iconResId = R.drawable.img_okx_dex_logo,
|
||||
onCloseClick = onCloseClick,
|
||||
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
||||
text = resourceReference(id = com.tangem.core.ui.R.string.token_swap_promotion_button),
|
||||
onClick = onSwapClick,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
data object NetworksUnreachable : Warning(
|
||||
title = resourceReference(R.string.warning_network_unreachable_title),
|
||||
subtitle = resourceReference(R.string.warning_network_unreachable_message),
|
||||
|
|
|
|||
|
|
@ -108,12 +108,6 @@ internal class TokenDetailsNotificationConverter(
|
|||
symbol = warning.amountCurrency.network.currencySymbol,
|
||||
)
|
||||
is CryptoCurrencyWarning.TopUpWithoutReserve -> TopUpWithoutReserve
|
||||
is CryptoCurrencyWarning.SwapPromo -> SwapPromo(
|
||||
startDateTime = warning.startDateTime,
|
||||
endDateTime = warning.endDateTime,
|
||||
onSwapClick = { clickIntents.onSwapPromoClick(warning.promoId) },
|
||||
onCloseClick = { clickIntents.onSwapPromoDismiss(warning.promoId) },
|
||||
)
|
||||
is CryptoCurrencyWarning.BeaconChainShutdown -> NetworkShutdown(
|
||||
title = resourceReference(R.string.warning_beacon_chain_retirement_title),
|
||||
subtitle = resourceReference(R.string.warning_beacon_chain_retirement_content),
|
||||
|
|
|
|||
|
|
@ -184,7 +184,6 @@ internal class UpdateNotificationsTransformer(
|
|||
is CryptoCurrencyWarning.Rent,
|
||||
is CryptoCurrencyWarning.SomeNetworksNoAccount,
|
||||
is CryptoCurrencyWarning.TopUpWithoutReserve,
|
||||
is CryptoCurrencyWarning.SwapPromo,
|
||||
is CryptoCurrencyWarning.FeeResourceInfo,
|
||||
is CryptoCurrencyWarning.UsedOutdatedDataWarning,
|
||||
-> null
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ import com.tangem.feature.wallet.presentation.wallet.ui.components.visa.KycRejec
|
|||
import com.tangem.feature.walletsettings.component.RenameWalletComponent
|
||||
import com.tangem.features.biometry.AskBiometryComponent
|
||||
import com.tangem.features.feed.entry.components.FeedEntryComponent
|
||||
import com.tangem.features.promobanners.api.NewPromoBannersFeatureToggles
|
||||
import com.tangem.features.promobanners.api.PromoBannersBlockComponent
|
||||
import com.tangem.features.pushnotifications.api.PushNotificationsBottomSheetComponent
|
||||
import com.tangem.features.pushnotifications.api.PushNotificationsParams
|
||||
|
|
@ -63,7 +62,6 @@ internal class WalletComponent @AssistedInject constructor(
|
|||
private val tokenReceiveComponentFactory: TokenReceiveComponent.Factory,
|
||||
private val yieldSupplyDepositedWarningComponent: YieldSupplyDepositedWarningComponent.Factory,
|
||||
private val promoBannersBlockComponentFactory: PromoBannersBlockComponent.Factory,
|
||||
private val newPromoBannersFeatureToggles: NewPromoBannersFeatureToggles,
|
||||
private val networkSelectionComponentFactory: NetworkSelectionComponent.Factory,
|
||||
private val tokenActionsComponentFactory: TokenActionsComponent.Factory,
|
||||
private val portfolioSelectorComponentFactory: PortfolioSelectorComponent.Factory,
|
||||
|
|
@ -85,8 +83,7 @@ internal class WalletComponent @AssistedInject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private val promoBannersBlockComponent: PromoBannersBlockComponent? by lazy {
|
||||
if (!newPromoBannersFeatureToggles.isNewPromoBannersEnabled) return@lazy null
|
||||
private val promoBannersBlockComponent: PromoBannersBlockComponent by lazy {
|
||||
promoBannersBlockComponentFactory.create(
|
||||
context = child("promoBannersBlockComponent"),
|
||||
params = PromoBannersBlockComponent.Params(
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import com.tangem.core.analytics.models.event.AssetsDiscoveryAnalyticsEvent
|
|||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.navigation.review.ReviewManager
|
||||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.domain.assetsdiscovery.usecase.AcknowledgeAssetsDiscoveryCompletionUseCase
|
||||
import com.tangem.domain.card.SetCardWasScannedUseCase
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
|
|
@ -29,17 +28,11 @@ import com.tangem.domain.models.wallet.requireColdWallet
|
|||
import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher
|
||||
import com.tangem.domain.notifications.SetShouldShowNotificationUseCase
|
||||
import com.tangem.domain.notifications.repository.NotificationsRepository
|
||||
import com.tangem.domain.onramp.model.OnrampSource
|
||||
import com.tangem.domain.promo.ShouldShowPromoWalletUseCase
|
||||
import com.tangem.domain.promo.models.PromoId
|
||||
import com.tangem.domain.quotes.multi.MultiQuoteStatusFetcher
|
||||
import com.tangem.domain.settings.NeverToSuggestRateAppUseCase
|
||||
import com.tangem.domain.settings.RemindToRateAppLaterUseCase
|
||||
import com.tangem.domain.staking.StakingIdFactory
|
||||
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.tokens.model.details.NavigationAction
|
||||
import com.tangem.domain.wallets.usecase.*
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent
|
||||
|
|
@ -75,10 +68,6 @@ internal interface WalletWarningsClickIntents {
|
|||
|
||||
fun onCloseRateAppWarningClick()
|
||||
|
||||
fun onClosePromoClick(promoId: PromoId)
|
||||
|
||||
fun onPromoClick(promoId: PromoId, cryptoCurrency: CryptoCurrency? = null)
|
||||
|
||||
fun onSupportClick()
|
||||
|
||||
fun onBackupErrorClick()
|
||||
|
|
@ -91,8 +80,6 @@ internal interface WalletWarningsClickIntents {
|
|||
|
||||
fun onFinishWalletActivationClick(isBackupExists: Boolean)
|
||||
|
||||
fun onYieldPromoTermsAndConditionsClick()
|
||||
|
||||
fun onUpgradeHotWalletClick(userWalletId: UserWalletId)
|
||||
|
||||
fun onCloseUpgradeBannerClick(userWalletId: UserWalletId)
|
||||
|
|
@ -115,10 +102,8 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
private val nonBiometricUnlockWalletUseCase: NonBiometricUnlockWalletUseCase,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val shouldShowPromoWalletUseCase: ShouldShowPromoWalletUseCase,
|
||||
private val getWalletMetaInfoUseCase: GetWalletMetaInfoUseCase,
|
||||
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
|
||||
private val urlOpener: UrlOpener,
|
||||
private val multiNetworkStatusFetcher: MultiNetworkStatusFetcher,
|
||||
private val multiQuoteStatusFetcher: MultiQuoteStatusFetcher,
|
||||
private val multiStakingBalanceFetcher: MultiStakingBalanceFetcher,
|
||||
|
|
@ -243,91 +228,6 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun onClosePromoClick(promoId: PromoId) {
|
||||
analyticsEventHandler.send(
|
||||
when (promoId) {
|
||||
PromoId.Referral -> MainScreen.ReferralPromoButtonDismiss()
|
||||
PromoId.Sepa -> PromotionBannerClicked(
|
||||
source = AnalyticsParam.ScreensSources.Main,
|
||||
program = Program.Sepa,
|
||||
action = PromotionBannerClicked.BannerAction.Closed(),
|
||||
)
|
||||
PromoId.VisaPresale -> PromoAnalyticsEvent.VisaWaitlistPromoDismiss()
|
||||
PromoId.BlackFriday -> PromotionBannerClicked(
|
||||
source = AnalyticsParam.ScreensSources.Main,
|
||||
program = Program.BlackFriday,
|
||||
action = PromotionBannerClicked.BannerAction.Closed(),
|
||||
)
|
||||
PromoId.OnePlusOne -> PromotionBannerClicked(
|
||||
source = AnalyticsParam.ScreensSources.Main,
|
||||
program = Program.OnePlusOne,
|
||||
action = PromotionBannerClicked.BannerAction.Closed(),
|
||||
)
|
||||
PromoId.YieldPromo -> PromotionBannerClicked(
|
||||
source = AnalyticsParam.ScreensSources.Main,
|
||||
program = Program.YieldPromo,
|
||||
action = PromotionBannerClicked.BannerAction.Closed(),
|
||||
)
|
||||
},
|
||||
)
|
||||
modelScope.launch(dispatchers.main) {
|
||||
shouldShowPromoWalletUseCase.neverToShow(promoId)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPromoClick(promoId: PromoId, cryptoCurrency: CryptoCurrency?) {
|
||||
val userWallet = getSelectedUserWallet() ?: return
|
||||
when (promoId) {
|
||||
PromoId.Referral -> {
|
||||
analyticsEventHandler.send(MainScreen.ReferralPromoButtonParticipate())
|
||||
appRouter.push(ReferralProgram(userWalletId = userWallet.walletId))
|
||||
}
|
||||
PromoId.Sepa -> {
|
||||
analyticsEventHandler.send(
|
||||
PromotionBannerClicked(
|
||||
source = AnalyticsParam.ScreensSources.Main,
|
||||
program = Program.Sepa,
|
||||
action = PromotionBannerClicked.BannerAction.Clicked(),
|
||||
),
|
||||
)
|
||||
cryptoCurrency ?: return
|
||||
appRouter.push(
|
||||
Onramp(
|
||||
userWalletId = userWallet.walletId,
|
||||
currency = cryptoCurrency,
|
||||
source = OnrampSource.SEPA_BANNER,
|
||||
shouldLaunchSepa = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
PromoId.VisaPresale -> {
|
||||
analyticsEventHandler.send(PromoAnalyticsEvent.VisaWaitlistPromoJoin())
|
||||
urlOpener.openUrl(VISA_PROMO_LINK)
|
||||
}
|
||||
PromoId.BlackFriday -> {
|
||||
analyticsEventHandler.send(
|
||||
PromotionBannerClicked(
|
||||
source = AnalyticsParam.ScreensSources.Main,
|
||||
program = Program.BlackFriday,
|
||||
action = PromotionBannerClicked.BannerAction.Clicked(),
|
||||
),
|
||||
)
|
||||
urlOpener.openUrl(BLACK_FRIDAY_PROMO_LINK)
|
||||
}
|
||||
PromoId.OnePlusOne -> {
|
||||
analyticsEventHandler.send(
|
||||
PromotionBannerClicked(
|
||||
source = AnalyticsParam.ScreensSources.Main,
|
||||
program = Program.OnePlusOne,
|
||||
action = PromotionBannerClicked.BannerAction.Clicked(),
|
||||
),
|
||||
)
|
||||
urlOpener.openUrl(ONE_PLUS_ONE_PROMO_LINK)
|
||||
}
|
||||
PromoId.YieldPromo -> Unit // banner is not clickable, only terms and conditions button
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSupportClick() {
|
||||
val userWallet = getSelectedUserWallet() ?: return
|
||||
|
||||
|
|
@ -478,17 +378,6 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun onYieldPromoTermsAndConditionsClick() {
|
||||
analyticsEventHandler.send(
|
||||
PromotionBannerClicked(
|
||||
source = AnalyticsParam.ScreensSources.Main,
|
||||
program = Program.YieldPromo,
|
||||
action = PromotionBannerClicked.BannerAction.Clicked(),
|
||||
),
|
||||
)
|
||||
urlOpener.openUrl(YIELD_PROMO_TERMS_LINK)
|
||||
}
|
||||
|
||||
override fun onUpgradeHotWalletClick(userWalletId: UserWalletId) {
|
||||
modelScope.launch(dispatchers.main) {
|
||||
val userWallet = getUserWalletUseCase(userWalletId).getOrNull()
|
||||
|
|
@ -519,21 +408,4 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
AccountId.forMainCryptoPortfolio(userWalletId),
|
||||
)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val VISA_PROMO_LINK = "https://tangem.com/en/cardwaitlist/?utm_source=tangem-app-banner" +
|
||||
"&utm_medium=banner" +
|
||||
"&utm_campaign=tangempaywaitlist"
|
||||
const val BLACK_FRIDAY_PROMO_LINK = "https://tangem.com/en/pricing/" +
|
||||
"?promocode=BF2025" +
|
||||
"&utm_source=tangem-app-banner" +
|
||||
"&utm_medium=banner" +
|
||||
"&utm_campaign=BlackFriday2025"
|
||||
const val ONE_PLUS_ONE_PROMO_LINK = "https://tangem.com/pricing/" +
|
||||
"?cat=family" +
|
||||
"&utm_source=tangem-app-banner" +
|
||||
"&utm_medium=banner" +
|
||||
"&utm_campaign=BOGO50"
|
||||
const val YIELD_PROMO_TERMS_LINK = "https://tangem.com/docs/yield-mode-toc.html"
|
||||
}
|
||||
}
|
||||
|
|
@ -125,12 +125,6 @@ sealed class WalletScreenAnalyticsEvent {
|
|||
if (blockchain != null) put("Blockchain", blockchain)
|
||||
},
|
||||
)
|
||||
|
||||
// region Referral Promo
|
||||
class ReferralPromo : MainScreen(event = "Referral Banner")
|
||||
class ReferralPromoButtonParticipate : MainScreen(event = "Button - Referral Participate")
|
||||
class ReferralPromoButtonDismiss : MainScreen(event = "Button - Referral Dismiss")
|
||||
//endregion
|
||||
}
|
||||
|
||||
sealed class PushBannerPromo(
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import com.tangem.core.analytics.api.AnalyticsEventHandler
|
|||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.domain.tokens.model.analytics.PromoAnalyticsEvent.*
|
||||
import com.tangem.feature.wallet.child.wallet.model.WalletActivationBannerType
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent.MainScreen
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent.MainScreen.*
|
||||
|
|
@ -69,28 +68,6 @@ internal class WalletWarningsAnalyticsSender @Inject constructor(
|
|||
is WalletNotification.RateApp -> HowDoYouLikeTangem()
|
||||
is WalletNotification.Critical.BackupError -> BackupError()
|
||||
is WalletNotification.NoteMigration -> NotePromo()
|
||||
is WalletNotification.SwapPromo -> NoticePromotionBanner(
|
||||
source = AnalyticsParam.ScreensSources.Main,
|
||||
program = Program.Empty, // Use it on new promo action
|
||||
)
|
||||
is WalletNotification.Sepa -> NoticePromotionBanner(
|
||||
source = AnalyticsParam.ScreensSources.Main,
|
||||
program = Program.Sepa,
|
||||
)
|
||||
is WalletNotification.BlackFridayPromo -> NoticePromotionBanner(
|
||||
source = AnalyticsParam.ScreensSources.Main,
|
||||
program = Program.BlackFriday,
|
||||
)
|
||||
is WalletNotification.OnePlusOnePromo -> NoticePromotionBanner(
|
||||
source = AnalyticsParam.ScreensSources.Main,
|
||||
program = Program.OnePlusOne,
|
||||
)
|
||||
is WalletNotification.YieldPromo -> NoticePromotionBanner(
|
||||
source = AnalyticsParam.ScreensSources.Main,
|
||||
program = Program.YieldPromo,
|
||||
)
|
||||
is WalletNotification.ReferralPromo -> MainScreen.ReferralPromo()
|
||||
is WalletNotification.VisaPresalePromo -> VisaWaitlistPromo()
|
||||
is WalletNotification.UnlockWallets -> null // See [SelectedWalletAnalyticsSender]
|
||||
is WalletNotification.Informational.NoAccount,
|
||||
is WalletNotification.Warning.LowSignatures,
|
||||
|
|
@ -138,14 +115,6 @@ internal class WalletWarningsAnalyticsSender @Inject constructor(
|
|||
is WalletNotificationUM.RateApp -> HowDoYouLikeTangem()
|
||||
is WalletNotificationUM.BackupError -> BackupError()
|
||||
is WalletNotificationUM.NoteMigration -> NotePromo()
|
||||
is WalletNotificationUM.OnePlusOnePromo -> NoticePromotionBanner(
|
||||
source = AnalyticsParam.ScreensSources.Main,
|
||||
program = Program.OnePlusOne,
|
||||
)
|
||||
is WalletNotificationUM.YieldPromo -> NoticePromotionBanner(
|
||||
source = AnalyticsParam.ScreensSources.Main,
|
||||
program = Program.YieldPromo,
|
||||
)
|
||||
is WalletNotificationUM.FinishWalletActivation -> {
|
||||
val activationState = if (notificationUM.isBackupExists) {
|
||||
NoticeFinishActivation.ActivationState.Unfinished
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@ import com.tangem.domain.models.currency.CryptoCurrency
|
|||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.notifications.repository.NotificationsRepository
|
||||
import com.tangem.domain.promo.ShouldShowPromoWalletUseCase
|
||||
import com.tangem.domain.promo.models.PromoId
|
||||
import com.tangem.domain.settings.IsReadyToShowRateAppUseCase
|
||||
import com.tangem.domain.assetsdiscovery.model.AssetsDiscoveryProgress
|
||||
import com.tangem.domain.assetsdiscovery.usecase.ObserveAssetsDiscoveryUseCase
|
||||
|
|
@ -54,7 +52,6 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
|||
private val isReadyToShowRateAppUseCase: IsReadyToShowRateAppUseCase,
|
||||
private val isNeedToBackupUseCase: IsNeedToBackupUseCase,
|
||||
private val backupValidator: BackupValidator,
|
||||
private val shouldShowPromoWalletUseCase: ShouldShowPromoWalletUseCase,
|
||||
private val notificationsRepository: NotificationsRepository,
|
||||
private val accountDependencies: AccountDependencies,
|
||||
private val getAccessCodeSkippedUseCase: GetAccessCodeSkippedUseCase,
|
||||
|
|
@ -82,13 +79,9 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
|||
accountStatusListFlow,
|
||||
isReadyToShowRateAppUseCase().distinctUntilChanged(),
|
||||
isNeedToBackupUseCase(userWallet.walletId).distinctUntilChanged(),
|
||||
shouldShowPromoWalletUseCase(userWalletId = userWallet.walletId, promoId = PromoId.OnePlusOne)
|
||||
.distinctUntilChanged(),
|
||||
notificationsRepository.getShouldShowNotification(NotificationId.EnablePushesReminderNotification.key)
|
||||
.distinctUntilChanged(),
|
||||
getAccessCodeSkippedUseCase(userWallet.walletId).distinctUntilChanged(),
|
||||
shouldShowPromoWalletUseCase(userWalletId = userWallet.walletId, promoId = PromoId.YieldPromo)
|
||||
.distinctUntilChanged(),
|
||||
shouldShowUpgradeHotWalletBannerUseCase.invoke(userWallet.walletId)
|
||||
.distinctUntilChanged(),
|
||||
getUpgradeBannerClosureTimestampUseCase(userWallet.walletId)
|
||||
|
|
@ -99,13 +92,11 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
|||
val accountStatusList = array[0] as AccountStatusList
|
||||
val isReadyToShowRating = array[1] as Boolean
|
||||
val isNeedToBackup = array[2] as Boolean
|
||||
val shouldShowOnePlusOnePromo = array[3] as Boolean
|
||||
val shouldShowEnablePushesReminderNotification = array[4] as Boolean
|
||||
val shouldAccessCodeSkipped = array[5] as Boolean
|
||||
val shouldShowYieldPromo = array[6] as Boolean
|
||||
val shouldShowUpgradeBanner = array[7] as Boolean
|
||||
val closureTimestamp = array[8] as? Long
|
||||
val assetsDiscoveryProgress = array[9] as AssetsDiscoveryProgress
|
||||
val shouldShowEnablePushesReminderNotification = array[3] as Boolean
|
||||
val shouldAccessCodeSkipped = array[4] as Boolean
|
||||
val shouldShowUpgradeBanner = array[5] as Boolean
|
||||
val closureTimestamp = array[6] as? Long
|
||||
val assetsDiscoveryProgress = array[7] as AssetsDiscoveryProgress
|
||||
|
||||
val flattenCurrencies = accountStatusList.flattenCurrencies()
|
||||
val paymentAccountStatus = accountStatusList.accountStatuses
|
||||
|
|
@ -132,10 +123,6 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
|||
shouldAccessCodeSkipped = shouldAccessCodeSkipped,
|
||||
)
|
||||
|
||||
addOnePlusOnePromoNotification(clickIntents, shouldShowOnePlusOnePromo)
|
||||
|
||||
addYieldPromoNotification(clickIntents, shouldShowYieldPromo)
|
||||
|
||||
addInformationalNotifications(
|
||||
userWallet = userWallet,
|
||||
cardTypesResolver = cardTypesResolver,
|
||||
|
|
@ -296,32 +283,6 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
|||
.map(CryptoCurrencyStatus::currency)
|
||||
}
|
||||
|
||||
private fun MutableList<WalletNotification>.addOnePlusOnePromoNotification(
|
||||
clickIntents: WalletClickIntents,
|
||||
shouldShowPromo: Boolean,
|
||||
) {
|
||||
addIf(
|
||||
element = WalletNotification.OnePlusOnePromo(
|
||||
onCloseClick = { clickIntents.onClosePromoClick(promoId = PromoId.OnePlusOne) },
|
||||
onClick = { clickIntents.onPromoClick(promoId = PromoId.OnePlusOne) },
|
||||
),
|
||||
condition = shouldShowPromo,
|
||||
)
|
||||
}
|
||||
|
||||
private fun MutableList<WalletNotification>.addYieldPromoNotification(
|
||||
clickIntents: WalletClickIntents,
|
||||
shouldShowPromo: Boolean,
|
||||
) {
|
||||
addIf(
|
||||
element = WalletNotification.YieldPromo(
|
||||
onCloseClick = { clickIntents.onClosePromoClick(promoId = PromoId.YieldPromo) },
|
||||
onTermsAndConditionsClick = { clickIntents.onYieldPromoTermsAndConditionsClick() },
|
||||
),
|
||||
condition = shouldShowPromo,
|
||||
)
|
||||
}
|
||||
|
||||
// private fun MutableList<WalletNotification>.addYieldSupplyNotifications(
|
||||
// flattenCurrencies: Lce<TokenListError, List<CryptoCurrencyStatus>>,
|
||||
// ) {
|
||||
|
|
|
|||
|
|
@ -5,10 +5,7 @@ import com.tangem.common.ui.notifications.NotificationId
|
|||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.isMultiCurrency
|
||||
import com.tangem.domain.notifications.repository.NotificationsRepository
|
||||
import com.tangem.domain.promo.ShouldShowPromoWalletUseCase
|
||||
import com.tangem.domain.promo.models.PromoId
|
||||
import com.tangem.domain.settings.IsReadyToShowRateAppUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
|
|
@ -29,32 +26,22 @@ import javax.inject.Inject
|
|||
@ModelScoped
|
||||
internal class GetWalletNotificationsCarouselFactory @Inject constructor(
|
||||
private val isReadyToShowRateAppUseCase: IsReadyToShowRateAppUseCase,
|
||||
private val shouldShowPromoWalletUseCase: ShouldShowPromoWalletUseCase,
|
||||
private val getWalletsUseCase: GetWalletsUseCase,
|
||||
private val notificationsRepository: NotificationsRepository,
|
||||
) {
|
||||
fun create(userWallet: UserWallet, clickIntents: WalletClickIntents): Flow<ImmutableList<WalletNotificationUM>> {
|
||||
return combine(
|
||||
flow = shouldShowPromoWalletUseCase(userWalletId = userWallet.walletId, promoId = PromoId.YieldPromo)
|
||||
.distinctUntilChanged(),
|
||||
flow2 = notificationsRepository.getShouldShowNotification(
|
||||
flow = notificationsRepository.getShouldShowNotification(
|
||||
NotificationId.EnablePushesReminderNotification.key,
|
||||
).distinctUntilChanged(),
|
||||
flow3 = shouldShowPromoWalletUseCase(userWalletId = userWallet.walletId, promoId = PromoId.OnePlusOne)
|
||||
.distinctUntilChanged(),
|
||||
flow4 = isReadyToShowRateAppUseCase().distinctUntilChanged(),
|
||||
flow5 = getWalletsUseCase().conflate(),
|
||||
) { showYieldPromo, showPushesNotification, showOnePlusOnePromo, showRateAppPromo, wallets ->
|
||||
flow2 = isReadyToShowRateAppUseCase().distinctUntilChanged(),
|
||||
flow3 = getWalletsUseCase().conflate(),
|
||||
) { showPushesNotification, showRateAppPromo, wallets ->
|
||||
|
||||
buildList {
|
||||
addNoteMigrationNotification(userWallet, wallets, clickIntents)
|
||||
addRateAppNotification(showRateAppPromo, clickIntents)
|
||||
|
||||
if (userWallet.isMultiCurrency) {
|
||||
addOnePlusOnePromoNotification(clickIntents, showOnePlusOnePromo)
|
||||
addYieldPromoNotification(clickIntents, showYieldPromo)
|
||||
}
|
||||
|
||||
addPushNotification(
|
||||
shouldShow = showPushesNotification,
|
||||
isPushesAllowed = notificationsRepository.isUserAllowToSubscribeOnPushNotifications(),
|
||||
|
|
@ -77,30 +64,6 @@ internal class GetWalletNotificationsCarouselFactory @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun MutableList<WalletNotificationUM>.addYieldPromoNotification(
|
||||
clickIntents: WalletClickIntents,
|
||||
shouldShowPromo: Boolean,
|
||||
) {
|
||||
addIf(shouldShowPromo) {
|
||||
WalletNotificationUM.YieldPromo(
|
||||
onCloseClick = { clickIntents.onClosePromoClick(promoId = PromoId.YieldPromo) },
|
||||
onTermsAndConditionsClick = { clickIntents.onYieldPromoTermsAndConditionsClick() },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableList<WalletNotificationUM>.addOnePlusOnePromoNotification(
|
||||
clickIntents: WalletClickIntents,
|
||||
shouldShowPromo: Boolean,
|
||||
) {
|
||||
addIf(shouldShowPromo) {
|
||||
WalletNotificationUM.OnePlusOnePromo(
|
||||
onCloseClick = { clickIntents.onClosePromoClick(promoId = PromoId.OnePlusOne) },
|
||||
onClick = { clickIntents.onPromoClick(promoId = PromoId.OnePlusOne) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableList<WalletNotificationUM>.addNoteMigrationNotification(
|
||||
userWallet: UserWallet,
|
||||
userWallets: List<UserWallet>,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import com.tangem.core.ui.extensions.resourceReference
|
|||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.feature.wallet.child.wallet.model.WalletActivationBannerType
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import org.joda.time.DateTime
|
||||
|
||||
/**
|
||||
* Wallet notification component state
|
||||
|
|
@ -229,19 +228,6 @@ sealed class WalletNotification(val config: NotificationConfig) {
|
|||
),
|
||||
)
|
||||
|
||||
data class SwapPromo(
|
||||
val startDateTime: DateTime,
|
||||
val endDateTime: DateTime,
|
||||
val onCloseClick: () -> Unit,
|
||||
) : WalletNotification(
|
||||
config = NotificationConfig(
|
||||
title = resourceReference(id = R.string.swap_promo_title),
|
||||
subtitle = resourceReference(id = R.string.swap_promo_text),
|
||||
iconResId = R.drawable.img_okx_dex_logo,
|
||||
onCloseClick = onCloseClick,
|
||||
),
|
||||
)
|
||||
|
||||
data class NoteMigration(val onClick: () -> Unit) : WalletNotification(
|
||||
config = NotificationConfig(
|
||||
title = resourceReference(R.string.wallet_promo_banner_title),
|
||||
|
|
@ -282,108 +268,6 @@ sealed class WalletNotification(val config: NotificationConfig) {
|
|||
),
|
||||
)
|
||||
|
||||
data class ReferralPromo(
|
||||
val onCloseClick: () -> Unit,
|
||||
val onClick: () -> Unit,
|
||||
) : WalletNotification(
|
||||
config = NotificationConfig(
|
||||
title = resourceReference(R.string.notification_referral_promo_title),
|
||||
subtitle = resourceReference(R.string.notification_referral_promo_text),
|
||||
iconResId = R.drawable.img_referral_promo,
|
||||
onCloseClick = onCloseClick,
|
||||
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
||||
text = resourceReference(R.string.notification_referral_promo_button),
|
||||
onClick = onClick,
|
||||
),
|
||||
iconSize = 54.dp,
|
||||
),
|
||||
)
|
||||
|
||||
data class VisaPresalePromo(
|
||||
val onCloseClick: () -> Unit,
|
||||
val onClick: () -> Unit,
|
||||
) : WalletNotification(
|
||||
config = NotificationConfig(
|
||||
title = resourceReference(R.string.notification_visa_waitlist_promo_title),
|
||||
subtitle = resourceReference(R.string.notification_visa_waitlist_promo_text),
|
||||
iconResId = R.drawable.img_visa_waitlist_promo,
|
||||
onCloseClick = onCloseClick,
|
||||
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
||||
text = resourceReference(R.string.notification_referral_promo_button),
|
||||
onClick = onClick,
|
||||
),
|
||||
iconSize = 54.dp,
|
||||
),
|
||||
)
|
||||
|
||||
data class Sepa(
|
||||
val onCloseClick: () -> Unit,
|
||||
val onClick: () -> Unit,
|
||||
) : WalletNotification(
|
||||
config = NotificationConfig(
|
||||
title = resourceReference(R.string.notification_sepa_title),
|
||||
subtitle = resourceReference(R.string.notification_sepa_text),
|
||||
iconResId = R.drawable.img_notification_sepa,
|
||||
onCloseClick = onCloseClick,
|
||||
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
||||
text = resourceReference(R.string.notification_sepa_button),
|
||||
onClick = onClick,
|
||||
),
|
||||
iconSize = 54.dp,
|
||||
),
|
||||
)
|
||||
|
||||
data class BlackFridayPromo(
|
||||
val onCloseClick: () -> Unit,
|
||||
val onClick: () -> Unit,
|
||||
) : WalletNotification(
|
||||
config = NotificationConfig(
|
||||
title = resourceReference(R.string.notification_black_friday_title),
|
||||
subtitle = resourceReference(R.string.notification_black_friday_text),
|
||||
iconResId = R.drawable.img_black_friday_promo,
|
||||
onCloseClick = onCloseClick,
|
||||
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
||||
text = resourceReference(R.string.common_claim),
|
||||
onClick = onClick,
|
||||
),
|
||||
iconSize = 54.dp,
|
||||
),
|
||||
)
|
||||
|
||||
data class OnePlusOnePromo(
|
||||
val onCloseClick: () -> Unit,
|
||||
val onClick: () -> Unit,
|
||||
) : WalletNotification(
|
||||
config = NotificationConfig(
|
||||
title = resourceReference(R.string.notification_one_plus_one_title),
|
||||
subtitle = resourceReference(R.string.notification_one_plus_one_text),
|
||||
iconResId = R.drawable.img_one_plus_one_promo,
|
||||
onCloseClick = onCloseClick,
|
||||
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
||||
text = resourceReference(R.string.notification_one_plus_one_button),
|
||||
onClick = onClick,
|
||||
),
|
||||
iconSize = 54.dp,
|
||||
),
|
||||
)
|
||||
|
||||
data class YieldPromo(
|
||||
val onCloseClick: () -> Unit,
|
||||
val onTermsAndConditionsClick: () -> Unit,
|
||||
) : WalletNotification(
|
||||
config = NotificationConfig(
|
||||
title = resourceReference(R.string.notification_yield_promo_title),
|
||||
subtitle = resourceReference(R.string.notification_yield_promo_text),
|
||||
iconResId = R.drawable.ic_yield_promo_36,
|
||||
onCloseClick = onCloseClick,
|
||||
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
||||
text = resourceReference(R.string.notification_yield_promo_button),
|
||||
onClick = onTermsAndConditionsClick,
|
||||
),
|
||||
iconSize = 36.dp,
|
||||
),
|
||||
)
|
||||
|
||||
data class PushNotifications(
|
||||
val onCloseClick: () -> Unit,
|
||||
val onEnabledClick: () -> Unit,
|
||||
|
|
|
|||
|
|
@ -360,53 +360,6 @@ internal sealed class WalletNotificationUM(val messageUM: TangemMessageUM, val t
|
|||
type = WalletNotificationType.Promo,
|
||||
)
|
||||
|
||||
data class OnePlusOnePromo(
|
||||
val onCloseClick: () -> Unit,
|
||||
val onClick: () -> Unit,
|
||||
) : WalletNotificationUM(
|
||||
messageUM = TangemMessageUM(
|
||||
id = "OnePlusOnePromoNotification",
|
||||
title = resourceReference(R.string.notification_one_plus_one_title),
|
||||
subtitle = resourceReference(R.string.notification_one_plus_one_text),
|
||||
messageEffect = TangemMessageEffect.Magic,
|
||||
iconUM = TangemIconUM.Image(R.drawable.img_one_plus_one_promo),
|
||||
iconSize = 54.dp,
|
||||
buttonsUM = persistentListOf(
|
||||
TangemMessageButtonUM(
|
||||
text = resourceReference(R.string.common_later),
|
||||
type = TangemButtonType.PrimaryInverse,
|
||||
onClick = onCloseClick,
|
||||
),
|
||||
TangemMessageButtonUM(
|
||||
text = resourceReference(R.string.notification_one_plus_one_button),
|
||||
type = TangemButtonType.Primary,
|
||||
onClick = onClick,
|
||||
),
|
||||
),
|
||||
),
|
||||
type = WalletNotificationType.Promo,
|
||||
)
|
||||
|
||||
data class YieldPromo(
|
||||
val onCloseClick: () -> Unit,
|
||||
val onTermsAndConditionsClick: () -> Unit,
|
||||
) : WalletNotificationUM(
|
||||
messageUM = TangemMessageUM(
|
||||
id = "YieldPromoNotification",
|
||||
title = resourceReference(R.string.notification_yield_promo_title),
|
||||
subtitle = resourceReference(R.string.notification_yield_promo_text),
|
||||
onCloseClick = onCloseClick,
|
||||
messageEffect = TangemMessageEffect.Magic,
|
||||
buttonsUM = persistentListOf(
|
||||
TangemMessageButtonUM(
|
||||
text = resourceReference(R.string.notification_yield_promo_button),
|
||||
type = TangemButtonType.Primary,
|
||||
onClick = onTermsAndConditionsClick,
|
||||
),
|
||||
),
|
||||
),
|
||||
type = WalletNotificationType.Promo,
|
||||
)
|
||||
// endregion
|
||||
|
||||
// region Survey
|
||||
|
|
|
|||
|
|
@ -27,11 +27,7 @@ internal fun LazyListScope.notifications(configs: ImmutableList<WalletNotificati
|
|||
key = { it::class.java },
|
||||
contentType = { it::class.java },
|
||||
itemContent = { item ->
|
||||
// TODO develop promo banner general component
|
||||
when (item) {
|
||||
is WalletNotification.SwapPromo -> {
|
||||
// Use it on new promo action
|
||||
}
|
||||
is WalletNotification.NoteMigration -> {
|
||||
NoteMigrationNotification(
|
||||
config = item.config,
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="36dp"
|
||||
android:height="36dp"
|
||||
android:viewportWidth="36"
|
||||
android:viewportHeight="36">
|
||||
<path
|
||||
android:pathData="M18,18m-18,0a18,18 0,1 1,36 0a18,18 0,1 1,-36 0"
|
||||
android:strokeAlpha="0.1"
|
||||
android:fillColor="#0099FF"
|
||||
android:fillAlpha="0.1"/>
|
||||
<path
|
||||
android:pathData="M18.057,7.745C20.247,7.745 21.968,7.745 23.312,7.926C24.688,8.111 25.781,8.498 26.639,9.356C27.497,10.214 27.885,11.307 28.07,12.683C28.25,14.027 28.25,15.748 28.25,17.938V18.052C28.25,20.243 28.25,21.964 28.07,23.307C27.885,24.684 27.497,25.776 26.639,26.635C25.781,27.493 24.688,27.879 23.312,28.064C21.968,28.245 20.247,28.245 18.057,28.245H17.943C15.752,28.245 14.031,28.245 12.688,28.064C11.311,27.879 10.219,27.493 9.361,26.635C8.502,25.776 8.116,24.684 7.931,23.307C7.75,21.964 7.75,20.243 7.75,18.052V17.938C7.75,15.748 7.75,14.027 7.931,12.683C8.116,11.307 8.503,10.214 9.361,9.356C10.219,8.498 11.311,8.111 12.688,7.926C14.031,7.745 15.752,7.745 17.943,7.745H18.057ZM13,21.248C12.586,21.248 12.25,21.584 12.25,21.998V23.998C12.25,24.412 12.586,24.748 13,24.748C13.414,24.748 13.75,24.412 13.75,23.998V21.998C13.75,21.584 13.414,21.248 13,21.248ZM18,20.247C17.586,20.247 17.25,20.583 17.25,20.997V23.997C17.25,24.411 17.586,24.747 18,24.747C18.414,24.747 18.75,24.411 18.75,23.997V20.997C18.75,20.583 18.414,20.247 18,20.247ZM23,18.245C22.586,18.245 22.25,18.581 22.25,18.995V23.995C22.25,24.409 22.586,24.745 23,24.745C23.414,24.745 23.75,24.409 23.75,23.995V18.995C23.75,18.581 23.414,18.245 23,18.245ZM21.859,11.247C21.654,11.256 21.416,11.295 21.179,11.335C21.168,11.337 21.157,11.339 21.146,11.341L19.878,11.55C19.47,11.617 19.193,12.002 19.26,12.411C19.327,12.82 19.714,13.097 20.122,13.029L20.846,12.91C18.963,15.552 15.953,16.745 12,16.745C11.586,16.745 11.25,17.081 11.25,17.495C11.25,17.909 11.586,18.245 12,18.245C16.322,18.245 19.898,16.9 22.132,13.689L22.279,14.201C22.393,14.599 22.808,14.829 23.206,14.716C23.604,14.601 23.835,14.186 23.721,13.788L23.403,12.677C23.399,12.666 23.396,12.655 23.393,12.643C23.335,12.44 23.271,12.218 23.189,12.036C23.088,11.814 22.93,11.576 22.645,11.414C22.369,11.257 22.09,11.236 21.859,11.247Z"
|
||||
android:fillColor="#0099FF"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
Loading…
Add table
Add a link
Reference in a new issue