diff --git a/app/src/main/java/com/tangem/tap/di/domain/SettingsDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/SettingsDomainModule.kt index 3c9fb7b2a9..629af1e441 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/SettingsDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/SettingsDomainModule.kt @@ -7,8 +7,8 @@ import com.tangem.domain.balancehiding.UpdateBalanceHidingSettingsUseCase import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository import com.tangem.domain.settings.* import com.tangem.domain.settings.repositories.AppRatingRepository +import com.tangem.domain.settings.repositories.PromoSettingsRepository import com.tangem.domain.settings.repositories.SettingsRepository -import com.tangem.domain.settings.repositories.SwapPromoRepository import com.tangem.tap.domain.TangemSdkManager import com.tangem.tap.domain.settings.DefaultLegacySettingsRepository import dagger.Module @@ -108,17 +108,25 @@ internal object SettingsDomainModule { @Provides @ViewModelScoped fun provideShouldShowSwapPromoWalletUseCase( - swapPromoRepository: SwapPromoRepository, + promoSettingsRepository: PromoSettingsRepository, ): ShouldShowSwapPromoWalletUseCase { - return ShouldShowSwapPromoWalletUseCase(swapPromoRepository) + return ShouldShowSwapPromoWalletUseCase(promoSettingsRepository) + } + + @Provides + @ViewModelScoped + fun provideShouldShowTravalaPromoWalletUseCase( + promoSettingsRepository: PromoSettingsRepository, + ): ShouldShowTravalaPromoWalletUseCase { + return ShouldShowTravalaPromoWalletUseCase(promoSettingsRepository) } @Provides @ViewModelScoped fun provideShouldShowSwapPromoTokenUseCase( - swapPromoRepository: SwapPromoRepository, + promoSettingsRepository: PromoSettingsRepository, ): ShouldShowSwapPromoTokenUseCase { - return ShouldShowSwapPromoTokenUseCase(swapPromoRepository) + return ShouldShowSwapPromoTokenUseCase(promoSettingsRepository) } @Provides diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/PromotionInfoResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/PromotionInfoResponse.kt index fa9140eea1..668a77c321 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/PromotionInfoResponse.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/promotion/models/PromotionInfoResponse.kt @@ -13,6 +13,7 @@ data class PromotionInfoResponse( data class BannerState( @Json(name = "timeline") val timeline: Timeline, @Json(name = "status") val status: String, + @Json(name = "link") val link: String?, ) @JsonClass(generateAdapter = true) diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/preferences/PreferencesKeys.kt b/core/datasource/src/main/java/com/tangem/datasource/local/preferences/PreferencesKeys.kt index bec274ae30..8a7c3c3dff 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/local/preferences/PreferencesKeys.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/local/preferences/PreferencesKeys.kt @@ -55,6 +55,10 @@ object PreferencesKeys { booleanPreferencesKey(name = "isTokenSwapPromoChangellyShown") } + val IS_WALLET_TRAVALA_PROMO_SHOWN_KEY by lazy { + booleanPreferencesKey(name = "isWalletTravalaPromoShown") + } + val FEATURE_TOGGLES_KEY by lazy { stringPreferencesKey(name = "featureToggles") } val WAS_TWINS_ONBOARDING_SHOWN by lazy { booleanPreferencesKey(name = "twinsOnboardingShown") } diff --git a/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json b/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json index cf1fb0dc1d..629a8b5e9b 100644 --- a/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json +++ b/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json @@ -9,7 +9,7 @@ }, { "name": "REDESIGNED_SEND_SCREEN_ENABLED", - "version": "5.9.1" + "version": "5.10.0" }, { "name": "GENERAL_USER_WALLETS_LIST_MANAGER_ENABLED", diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index f12dc6ee9c..931a4aff2e 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -267,6 +267,9 @@ Обменивайте свои токены с %1$s комиссии провайдера через Changelly с %2$s по %3$s февраля. Обмен с Changelly, %s комиссии Токены + Забронировать + Оплатите его криптой и сэкономьте **50 долларов** через нашего партнера Travala: **%1s - %2s** + Забронируйте отпуск с Tangem Добавить Изменить Рыночная капитализация diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 1b3c413136..f0fc91c000 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -267,6 +267,9 @@ Enjoy %1$s service fees on swaps via Changelly from February %2$s-%3$s Swap with Changelly, %s fees Tokens + Book now + Save **$50** while booking via our partner Travala: **%1s - %2s** + Book your holidays with Tangem and pay in crypto Add Edit Coin market cap diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/notifications/NotificationWithBackground.kt b/core/ui/src/main/java/com/tangem/core/ui/components/notifications/NotificationWithBackground.kt index e4e8a06833..0c48f4b767 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/notifications/NotificationWithBackground.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/notifications/NotificationWithBackground.kt @@ -47,7 +47,11 @@ fun NotificationWithBackground(config: NotificationConfig, modifier: Modifier = modifier = modifier .defaultMinSize(minHeight = TangemTheme.dimens.size62) .fillMaxWidth() - .clip(TangemTheme.shapes.roundedCornersXMedium), + .clip(TangemTheme.shapes.roundedCornersXMedium) + .clickable( + enabled = config.onClick != null, + onClick = config.onClick ?: {}, + ), ) { val (iconRef, titleRef, subtitleRef, closeIconRef, buttonRef, backgroundRef) = createRefs() diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/notifications/TravalaNotificationWithBackground.kt b/core/ui/src/main/java/com/tangem/core/ui/components/notifications/TravalaNotificationWithBackground.kt new file mode 100644 index 0000000000..9e6ba3db1d --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/notifications/TravalaNotificationWithBackground.kt @@ -0,0 +1,215 @@ +package com.tangem.core.ui.components.notifications + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.* +import androidx.compose.material.Icon +import androidx.compose.material.Text +import androidx.compose.material.ripple.rememberRipple +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.layout.ScaleFactor +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.AnnotatedString +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.style.LineBreak +import androidx.compose.ui.text.withStyle +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Density +import androidx.compose.ui.unit.dp +import com.tangem.core.ui.R +import com.tangem.core.ui.components.SpacerH8 +import com.tangem.core.ui.components.buttons.common.TangemButton +import com.tangem.core.ui.components.buttons.common.TangemButtonColors +import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition +import com.tangem.core.ui.extensions.resolveReference +import com.tangem.core.ui.extensions.resourceReference +import com.tangem.core.ui.extensions.wrappedList +import com.tangem.core.ui.res.TangemColorPalette.White +import com.tangem.core.ui.res.TangemTheme + +/** + * Travala notification with image background + * @see Travala Promo + */ +@Suppress("LongMethod", "DestructuringDeclarationWithTooManyEntries") +@Composable +fun TravalaNotificationWithBackground(config: NotificationConfig, modifier: Modifier = Modifier) { + val button = config.buttonsState as? NotificationConfig.ButtonsState.SecondaryButtonConfig + + Box( + modifier = modifier + .defaultMinSize(minHeight = TangemTheme.dimens.size62) + .fillMaxWidth() + .clip(TangemTheme.shapes.roundedCornersXMedium) + .background(Color.Black) + .clickable( + enabled = config.onClick != null, + onClick = config.onClick ?: {}, + ), + propagateMinConstraints = true, + contentAlignment = Alignment.TopStart, + ) { + val density = LocalDensity.current + Image( + painter = painterResource(R.drawable.img_travala_banner_promo_background), + contentDescription = null, + contentScale = TravalaBackgroundScale(density), + alignment = Alignment.TopStart, + modifier = Modifier + .matchParentSize() + .wrapContentSize(unbounded = true, align = Alignment.TopStart) + .align(Alignment.TopStart), + ) + Image( + painter = painterResource(R.drawable.img_travala_banner_promo_background_2), + contentDescription = null, + contentScale = TravalaBackgroundScale(density), + alignment = Alignment.TopStart, + modifier = Modifier + .matchParentSize() + .wrapContentSize(unbounded = true, align = Alignment.TopEnd) + .align(Alignment.TopEnd), + ) + Column { + Row { + Box(modifier = Modifier.size(87.dp)) + Column( + Modifier + .weight(1f) + .padding(top = TangemTheme.dimens.spacing12), + ) { + Text( + text = config.title.resolveReference(), + style = TangemTheme.typography.button.copy( + lineBreak = LineBreak.Heading, + ), + color = TangemTheme.colors.text.constantWhite, + ) + SpacerH8() + Text( + text = formatSubtitle(config.subtitle.resolveReference()), + style = TangemTheme.typography.caption2.copy( + lineBreak = LineBreak.Heading, + ), + color = TangemTheme.colors.text.constantWhite, + ) + } + Icon( + painter = painterResource(id = R.drawable.ic_close_24), + contentDescription = null, + tint = TangemTheme.colors.text.constantWhite, + modifier = Modifier + .padding( + top = TangemTheme.dimens.spacing12, + end = TangemTheme.dimens.spacing12, + start = TangemTheme.dimens.spacing2, + ) + .size(TangemTheme.dimens.size16) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = rememberRipple(bounded = false), + ) { + config.onCloseClick?.invoke() + }, + ) + } + + TangemButton( + text = button?.text?.resolveReference().orEmpty(), + icon = TangemButtonIconPosition.None, + onClick = button?.onClick ?: {}, + colors = TangemButtonColors( + backgroundColor = White.copy(alpha = 0.3f), + contentColor = White, + disabledBackgroundColor = TangemTheme.colors.button.disabled, + disabledContentColor = TangemTheme.colors.text.disabled, + ), + enabled = true, + showProgress = false, + modifier = Modifier + .padding(TangemTheme.dimens.spacing12) + .fillMaxWidth(), + ) + } + } +} + +private const val TRAVALA_BACKGROUND_SRC_IMG_SCALE = 4 + +private class TravalaBackgroundScale( + val density: Density, +) : ContentScale { + override fun computeScaleFactor(srcSize: Size, dstSize: Size): ScaleFactor { + with(density) { + val originalWidth = (srcSize.width / TRAVALA_BACKGROUND_SRC_IMG_SCALE).dp.toPx() + val widthScale = originalWidth / srcSize.width + val originalHeight = (srcSize.height / TRAVALA_BACKGROUND_SRC_IMG_SCALE).dp.toPx() + val heightScale = originalHeight / srcSize.height + return ScaleFactor(widthScale, heightScale) + } + } +} + +@Composable +private fun formatSubtitle(subtitle: String): AnnotatedString { + val pattern = Regex("\\*\\*(.*?)\\*\\*") + var startIndex = 0 + val annotatedString = buildAnnotatedString { + pattern.findAll(subtitle).forEach { matchResult -> + val index = matchResult.range.first + val matchedValue = matchResult.groups[1]?.value ?: "" + + // appends unformatted part + append(subtitle.substring(startIndex, index)) + + // applies style on ^^-wrapped parts + withStyle(SpanStyle(fontWeight = TangemTheme.typography.caption1.fontWeight)) { + append(matchedValue) + } + + // goes to next part + startIndex = matchResult.range.last + 1 + } + + // appends remaining ending if exists + append(subtitle.substring(startIndex)) + } + + return annotatedString +} + +//region preview +@Preview +@Composable +private fun TravalaNotificationWithBackgroundPreview() { + TangemTheme { + TravalaNotificationWithBackground( + config = NotificationConfig( + title = resourceReference( + id = R.string.main_travala_promotion_title, + ), + subtitle = resourceReference( + id = R.string.main_travala_promotion_description, + formatArgs = wrappedList("May 13", "June 12"), + ), + iconResId = R.drawable.img_swap_promo, + backgroundResId = R.drawable.img_travala_banner_promo_background, + buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig( + text = resourceReference(id = R.string.token_swap_promotion_button), + onClick = {}, + ), + ), + ) + } +} +//endregion \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/utils/DateTimeFormatters.kt b/core/ui/src/main/java/com/tangem/core/ui/utils/DateTimeFormatters.kt index 0ea40469e2..d42121d3f0 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/utils/DateTimeFormatters.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/utils/DateTimeFormatters.kt @@ -1,5 +1,6 @@ package com.tangem.core.ui.utils +import android.text.format.DateFormat import org.joda.time.DateTime import org.joda.time.format.DateTimeFormat import org.joda.time.format.DateTimeFormatter @@ -55,6 +56,16 @@ object DateTimeFormatters { .withLocale(Locale.getDefault()) } + /** + * In API version < 24, there may be some problems with getting the best date and time format pattern. + */ + val dateMMMMd: DateTimeFormatter by lazy { + DateTimeFormatterBuilder() + .appendPattern(DateFormat.getBestDateTimePattern(Locale.getDefault(), "MMMM d")) + .toFormatter() + .withLocale(Locale.getDefault()) + } + val dateTimeFormatter: DateTimeFormatter by lazy { DateTimeFormat.forPattern("dd.MM.yyyy HH:mm") } diff --git a/core/ui/src/main/res/drawable/img_travala_banner_promo_background.webp b/core/ui/src/main/res/drawable/img_travala_banner_promo_background.webp new file mode 100644 index 0000000000..bc3845b8b7 Binary files /dev/null and b/core/ui/src/main/res/drawable/img_travala_banner_promo_background.webp differ diff --git a/core/ui/src/main/res/drawable/img_travala_banner_promo_background_2.webp b/core/ui/src/main/res/drawable/img_travala_banner_promo_background_2.webp new file mode 100644 index 0000000000..c051b16418 Binary files /dev/null and b/core/ui/src/main/res/drawable/img_travala_banner_promo_background_2.webp differ diff --git a/data/promo/src/main/java/com/tangem/data/promo/DefaultPromoRepository.kt b/data/promo/src/main/java/com/tangem/data/promo/DefaultPromoRepository.kt index 3121a961d7..a92a4f5eb9 100644 --- a/data/promo/src/main/java/com/tangem/data/promo/DefaultPromoRepository.kt +++ b/data/promo/src/main/java/com/tangem/data/promo/DefaultPromoRepository.kt @@ -23,7 +23,17 @@ internal class DefaultPromoRepository( }.getOrNull() } + override suspend fun getTravalaPromoBanner(): PromoBanner? { + return runCatching(dispatchers.io) { + promoResponseConverter.convert( + tangemApi.getPromotionInfo(TRAVALA) + .getOrThrow(), + ) + }.getOrNull() + } + private companion object { private const val CHANGELLY_NAME = "changelly" + private const val TRAVALA = "travala" } } \ No newline at end of file diff --git a/data/promo/src/main/java/com/tangem/data/promo/converters/PromoResponseConverter.kt b/data/promo/src/main/java/com/tangem/data/promo/converters/PromoResponseConverter.kt index c7ad8f331a..151675506b 100644 --- a/data/promo/src/main/java/com/tangem/data/promo/converters/PromoResponseConverter.kt +++ b/data/promo/src/main/java/com/tangem/data/promo/converters/PromoResponseConverter.kt @@ -13,6 +13,7 @@ class PromoResponseConverter : Converter { 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), diff --git a/data/settings/src/main/java/com/tangem/data/settings/DefaultSwapPromoRepository.kt b/data/settings/src/main/java/com/tangem/data/settings/DefaultPromoSettingsRepository.kt similarity index 55% rename from data/settings/src/main/java/com/tangem/data/settings/DefaultSwapPromoRepository.kt rename to data/settings/src/main/java/com/tangem/data/settings/DefaultPromoSettingsRepository.kt index 6d9ccf740a..80ba44157d 100644 --- a/data/settings/src/main/java/com/tangem/data/settings/DefaultSwapPromoRepository.kt +++ b/data/settings/src/main/java/com/tangem/data/settings/DefaultPromoSettingsRepository.kt @@ -3,36 +3,48 @@ package com.tangem.data.settings import com.tangem.datasource.local.preferences.AppPreferencesStore import com.tangem.datasource.local.preferences.PreferencesKeys.IS_TOKEN_SWAP_PROMO_CHANGELLY_SHOW_KEY import com.tangem.datasource.local.preferences.PreferencesKeys.IS_WALLET_SWAP_PROMO_CHANGELLY_SHOW_KEY +import com.tangem.datasource.local.preferences.PreferencesKeys.IS_WALLET_TRAVALA_PROMO_SHOWN_KEY import com.tangem.datasource.local.preferences.utils.get import com.tangem.datasource.local.preferences.utils.store -import com.tangem.domain.settings.repositories.SwapPromoRepository +import com.tangem.domain.settings.repositories.PromoSettingsRepository import kotlinx.coroutines.flow.Flow /** * Repository for showing swap promo notification. */ -class DefaultSwapPromoRepository( +class DefaultPromoSettingsRepository( private val appPreferencesStore: AppPreferencesStore, -) : SwapPromoRepository { - override fun isReadyToShowWalletPromo(): Flow { +) : PromoSettingsRepository { + override fun isReadyToShowWalletSwapPromo(): Flow { return appPreferencesStore.get(IS_WALLET_SWAP_PROMO_CHANGELLY_SHOW_KEY, true) } - override fun isReadyToShowTokenPromo(): Flow { + override fun isReadyToShowTokenSwapPromo(): Flow { return appPreferencesStore.get(IS_TOKEN_SWAP_PROMO_CHANGELLY_SHOW_KEY, true) } - override suspend fun setNeverToShowWalletPromo() { + override suspend fun setNeverToShowWalletSwapPromo() { appPreferencesStore.store( key = IS_WALLET_SWAP_PROMO_CHANGELLY_SHOW_KEY, value = false, ) } - override suspend fun setNeverToShowTokenPromo() { + override suspend fun setNeverToShowTokenSwapPromo() { appPreferencesStore.store( key = IS_TOKEN_SWAP_PROMO_CHANGELLY_SHOW_KEY, value = false, ) } + + override fun isReadyToShowWalletTravalaPromo(): Flow { + return appPreferencesStore.get(IS_WALLET_TRAVALA_PROMO_SHOWN_KEY, true) + } + + override suspend fun setNeverToShowWalletTravalaPromo() { + appPreferencesStore.store( + key = IS_WALLET_TRAVALA_PROMO_SHOWN_KEY, + value = false, + ) + } } \ No newline at end of file diff --git a/data/settings/src/main/java/com/tangem/data/settings/di/SettingsDataModule.kt b/data/settings/src/main/java/com/tangem/data/settings/di/SettingsDataModule.kt index 43d5796d15..880f0d36b1 100644 --- a/data/settings/src/main/java/com/tangem/data/settings/di/SettingsDataModule.kt +++ b/data/settings/src/main/java/com/tangem/data/settings/di/SettingsDataModule.kt @@ -2,12 +2,12 @@ package com.tangem.data.settings.di import com.tangem.data.settings.DefaultAppRatingRepository import com.tangem.data.settings.DefaultSettingsRepository -import com.tangem.data.settings.DefaultSwapPromoRepository +import com.tangem.data.settings.DefaultPromoSettingsRepository import com.tangem.data.source.preferences.PreferencesDataSource import com.tangem.datasource.local.preferences.AppPreferencesStore import com.tangem.domain.settings.repositories.AppRatingRepository import com.tangem.domain.settings.repositories.SettingsRepository -import com.tangem.domain.settings.repositories.SwapPromoRepository +import com.tangem.domain.settings.repositories.PromoSettingsRepository import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.Module import dagger.Provides @@ -41,7 +41,7 @@ internal object SettingsDataModule { @Provides @Singleton - fun provideSwapPromoRepository(appPreferencesStore: AppPreferencesStore): SwapPromoRepository { - return DefaultSwapPromoRepository(appPreferencesStore = appPreferencesStore) + fun providePromoSettingsSettingsRepository(appPreferencesStore: AppPreferencesStore): PromoSettingsRepository { + return DefaultPromoSettingsRepository(appPreferencesStore = appPreferencesStore) } } \ No newline at end of file diff --git a/domain/legacy/src/main/java/com/tangem/domain/common/CardTypesResolver.kt b/domain/legacy/src/main/java/com/tangem/domain/common/CardTypesResolver.kt index 0cbee25c28..56a874bd6a 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/common/CardTypesResolver.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/common/CardTypesResolver.kt @@ -30,6 +30,12 @@ interface CardTypesResolver { fun isSatoshiFriendsWallet(): Boolean + fun isBitcoinPizzaDayWallet(): Boolean + + fun isVeChainWallet(): Boolean + + fun isNewWorldEliteWallet(): Boolean + fun isWhiteWallet(): Boolean fun isWallet2(): Boolean diff --git a/domain/legacy/src/main/java/com/tangem/domain/common/TangemCardTypesResolver.kt b/domain/legacy/src/main/java/com/tangem/domain/common/TangemCardTypesResolver.kt index 077ffe5de1..8c3a6ec485 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/common/TangemCardTypesResolver.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/common/TangemCardTypesResolver.kt @@ -48,6 +48,12 @@ internal class TangemCardTypesResolver( override fun isSatoshiFriendsWallet(): Boolean = card.batchId == SATOSHI_WALLET_BATCH_ID + override fun isBitcoinPizzaDayWallet(): Boolean = card.batchId == BITCOIN_PIZZA_DAY_WALLET_BATCH_ID + + override fun isVeChainWallet(): Boolean = card.batchId == VECHAIN_WALLET_BATCH_ID + + override fun isNewWorldEliteWallet(): Boolean = card.batchId == NEW_WORLD_ELITE_WALLET_BATCH_ID + override fun isWhiteWallet(): Boolean { return walletData == null && card.firmwareVersion <= FirmwareVersion.HDWalletAvailable } @@ -154,5 +160,8 @@ internal class TangemCardTypesResolver( const val WHITE_WALLET2_BATCH_ID = "AF15" const val TRILLIANT_WALLET_BATCH_ID = "AF16" const val AVRORA_WALLET_BATCH_ID = "AF18" + const val BITCOIN_PIZZA_DAY_WALLET_BATCH_ID = "AF33" + const val VECHAIN_WALLET_BATCH_ID = "AF29" + const val NEW_WORLD_ELITE_WALLET_BATCH_ID = "AF26" } } \ No newline at end of file diff --git a/domain/settings/src/main/java/com/tangem/domain/settings/ShouldShowSwapPromoTokenUseCase.kt b/domain/settings/src/main/java/com/tangem/domain/settings/ShouldShowSwapPromoTokenUseCase.kt index 966e1bcf83..8ede57bcf9 100644 --- a/domain/settings/src/main/java/com/tangem/domain/settings/ShouldShowSwapPromoTokenUseCase.kt +++ b/domain/settings/src/main/java/com/tangem/domain/settings/ShouldShowSwapPromoTokenUseCase.kt @@ -1,11 +1,11 @@ package com.tangem.domain.settings -import com.tangem.domain.settings.repositories.SwapPromoRepository +import com.tangem.domain.settings.repositories.PromoSettingsRepository import kotlinx.coroutines.flow.Flow -class ShouldShowSwapPromoTokenUseCase(private val swapPromoRepository: SwapPromoRepository) { +class ShouldShowSwapPromoTokenUseCase(private val promoSettingsRepository: PromoSettingsRepository) { - operator fun invoke(): Flow = swapPromoRepository.isReadyToShowTokenPromo() + operator fun invoke(): Flow = promoSettingsRepository.isReadyToShowTokenSwapPromo() - suspend fun neverToShow() = swapPromoRepository.setNeverToShowTokenPromo() + suspend fun neverToShow() = promoSettingsRepository.setNeverToShowTokenSwapPromo() } \ No newline at end of file diff --git a/domain/settings/src/main/java/com/tangem/domain/settings/ShouldShowSwapPromoWalletUseCase.kt b/domain/settings/src/main/java/com/tangem/domain/settings/ShouldShowSwapPromoWalletUseCase.kt index e2b30e1ba5..233277f71f 100644 --- a/domain/settings/src/main/java/com/tangem/domain/settings/ShouldShowSwapPromoWalletUseCase.kt +++ b/domain/settings/src/main/java/com/tangem/domain/settings/ShouldShowSwapPromoWalletUseCase.kt @@ -1,11 +1,11 @@ package com.tangem.domain.settings -import com.tangem.domain.settings.repositories.SwapPromoRepository +import com.tangem.domain.settings.repositories.PromoSettingsRepository import kotlinx.coroutines.flow.Flow -class ShouldShowSwapPromoWalletUseCase(private val swapPromoRepository: SwapPromoRepository) { +class ShouldShowSwapPromoWalletUseCase(private val promoSettingsRepository: PromoSettingsRepository) { - operator fun invoke(): Flow = swapPromoRepository.isReadyToShowWalletPromo() + operator fun invoke(): Flow = promoSettingsRepository.isReadyToShowWalletSwapPromo() - suspend fun neverToShow() = swapPromoRepository.setNeverToShowWalletPromo() + suspend fun neverToShow() = promoSettingsRepository.setNeverToShowWalletSwapPromo() } \ No newline at end of file diff --git a/domain/settings/src/main/java/com/tangem/domain/settings/ShouldShowTravalaPromoWalletUseCase.kt b/domain/settings/src/main/java/com/tangem/domain/settings/ShouldShowTravalaPromoWalletUseCase.kt new file mode 100644 index 0000000000..643e7387c8 --- /dev/null +++ b/domain/settings/src/main/java/com/tangem/domain/settings/ShouldShowTravalaPromoWalletUseCase.kt @@ -0,0 +1,11 @@ +package com.tangem.domain.settings + +import com.tangem.domain.settings.repositories.PromoSettingsRepository +import kotlinx.coroutines.flow.Flow + +class ShouldShowTravalaPromoWalletUseCase(private val promoSettingsRepository: PromoSettingsRepository) { + + operator fun invoke(): Flow = promoSettingsRepository.isReadyToShowWalletTravalaPromo() + + suspend fun neverToShow() = promoSettingsRepository.setNeverToShowWalletTravalaPromo() +} \ No newline at end of file diff --git a/domain/settings/src/main/java/com/tangem/domain/settings/repositories/PromoSettingsRepository.kt b/domain/settings/src/main/java/com/tangem/domain/settings/repositories/PromoSettingsRepository.kt new file mode 100644 index 0000000000..0e3946bb89 --- /dev/null +++ b/domain/settings/src/main/java/com/tangem/domain/settings/repositories/PromoSettingsRepository.kt @@ -0,0 +1,17 @@ +package com.tangem.domain.settings.repositories + +import kotlinx.coroutines.flow.Flow + +interface PromoSettingsRepository { + fun isReadyToShowWalletSwapPromo(): Flow + + fun isReadyToShowTokenSwapPromo(): Flow + + suspend fun setNeverToShowWalletSwapPromo() + + suspend fun setNeverToShowTokenSwapPromo() + + fun isReadyToShowWalletTravalaPromo(): Flow + + suspend fun setNeverToShowWalletTravalaPromo() +} \ No newline at end of file diff --git a/domain/settings/src/main/java/com/tangem/domain/settings/repositories/SwapPromoRepository.kt b/domain/settings/src/main/java/com/tangem/domain/settings/repositories/SwapPromoRepository.kt deleted file mode 100644 index ca97755e66..0000000000 --- a/domain/settings/src/main/java/com/tangem/domain/settings/repositories/SwapPromoRepository.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.tangem.domain.settings.repositories - -import kotlinx.coroutines.flow.Flow - -interface SwapPromoRepository { - fun isReadyToShowWalletPromo(): Flow - - fun isReadyToShowTokenPromo(): Flow - - suspend fun setNeverToShowWalletPromo() - - suspend fun setNeverToShowTokenPromo() -} \ No newline at end of file diff --git a/domain/tokens/models/src/main/java/com/tangem/domain/promo/PromoBanner.kt b/domain/tokens/models/src/main/java/com/tangem/domain/promo/PromoBanner.kt index 564a49e3d4..2608085143 100644 --- a/domain/tokens/models/src/main/java/com/tangem/domain/promo/PromoBanner.kt +++ b/domain/tokens/models/src/main/java/com/tangem/domain/promo/PromoBanner.kt @@ -12,6 +12,7 @@ data class PromoBanner( data class BannerState( val timeline: Timeline, val status: String, + val link: String?, ) data class Timeline( diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/PromoRepository.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/PromoRepository.kt index b15e05db54..ed42ab1cfc 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/PromoRepository.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/repository/PromoRepository.kt @@ -5,4 +5,6 @@ import com.tangem.domain.promo.PromoBanner interface PromoRepository { suspend fun getChangellyPromoBanner(): PromoBanner? + + suspend fun getTravalaPromoBanner(): PromoBanner? } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/WalletScreenAnalyticsEvent.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/WalletScreenAnalyticsEvent.kt index de6ddf8b1b..f39a38511b 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/WalletScreenAnalyticsEvent.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/WalletScreenAnalyticsEvent.kt @@ -121,4 +121,38 @@ sealed class WalletScreenAnalyticsEvent { data object DeleteWalletTapped : MainScreen(event = "Button - Delete Wallet Tapped") } + + sealed class Promotion( + event: String, + params: Map = mapOf(), + ) : AnalyticsEvent(category = "Promotion", event = event, params = params) { + class NoticePromotionBanner( + source: AnalyticsParam.ScreensSources, + programName: String, + ) : Promotion( + event = "Notice - Promotion Banner", + params = mapOf( + AnalyticsParam.SOURCE to source.value, + "Program Name" to programName, + ), + ) + + class PromotionBannerClicked( + source: AnalyticsParam.ScreensSources, + programName: String, + action: BannerAction, + ) : Promotion( + event = "Promo Banner Clicked", + params = mapOf( + AnalyticsParam.SOURCE to source.value, + "Program Name" to programName, + "Action" to action.action, + ), + ) { + sealed class BannerAction(val action: String) { + data object Clicked : BannerAction(action = "Clicked") + data object Closed : BannerAction(action = "Closed") + } + } + } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/WalletWarningsAnalyticsSender.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/WalletWarningsAnalyticsSender.kt index e80fc87a24..16ba03cb43 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/WalletWarningsAnalyticsSender.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/WalletWarningsAnalyticsSender.kt @@ -2,6 +2,8 @@ package com.tangem.feature.wallet.presentation.wallet.analytics.utils import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.analytics.models.AnalyticsEvent +import com.tangem.core.analytics.models.AnalyticsParam +import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent.MainScreen import com.tangem.feature.wallet.presentation.wallet.state.model.WalletNotification import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState @@ -44,6 +46,10 @@ internal class WalletWarningsAnalyticsSender @Inject constructor( is WalletNotification.Informational.MissingAddresses -> MainScreen.MissingAddresses is WalletNotification.RateApp -> MainScreen.HowDoYouLikeTangem is WalletNotification.Critical.BackupError -> MainScreen.BackupError + is WalletNotification.TravalaPromo -> WalletScreenAnalyticsEvent.Promotion.NoticePromotionBanner( + source = AnalyticsParam.ScreensSources.Main, + programName = "Travala", + ) is WalletNotification.UnlockWallets -> null // See [SelectedWalletAnalyticsSender] is WalletNotification.Informational.NoAccount, is WalletNotification.Warning.LowSignatures, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt index 7432cbb84e..daaebb07e1 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt @@ -6,7 +6,7 @@ import com.tangem.domain.common.util.cardTypesResolver import com.tangem.domain.demo.IsDemoCardUseCase import com.tangem.domain.promo.PromoBanner import com.tangem.domain.settings.IsReadyToShowRateAppUseCase -import com.tangem.domain.settings.ShouldShowSwapPromoWalletUseCase +import com.tangem.domain.settings.ShouldShowTravalaPromoWalletUseCase import com.tangem.domain.tokens.GetTokenListUseCase import com.tangem.domain.tokens.error.TokenListError import com.tangem.domain.tokens.model.CryptoCurrency @@ -34,7 +34,7 @@ internal class GetMultiWalletWarningsFactory @Inject constructor( private val getTokenListUseCase: GetTokenListUseCase, private val isDemoCardUseCase: IsDemoCardUseCase, private val isReadyToShowRateAppUseCase: IsReadyToShowRateAppUseCase, - private val shouldShowSwapPromoWalletUseCase: ShouldShowSwapPromoWalletUseCase, + private val shouldShowTravalaPromoWalletUseCase: ShouldShowTravalaPromoWalletUseCase, private val promoRepository: PromoRepository, private val isNeedToBackupUseCase: IsNeedToBackupUseCase, private val backupValidator: BackupValidator, @@ -45,18 +45,18 @@ internal class GetMultiWalletWarningsFactory @Inject constructor( fun create(userWallet: UserWallet, clickIntents: WalletClickIntents): Flow> { val cardTypesResolver = userWallet.scanResponse.cardTypesResolver - val promoFlow = flow { emit(promoRepository.getChangellyPromoBanner()) } + val travalaPromoFlow = flow { emit(promoRepository.getTravalaPromoBanner()) } return combine( flow = getTokenListUseCase(userWallet.walletId).conflate(), flow2 = isReadyToShowRateAppUseCase().conflate(), flow3 = isNeedToBackupUseCase(userWallet.walletId).conflate(), - flow4 = shouldShowSwapPromoWalletUseCase().conflate(), - flow5 = promoFlow, - ) { maybeTokenList, isReadyToShowRating, isNeedToBackup, shouldShowPromo, promoBanner -> + flow4 = shouldShowTravalaPromoWalletUseCase().conflate(), + flow5 = travalaPromoFlow.conflate(), + ) { maybeTokenList, isReadyToShowRating, isNeedToBackup, shouldShowTravalaPromo, promoBanner -> readyForRateAppNotification = true buildList { - addSwapPromoNotification(shouldShowPromo, promoBanner, clickIntents) + addTravalaPromoNotification(shouldShowTravalaPromo, promoBanner, clickIntents) addCriticalNotifications(userWallet) @@ -69,16 +69,18 @@ internal class GetMultiWalletWarningsFactory @Inject constructor( } } - private fun MutableList.addSwapPromoNotification( + private fun MutableList.addTravalaPromoNotification( shouldShowPromo: Boolean, promoBanner: PromoBanner?, clickIntents: WalletClickIntents, ) { promoBanner ?: return - val promoNotification = WalletNotification.SwapPromo( + val promoNotification = WalletNotification.TravalaPromo( startDateTime = promoBanner.bannerState.timeline.start, endDateTime = promoBanner.bannerState.timeline.end, - onCloseClick = clickIntents::onCloseSwapPromoClick, + bannerLink = promoBanner.bannerState.link, + onBookNowButtonClick = clickIntents::onTravalaPromoClick, + onCloseClick = clickIntents::onCloseTravalaPromoClick, ) addIf( element = promoNotification, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletImageResolver.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletImageResolver.kt index 7c7adbde20..3613a6439a 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletImageResolver.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/WalletImageResolver.kt @@ -34,6 +34,9 @@ internal object WalletImageResolver { cardTypesResolver.isJrWallet() -> userWallet.resolveJrWallet() cardTypesResolver.isGrimWallet() -> userWallet.resolveGrimWallet() cardTypesResolver.isSatoshiFriendsWallet() -> userWallet.resolveSatoshiWallet() + cardTypesResolver.isBitcoinPizzaDayWallet() -> userWallet.resolveBitcoinPizzaDayWallet() + cardTypesResolver.isVeChainWallet() -> userWallet.resolveVeChainWallet() + cardTypesResolver.isNewWorldEliteWallet() -> userWallet.resolveNewWorldEliteWallet() cardTypesResolver.isWallet2() -> userWallet.resolveWallet2() cardTypesResolver.isShibaWallet() -> userWallet.resolveShibaWallet() cardTypesResolver.isTangemWallet() -> userWallet.resolveWallet1() @@ -130,6 +133,27 @@ internal object WalletImageResolver { ) } + private fun UserWallet.resolveBitcoinPizzaDayWallet(): Int? { + return resolveWallet2( + oneBackupResId = R.drawable.ill_pizza_day_card2_120_106, + twoBackupResId = R.drawable.ill_pizza_day_card3_120_106, + ) + } + + private fun UserWallet.resolveVeChainWallet(): Int? { + return resolveWallet2( + oneBackupResId = R.drawable.ill_vechain_card2_120_106, + twoBackupResId = R.drawable.ill_vechain_card3_120_106, + ) + } + + private fun UserWallet.resolveNewWorldEliteWallet(): Int? { + return resolveWallet2( + oneBackupResId = R.drawable.ill_nwe_card2_120_106, + twoBackupResId = R.drawable.ill_nwe_card3_120_106, + ) + } + private fun UserWallet.resolveWallet1(): Int? { return resolveWalletWithBackups { count -> when (count) { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletNotification.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletNotification.kt index 9f7f5ea139..c34e986c29 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletNotification.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletNotification.kt @@ -2,10 +2,8 @@ package com.tangem.feature.wallet.presentation.wallet.state.model import androidx.compose.runtime.Immutable import com.tangem.core.ui.components.notifications.NotificationConfig -import com.tangem.core.ui.extensions.TextReference -import com.tangem.core.ui.extensions.pluralReference -import com.tangem.core.ui.extensions.resourceReference -import com.tangem.core.ui.extensions.wrappedList +import com.tangem.core.ui.extensions.* +import com.tangem.core.ui.utils.DateTimeFormatters import com.tangem.feature.wallet.impl.R import org.joda.time.DateTime @@ -173,6 +171,34 @@ sealed class WalletNotification(val config: NotificationConfig) { ), ) + data class TravalaPromo( + val startDateTime: DateTime, + val endDateTime: DateTime, + val bannerLink: String?, + val onBookNowButtonClick: (String?) -> Unit, + val onCloseClick: () -> Unit, + ) : WalletNotification( + config = NotificationConfig( + title = resourceReference(id = R.string.main_travala_promotion_title), + subtitle = resourceReference( + id = R.string.main_travala_promotion_description, + wrappedList( + DateTimeFormatters.formatDate(startDateTime, DateTimeFormatters.dateMMMMd), + DateTimeFormatters.formatDate(endDateTime, DateTimeFormatters.dateMMMMd), + ), + ), + // Stub. Travala has its own Composable implementation with correct img + iconResId = R.drawable.ic_star_24, + // Stub. Travala has its own Composable implementation with correct img + backgroundResId = R.drawable.ic_star_24, + buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig( + onClick = { onBookNowButtonClick(bannerLink) }, + text = resourceReference(R.string.main_travala_promotion_button), + ), + onCloseClick = onCloseClick, + ), + ) + data class SwapPromo( val startDateTime: DateTime, val endDateTime: DateTime, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletNotifications.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletNotifications.kt index 476f3701e4..6b783e0eb0 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletNotifications.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletNotifications.kt @@ -6,6 +6,7 @@ import androidx.compose.foundation.lazy.items import androidx.compose.ui.Modifier import com.tangem.core.ui.components.notifications.Notification import com.tangem.core.ui.components.notifications.NotificationWithBackground +import com.tangem.core.ui.components.notifications.TravalaNotificationWithBackground import com.tangem.core.ui.res.TangemTheme import com.tangem.feature.wallet.presentation.wallet.state.model.WalletNotification import kotlinx.collections.immutable.ImmutableList @@ -25,23 +26,33 @@ internal fun LazyListScope.notifications(configs: ImmutableList TangemTheme.colors.icon.warning - is WalletNotification.Informational -> TangemTheme.colors.icon.accent - is WalletNotification.RateApp -> TangemTheme.colors.icon.attention - is WalletNotification.UnlockWallets -> TangemTheme.colors.icon.primary1 - else -> null - }, - ) + // TODO develop promo banner general component + when (it) { + is WalletNotification.SwapPromo -> { + NotificationWithBackground( + config = it.config, + modifier = modifier.animateItemPlacement(), + ) + } + is WalletNotification.TravalaPromo -> { + TravalaNotificationWithBackground( + config = it.config, + modifier = modifier.animateItemPlacement(), + ) + } + else -> { + Notification( + config = it.config, + modifier = modifier.animateItemPlacement(), + iconTint = when (it) { + is WalletNotification.Critical -> TangemTheme.colors.icon.warning + is WalletNotification.Informational -> TangemTheme.colors.icon.accent + is WalletNotification.RateApp -> TangemTheme.colors.icon.attention + is WalletNotification.UnlockWallets -> TangemTheme.colors.icon.primary1 + else -> null + }, + ) + } } }, ) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletWarningsClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletWarningsClickIntents.kt index 553dafc78b..418a4d8afd 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletWarningsClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletWarningsClickIntents.kt @@ -11,6 +11,7 @@ import com.tangem.domain.redux.ReduxStateHolder import com.tangem.domain.settings.NeverToSuggestRateAppUseCase import com.tangem.domain.settings.RemindToRateAppLaterUseCase import com.tangem.domain.settings.ShouldShowSwapPromoWalletUseCase +import com.tangem.domain.settings.ShouldShowTravalaPromoWalletUseCase import com.tangem.domain.tokens.FetchTokenListUseCase import com.tangem.domain.tokens.model.CryptoCurrency import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType @@ -19,6 +20,7 @@ import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.domain.wallets.usecase.UnlockWalletsUseCase import com.tangem.feature.wallet.impl.R +import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent.Basic import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent.MainScreen import com.tangem.feature.wallet.presentation.wallet.domain.ScanCardToUnlockWalletClickHandler @@ -56,6 +58,10 @@ internal interface WalletWarningsClickIntents { fun onCloseRateAppWarningClick() fun onCloseSwapPromoClick() + + fun onTravalaPromoClick(link: String?) + + fun onCloseTravalaPromoClick() } @Suppress("LongParameterList") @@ -75,6 +81,7 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( private val reduxStateHolder: ReduxStateHolder, private val dispatchers: CoroutineDispatcherProvider, private val shouldShowSwapPromoWalletUseCase: ShouldShowSwapPromoWalletUseCase, + private val shouldShowTravalaPromoWalletUseCase: ShouldShowTravalaPromoWalletUseCase, ) : BaseWalletClickIntents(), WalletWarningsClickIntents { override fun onAddBackupCardClick() { @@ -212,6 +219,34 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( } } + override fun onTravalaPromoClick(link: String?) { + analyticsEventHandler.send( + WalletScreenAnalyticsEvent.Promotion.PromotionBannerClicked( + source = AnalyticsParam.ScreensSources.Main, + programName = "Travala", + action = WalletScreenAnalyticsEvent.Promotion.PromotionBannerClicked.BannerAction.Clicked, + ), + ) + link?.let { + viewModelScope.launch(dispatchers.main) { + router.openUrl(link) + } + } + } + + override fun onCloseTravalaPromoClick() { + analyticsEventHandler.send( + WalletScreenAnalyticsEvent.Promotion.PromotionBannerClicked( + source = AnalyticsParam.ScreensSources.Main, + programName = "Travala", + action = WalletScreenAnalyticsEvent.Promotion.PromotionBannerClicked.BannerAction.Closed, + ), + ) + viewModelScope.launch(dispatchers.main) { + shouldShowTravalaPromoWalletUseCase.neverToShow() + } + } + private suspend fun getSelectedUserWallet(): UserWallet? { val userWalletId = stateHolder.getSelectedWalletId() return getUserWalletUseCase(userWalletId).getOrElse { diff --git a/features/wallet/impl/src/main/res/drawable/ill_nwe_card2_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_nwe_card2_120_106.webp new file mode 100644 index 0000000000..b54656293e Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_nwe_card2_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_nwe_card3_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_nwe_card3_120_106.webp new file mode 100644 index 0000000000..feecda86b3 Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_nwe_card3_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_pizza_day_card2_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_pizza_day_card2_120_106.webp new file mode 100644 index 0000000000..2608db4c6e Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_pizza_day_card2_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_pizza_day_card3_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_pizza_day_card3_120_106.webp new file mode 100644 index 0000000000..d47e557121 Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_pizza_day_card3_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_vechain_card2_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_vechain_card2_120_106.webp new file mode 100644 index 0000000000..bb5f23d301 Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_vechain_card2_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_vechain_card3_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_vechain_card3_120_106.webp new file mode 100644 index 0000000000..249477b20f Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_vechain_card3_120_106.webp differ