diff --git a/app/src/main/java/com/tangem/tap/di/domain/MarketsDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/MarketsDomainModule.kt index d6bfbdb63a..6e154f3fc1 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/MarketsDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/MarketsDomainModule.kt @@ -8,7 +8,6 @@ import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher import com.tangem.domain.promo.PromoRepository import com.tangem.domain.quotes.multi.MultiQuoteStatusFetcher import com.tangem.domain.quotes.single.SingleQuoteStatusSupplier -import com.tangem.domain.settings.repositories.SettingsRepository import com.tangem.domain.staking.StakingIdFactory import com.tangem.domain.staking.multi.MultiStakingBalanceFetcher import com.tangem.domain.tokens.repository.CurrenciesRepository @@ -129,13 +128,11 @@ object MarketsDomainModule { @Provides @Singleton - fun provideGetStakingNotificationMaxApyUseCase( - settingsRepository: SettingsRepository, + fun provideShouldShowYieldModeMarketPromoUseCase( promoRepository: PromoRepository, marketsTokenRepository: MarketsTokenRepository, - ): GetStakingNotificationMaxApyUseCase { - return GetStakingNotificationMaxApyUseCase( - settingsRepository = settingsRepository, + ): ShouldShowYieldModeMarketPromoUseCase { + return ShouldShowYieldModeMarketPromoUseCase( promoRepository = promoRepository, marketsTokenRepository = marketsTokenRepository, ) diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/markets/models/response/TokenMarketListResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/markets/models/response/TokenMarketListResponse.kt index 3c1829900b..31168b8c5b 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/markets/models/response/TokenMarketListResponse.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/markets/models/response/TokenMarketListResponse.kt @@ -26,6 +26,7 @@ data class TokenMarketListResponse( @Json(name = "market_cap") val marketCap: BigDecimal?, @Json(name = "is_under_market_cap_limit") val isUnderMarketCapLimit: Boolean?, @Json(name = "staking_opportunities") val stakingOpportunities: List?, + @Json(name = "max_yield_apy") val maxYieldApy: BigDecimal?, ) { @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 3fafa4462a..b52614222b 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 @@ -77,8 +77,8 @@ object PreferencesKeys { val SHOULD_SHOW_MARKETS_TOOLTIP_KEY by lazy { booleanPreferencesKey(name = "shouldShowMarketsTooltip") } - val MARKETS_STAKING_NOTIFICATION_HIDE_CLICKED_KEY by lazy { - booleanPreferencesKey(name = "marketsStakingNotificationHideClicked") + val MARKETS_YIELD_SUPPLY_NOTIFICATION_HIDE_CLICKED_KEY by lazy { + booleanPreferencesKey(name = "marketsYieldSupplyNotificationHideClicked") } val WALLET_FIRST_USAGE_DATE_KEY by lazy { longPreferencesKey(name = "walletFirstUsageDate") } diff --git a/core/ui/src/main/res/drawable/img_yield_supply_in_market_notification.webp b/core/ui/src/main/res/drawable/img_yield_supply_in_market_notification.webp new file mode 100644 index 0000000000..6f7bfc38ce Binary files /dev/null and b/core/ui/src/main/res/drawable/img_yield_supply_in_market_notification.webp differ diff --git a/data/markets/src/main/java/com/tangem/data/markets/DefaultMarketsTokenRepository.kt b/data/markets/src/main/java/com/tangem/data/markets/DefaultMarketsTokenRepository.kt index 9dcc66efb0..2f974d4f31 100644 --- a/data/markets/src/main/java/com/tangem/data/markets/DefaultMarketsTokenRepository.kt +++ b/data/markets/src/main/java/com/tangem/data/markets/DefaultMarketsTokenRepository.kt @@ -20,6 +20,7 @@ import com.tangem.datasource.api.markets.TangemTechMarketsApi import com.tangem.datasource.api.markets.models.response.TokenMarketExchangesResponse import com.tangem.datasource.local.datastore.RuntimeStateStore import com.tangem.datasource.local.userwallet.UserWalletsStore +import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.markets.* import com.tangem.domain.markets.repositories.MarketsTokenRepository import com.tangem.domain.models.account.DerivationIndex @@ -28,9 +29,8 @@ import com.tangem.domain.models.wallet.UserWalletId import com.tangem.pagination.* import com.tangem.pagination.fetcher.LimitOffsetBatchFetcher import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.withContext -import java.math.BigDecimal +import timber.log.Timber import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicLong @@ -43,7 +43,6 @@ internal class DefaultMarketsTokenRepository( private val analyticsEventHandler: AnalyticsEventHandler, private val cacheRegistry: CacheRegistry, private val tokenExchangesStore: RuntimeStateStore>, - private val maxApyStore: RuntimeStateStore, private val networkFactory: NetworkFactory, excludedBlockchains: ExcludedBlockchains, ) : MarketsTokenRepository { @@ -95,8 +94,6 @@ internal class DefaultMarketsTokenRepository( val tokenMarketListWithMaxApy = TokenMarketListConverter.convert(res) - maxApyStore.store(tokenMarketListWithMaxApy.maxApy) - return BatchFetchResult.Success( data = tokenMarketListWithMaxApy.tokens, last = last, @@ -294,8 +291,24 @@ internal class DefaultMarketsTokenRepository( } } - override suspend fun getMaxApy(): Flow { - return maxApyStore.get() + override suspend fun showYieldModePromo( + appCurrency: AppCurrency, + interval: TokenMarketListConfig.Interval, + ): Boolean = try { + val hasYieldSupplyTokens = marketsApi.getCoinsList( + currency = appCurrency.code, + interval = interval.toRequestParam(), + order = TokenMarketListConfig.Order.YieldSupply.toRequestParam(), + offset = 0, + limit = 40, + timestamp = null, + search = null, + ).getOrThrow().tokens.isNotEmpty() + + hasYieldSupplyTokens + } catch (error: Exception) { + Timber.e(error) + false } inline fun catchListErrorAndSendEvent(block: () -> T): T { diff --git a/data/markets/src/main/java/com/tangem/data/markets/converters/TokenListConfigConverters.kt b/data/markets/src/main/java/com/tangem/data/markets/converters/TokenListConfigConverters.kt index e280e160e1..7dce907fe8 100644 --- a/data/markets/src/main/java/com/tangem/data/markets/converters/TokenListConfigConverters.kt +++ b/data/markets/src/main/java/com/tangem/data/markets/converters/TokenListConfigConverters.kt @@ -16,6 +16,7 @@ internal fun TokenMarketListConfig.Order.toRequestParam(): String = when (this) TokenMarketListConfig.Order.TopGainers -> "gainers" TokenMarketListConfig.Order.TopLosers -> "losers" TokenMarketListConfig.Order.Staking -> "staking" + TokenMarketListConfig.Order.YieldSupply -> "yield" } internal fun PriceChangeInterval.toRequestParam(): String = when (this) { diff --git a/data/markets/src/main/java/com/tangem/data/markets/converters/TokenMarketListConverter.kt b/data/markets/src/main/java/com/tangem/data/markets/converters/TokenMarketListConverter.kt index 067f886293..ed6cb59dc4 100644 --- a/data/markets/src/main/java/com/tangem/data/markets/converters/TokenMarketListConverter.kt +++ b/data/markets/src/main/java/com/tangem/data/markets/converters/TokenMarketListConverter.kt @@ -40,7 +40,7 @@ internal object TokenMarketListConverter : Converter { + override fun isMarketsYieldSupplyNotificationHideClicked(): Flow { return appPreferencesStore.get( - key = PreferencesKeys.MARKETS_STAKING_NOTIFICATION_HIDE_CLICKED_KEY, + key = PreferencesKeys.MARKETS_YIELD_SUPPLY_NOTIFICATION_HIDE_CLICKED_KEY, default = false, ) } - override suspend fun setMarketsStakingNotificationHideClicked() { + override suspend fun setMarketsYieldSupplyNotificationHideClicked() { appPreferencesStore.store( - key = PreferencesKeys.MARKETS_STAKING_NOTIFICATION_HIDE_CLICKED_KEY, + key = PreferencesKeys.MARKETS_YIELD_SUPPLY_NOTIFICATION_HIDE_CLICKED_KEY, value = true, ) } diff --git a/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarket.kt b/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarket.kt index 36b179897a..3deeee528d 100644 --- a/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarket.kt +++ b/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarket.kt @@ -12,7 +12,7 @@ data class TokenMarket( val isUnderMarketCapLimit: Boolean, val tokenQuotesShort: TokenQuotesShort, val tokenCharts: Charts, - val stakingRate: BigDecimal?, + val yieldRate: BigDecimal?, val updateTimestamp: Long?, private val imageHost: String, ) { diff --git a/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarketListConfig.kt b/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarketListConfig.kt index 011df2c630..ffd82b8909 100644 --- a/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarketListConfig.kt +++ b/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/TokenMarketListConfig.kt @@ -8,7 +8,7 @@ data class TokenMarketListConfig( ) { enum class Order { - ByRating, Trending, Buyers, TopGainers, TopLosers, Staking + ByRating, Trending, Buyers, TopGainers, TopLosers, Staking, YieldSupply, } enum class Interval { diff --git a/domain/markets/src/main/java/com/tangem/domain/markets/GetStakingNotificationMaxApyUseCase.kt b/domain/markets/src/main/java/com/tangem/domain/markets/GetStakingNotificationMaxApyUseCase.kt deleted file mode 100644 index 4ccaea6680..0000000000 --- a/domain/markets/src/main/java/com/tangem/domain/markets/GetStakingNotificationMaxApyUseCase.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.tangem.domain.markets - -import android.icu.util.Calendar -import com.tangem.domain.markets.repositories.MarketsTokenRepository -import com.tangem.domain.promo.PromoRepository -import com.tangem.domain.settings.repositories.SettingsRepository -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.combine -import java.math.BigDecimal - -class GetStakingNotificationMaxApyUseCase( - private val settingsRepository: SettingsRepository, - private val promoRepository: PromoRepository, - private val marketsTokenRepository: MarketsTokenRepository, -) { - - suspend operator fun invoke(): Flow { - val hideClickedFlow = promoRepository.isMarketsStakingNotificationHideClicked() - val walletFirstUsageDate = settingsRepository.getWalletFirstUsageDate() - val currentDate = Calendar.getInstance().timeInMillis - - return combine( - flow = hideClickedFlow, - flow2 = marketsTokenRepository.getMaxApy(), - ) { hideClicked, maxApy -> - val showStakingNotification = if (!hideClicked && walletFirstUsageDate != 0L) { - currentDate - walletFirstUsageDate > TWO_WEEKS_IN_MILLIS - } else { - false - } - - maxApy.takeIf { showStakingNotification } - } - } - - private companion object { - const val TWO_WEEKS_IN_MILLIS = 14 * 24 * 60 * 60 * 1000L - } -} \ No newline at end of file diff --git a/domain/markets/src/main/java/com/tangem/domain/markets/ShouldShowYieldModeMarketPromoUseCase.kt b/domain/markets/src/main/java/com/tangem/domain/markets/ShouldShowYieldModeMarketPromoUseCase.kt new file mode 100644 index 0000000000..599e7cefc3 --- /dev/null +++ b/domain/markets/src/main/java/com/tangem/domain/markets/ShouldShowYieldModeMarketPromoUseCase.kt @@ -0,0 +1,24 @@ +package com.tangem.domain.markets + +import com.tangem.domain.appcurrency.model.AppCurrency +import com.tangem.domain.markets.repositories.MarketsTokenRepository +import com.tangem.domain.promo.PromoRepository +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +class ShouldShowYieldModeMarketPromoUseCase( + private val promoRepository: PromoRepository, + private val marketsTokenRepository: MarketsTokenRepository, +) { + + operator fun invoke(appCurrency: AppCurrency, interval: TokenMarketListConfig.Interval): Flow { + val hideClickedFlow = promoRepository.isMarketsYieldSupplyNotificationHideClicked() + + return hideClickedFlow.map { hideClicked -> + !hideClicked && marketsTokenRepository.showYieldModePromo( + appCurrency = appCurrency, + interval = interval, + ) + } + } +} \ No newline at end of file diff --git a/domain/markets/src/main/java/com/tangem/domain/markets/repositories/MarketsTokenRepository.kt b/domain/markets/src/main/java/com/tangem/domain/markets/repositories/MarketsTokenRepository.kt index d813fdcc17..00a0e86540 100644 --- a/domain/markets/src/main/java/com/tangem/domain/markets/repositories/MarketsTokenRepository.kt +++ b/domain/markets/src/main/java/com/tangem/domain/markets/repositories/MarketsTokenRepository.kt @@ -1,11 +1,10 @@ package com.tangem.domain.markets.repositories +import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.markets.* import com.tangem.domain.models.account.DerivationIndex import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.wallet.UserWalletId -import kotlinx.coroutines.flow.Flow -import java.math.BigDecimal interface MarketsTokenRepository { @@ -56,5 +55,5 @@ interface MarketsTokenRepository { */ suspend fun getTokenExchanges(tokenId: CryptoCurrency.RawID): List - suspend fun getMaxApy(): Flow + suspend fun showYieldModePromo(appCurrency: AppCurrency, interval: TokenMarketListConfig.Interval): Boolean } \ No newline at end of file diff --git a/domain/promo/src/main/java/com/tangem/domain/promo/PromoRepository.kt b/domain/promo/src/main/java/com/tangem/domain/promo/PromoRepository.kt index 6e7afbdb02..de65de82b0 100644 --- a/domain/promo/src/main/java/com/tangem/domain/promo/PromoRepository.kt +++ b/domain/promo/src/main/java/com/tangem/domain/promo/PromoRepository.kt @@ -16,9 +16,9 @@ interface PromoRepository { suspend fun setNeverToShowTokenPromo(promoId: PromoId) - fun isMarketsStakingNotificationHideClicked(): Flow + fun isMarketsYieldSupplyNotificationHideClicked(): Flow - suspend fun setMarketsStakingNotificationHideClicked() + suspend fun setMarketsYieldSupplyNotificationHideClicked() suspend fun isMoonpayPromoActive(): Boolean // endregion diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/converter/MarketsTokenItemConverter.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/converter/MarketsTokenItemConverter.kt index b513310fb1..6bc58aab6e 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/converter/MarketsTokenItemConverter.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/converter/MarketsTokenItemConverter.kt @@ -38,7 +38,7 @@ internal class MarketsTokenItemConverter( trendType = value.getTrendType(), chartData = value.getChartData(), isUnder100kMarketCap = value.isUnderMarketCapLimit, - stakingRate = value.stakingRate?.format { percent() }?.let { + stakingRate = value.yieldRate?.format { percent() }?.let { resourceReference(R.string.markets_apy_placeholder, wrappedList(it)) }, updateTimestamp = value.updateTimestamp, diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/feed/FeedComponentModel.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/feed/FeedComponentModel.kt index ee02fa8424..6b7fb68da4 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/feed/FeedComponentModel.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/feed/FeedComponentModel.kt @@ -338,6 +338,7 @@ internal class FeedComponentModel @Inject constructor( SortByTypeUM.TopGainers -> TokenMarketListConfig.Order.TopGainers SortByTypeUM.TopLosers -> TokenMarketListConfig.Order.TopLosers SortByTypeUM.Staking -> TokenMarketListConfig.Order.Staking + SortByTypeUM.YieldSupply -> TokenMarketListConfig.Order.YieldSupply } } diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/state/FeedMarketsBatchFlowManager.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/state/FeedMarketsBatchFlowManager.kt index 7fa17ca9f5..b053465040 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/state/FeedMarketsBatchFlowManager.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/state/FeedMarketsBatchFlowManager.kt @@ -386,6 +386,7 @@ internal class FeedMarketsBatchFlowManager( TokenMarketListConfig.Order.TopGainers -> SortByTypeUM.TopGainers TokenMarketListConfig.Order.TopLosers -> SortByTypeUM.TopLosers TokenMarketListConfig.Order.Staking -> SortByTypeUM.Staking + TokenMarketListConfig.Order.YieldSupply -> SortByTypeUM.YieldSupply } } } \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/state/MarketsListUM.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/state/MarketsListUM.kt index 27e1c0daaf..88dc1834e7 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/state/MarketsListUM.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/state/MarketsListUM.kt @@ -41,6 +41,7 @@ enum class SortByTypeUM(val text: TextReference) { TopGainers(resourceReference(R.string.markets_sort_by_top_gainers_title)), TopLosers(resourceReference(R.string.markets_sort_by_top_losers_title)), Staking(resourceReference(R.string.common_staking)), + YieldSupply(resourceReference(R.string.markets_sort_by_yield_mode_title)), } @Immutable diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/analytics/MarketsListAnalyticsEvent.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/analytics/MarketsListAnalyticsEvent.kt index c5f92d0700..996e95d31b 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/analytics/MarketsListAnalyticsEvent.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/analytics/MarketsListAnalyticsEvent.kt @@ -24,6 +24,7 @@ internal sealed class MarketsListAnalyticsEvent( SortByTypeUM.TopGainers -> "Gainers" SortByTypeUM.TopLosers -> "Losers" SortByTypeUM.Staking -> "Staking" + SortByTypeUM.YieldSupply -> "Yield Supply" }, "Period" to when (interval) { MarketsListUM.TrendInterval.H24 -> "24h" @@ -32,12 +33,11 @@ internal sealed class MarketsListAnalyticsEvent( }, ), ) + class YieldModePromoShown : MarketsListAnalyticsEvent(event = "Notice - Yield Mode Promo") - class StakingPromoShown : MarketsListAnalyticsEvent(event = "Notice - Staking Promo") + class YieldModePromoClosed : MarketsListAnalyticsEvent(event = "Yield Mode Promo Closed") - class StakingPromoClosed : MarketsListAnalyticsEvent(event = "Staking Promo Closed") - - class StakingMoreInfoClicked : MarketsListAnalyticsEvent(event = "Staking More Info") + class YieldModeMoreInfoClicked : MarketsListAnalyticsEvent(event = "Yield Mode More Info") data class TokenSearched(val tokenFound: Boolean) : MarketsListAnalyticsEvent( event = "Token Searched", diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/MarketsListModel.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/MarketsListModel.kt index 600133bc7c..e214f30658 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/MarketsListModel.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/MarketsListModel.kt @@ -10,19 +10,20 @@ import com.tangem.core.ui.components.bottomsheets.state.BottomSheetState import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.markets.GetMarketsTokenListFlowUseCase -import com.tangem.domain.markets.GetStakingNotificationMaxApyUseCase +import com.tangem.domain.markets.ShouldShowYieldModeMarketPromoUseCase import com.tangem.domain.markets.TokenMarket +import com.tangem.domain.markets.TokenMarketListConfig import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.promo.PromoRepository import com.tangem.domain.settings.usercountry.GetUserCountryUseCase import com.tangem.domain.settings.usercountry.models.UserCountry import com.tangem.domain.settings.usercountry.models.UserCountryError -import com.tangem.domain.settings.usercountry.models.needApplyFCARestrictions import com.tangem.features.markets.tokenlist.impl.analytics.MarketsListAnalyticsEvent import com.tangem.features.markets.tokenlist.impl.model.statemanager.MarketsListBatchFlowManager import com.tangem.features.markets.tokenlist.impl.model.statemanager.MarketsListUMStateManager import com.tangem.features.markets.tokenlist.impl.ui.state.ListUM import com.tangem.features.markets.tokenlist.impl.ui.state.MarketsListItemUM +import com.tangem.features.markets.tokenlist.impl.ui.state.MarketsListUM.TrendInterval import com.tangem.features.markets.tokenlist.impl.ui.state.SortByTypeUM import com.tangem.utils.Provider import com.tangem.utils.coroutines.CoroutineDispatcherProvider @@ -31,7 +32,6 @@ import com.tangem.utils.coroutines.saveIn import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.* import kotlinx.coroutines.flow.* -import java.math.BigDecimal import javax.inject.Inject private const val UPDATE_QUOTES_TIMER_MILLIS = 60000L @@ -45,7 +45,7 @@ internal class MarketsListModel @Inject constructor( override val dispatchers: CoroutineDispatcherProvider, getMarketsTokenListFlowUseCase: GetMarketsTokenListFlowUseCase, getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, - getStakingNotificationMaxApyUseCase: GetStakingNotificationMaxApyUseCase, + shouldShowYieldModeMarketPromoUseCase: ShouldShowYieldModeMarketPromoUseCase, private val promoRepository: PromoRepository, private val getUserCountryUseCase: GetUserCountryUseCase, private val analyticsEventHandler: AnalyticsEventHandler, @@ -69,8 +69,6 @@ internal class MarketsListModel @Inject constructor( visibleItemsChanged = { visibleItemIds.value = it }, onRetryButtonClicked = { activeListManager.reload() }, onTokenClick = { onTokenUIClicked(it) }, - onStakingNotificationClick = { analyticsEventHandler.send(MarketsListAnalyticsEvent.StakingMoreInfoClicked()) }, - onStakingNotificationCloseClick = { onStakingNotificationCloseClick() }, onShowTokensUnder100kClicked = { analyticsEventHandler.send(MarketsListAnalyticsEvent.ShowTokens()) }, ) @@ -112,53 +110,62 @@ internal class MarketsListModel @Inject constructor( marketsListUMStateManager.isInSearchStateFlow.flatMapLatest { isInSearchMode -> if (isInSearchMode) { combine( - searchMarketsListManager.uiItems, - searchMarketsListManager.isInInitialLoadingErrorState, - searchMarketsListManager.isSearchNotFoundState, - getStakingNotificationMaxApyUseCase(), - getUserCountryUseCase.invoke(), - ) { uiItems, isInInitialLoadingErrorState, isSearchNotFoundState, stakingMaxApy, userCountry -> + flow = searchMarketsListManager.uiItems, + flow2 = searchMarketsListManager.isInInitialLoadingErrorState, + flow3 = searchMarketsListManager.isSearchNotFoundState, + flow4 = shouldShowYieldModeMarketPromoUseCase( + appCurrency = currentAppCurrency.value, + interval = marketsListUMStateManager.selectedInterval.toBatchRequestInterval(), + ), + flow5 = getUserCountryUseCase.invoke(), + ) { uiItems, isInInitialLoadingErrorState, isSearchNotFoundState, isYieldModePromo, userCountry -> MarketsItemsData( items = uiItems, isInErrorState = isInInitialLoadingErrorState, isSearchNotFound = isSearchNotFoundState, - stakingNotificationMaxApy = stakingMaxApy, + shouldShowYieldModePromo = isYieldModePromo, userCountry = userCountry, ) } } else { combine( - mainMarketsListManager.uiItems, - mainMarketsListManager.isInInitialLoadingErrorState, - getStakingNotificationMaxApyUseCase(), - getUserCountryUseCase.invoke(), - ) { uiItems, isInInitialLoadingErrorState, stakingNotificationMaxApy, userCountry -> + flow = mainMarketsListManager.uiItems, + flow2 = mainMarketsListManager.isInInitialLoadingErrorState, + flow3 = shouldShowYieldModeMarketPromoUseCase( + appCurrency = currentAppCurrency.value, + interval = marketsListUMStateManager.selectedInterval.toBatchRequestInterval(), + ), + flow4 = getUserCountryUseCase.invoke(), + ) { uiItems, isInInitialLoadingErrorState, shouldShowYieldModePromo, userCountry -> MarketsItemsData( items = uiItems, isInErrorState = isInInitialLoadingErrorState, isSearchNotFound = false, - stakingNotificationMaxApy = stakingNotificationMaxApy, + shouldShowYieldModePromo = shouldShowYieldModePromo, userCountry = userCountry, ) } } }.collect { marketsItemsData -> - val stakingNotificationMaxApy = marketsItemsData.stakingNotificationMaxApy?.takeUnless { - marketsItemsData.userCountry.getOrNull().needApplyFCARestrictions() - } - - if (marketsListUMStateManager.state.value.stakingNotificationMaxApy == null && - stakingNotificationMaxApy != null - ) { - analyticsEventHandler.send(MarketsListAnalyticsEvent.StakingPromoShown()) + val shouldShowYieldModePromo = marketsItemsData.shouldShowYieldModePromo + if (marketsListUMStateManager.state.value.marketsNotificationUM == null && shouldShowYieldModePromo) { + analyticsEventHandler.send(MarketsListAnalyticsEvent.YieldModePromoShown()) } marketsListUMStateManager.onUiItemsChanged( uiItems = marketsItemsData.items, isInErrorState = marketsItemsData.isInErrorState, isSearchNotFound = marketsItemsData.isSearchNotFound, - stakingNotificationMaxApy = marketsItemsData.stakingNotificationMaxApy?.takeUnless { - marketsItemsData.userCountry.getOrNull().needApplyFCARestrictions() + marketsNotificationUM = if (shouldShowYieldModePromo) { + MarketsNotificationUM.YieldSupplyPromo( + onClick = { + analyticsEventHandler.send(MarketsListAnalyticsEvent.YieldModeMoreInfoClicked()) + marketsListUMStateManager.selectedSortByType = SortByTypeUM.YieldSupply + }, + onCloseClick = { onYieldModeNotificationCloseClick() }, + ) + } else { + null }, ) } @@ -266,6 +273,14 @@ internal class MarketsListModel @Inject constructor( mainMarketsListManager.reload() } + fun TrendInterval.toBatchRequestInterval(): TokenMarketListConfig.Interval { + return when (this) { + TrendInterval.H24 -> TokenMarketListConfig.Interval.H24 + TrendInterval.D7 -> TokenMarketListConfig.Interval.WEEK + TrendInterval.M1 -> TokenMarketListConfig.Interval.MONTH + } + } + private fun initAnalytics() { containerBottomSheetState.onEach { bottomSheetState -> if (bottomSheetState == BottomSheetState.EXPANDED) { @@ -302,10 +317,10 @@ internal class MarketsListModel @Inject constructor( }.saveIn(updateQuotesJob) } - private fun onStakingNotificationCloseClick() { - analyticsEventHandler.send(MarketsListAnalyticsEvent.StakingPromoClosed()) + private fun onYieldModeNotificationCloseClick() { + analyticsEventHandler.send(MarketsListAnalyticsEvent.YieldModePromoClosed()) modelScope.launch { - promoRepository.setMarketsStakingNotificationHideClicked() + promoRepository.setMarketsYieldSupplyNotificationHideClicked() } } @@ -313,7 +328,7 @@ internal class MarketsListModel @Inject constructor( val items: ImmutableList, val isInErrorState: Boolean, val isSearchNotFound: Boolean, - val stakingNotificationMaxApy: BigDecimal?, + val shouldShowYieldModePromo: Boolean, val userCountry: Either, ) } \ No newline at end of file diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/MarketsNotificationUM.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/MarketsNotificationUM.kt new file mode 100644 index 0000000000..5870289d78 --- /dev/null +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/MarketsNotificationUM.kt @@ -0,0 +1,22 @@ +package com.tangem.features.markets.tokenlist.impl.model + +import com.tangem.core.ui.components.notifications.NotificationConfig +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.resourceReference +import com.tangem.features.markets.impl.R + +internal sealed class MarketsNotificationUM(val config: NotificationConfig) { + + data class YieldSupplyPromo( + val onClick: () -> Unit, + val onCloseClick: () -> Unit, + ) : MarketsNotificationUM( + config = NotificationConfig( + iconResId = R.drawable.img_yield_supply_in_market_notification, + title = resourceReference(R.string.markets_yield_supply_banner_title), + subtitle = TextReference.EMPTY, + onClick = onClick, + onCloseClick = onCloseClick, + ), + ) +} \ No newline at end of file diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/converters/MarketsTokenItemConverter.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/converters/MarketsTokenItemConverter.kt index ec31aac834..2e0926eaf5 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/converters/MarketsTokenItemConverter.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/converters/MarketsTokenItemConverter.kt @@ -38,7 +38,7 @@ internal class MarketsTokenItemConverter( trendType = value.getTrendType(), chartData = value.getChartData(), isUnder100kMarketCap = value.isUnderMarketCapLimit, - stakingRate = value.stakingRate?.format { percent() }?.let { + stakingRate = value.yieldRate?.format { percent() }?.let { resourceReference(R.string.markets_apy_placeholder, wrappedList(it)) }, updateTimestamp = value.updateTimestamp, diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/statemanager/MarketsListBatchFlowManager.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/statemanager/MarketsListBatchFlowManager.kt index 03b8b24eeb..4847ff333a 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/statemanager/MarketsListBatchFlowManager.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/statemanager/MarketsListBatchFlowManager.kt @@ -343,6 +343,7 @@ internal class MarketsListBatchFlowManager( SortByTypeUM.TopGainers -> TokenMarketListConfig.Order.TopGainers SortByTypeUM.TopLosers -> TokenMarketListConfig.Order.TopLosers SortByTypeUM.Staking -> TokenMarketListConfig.Order.Staking + SortByTypeUM.YieldSupply -> TokenMarketListConfig.Order.YieldSupply } } diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/statemanager/MarketsListUMStateManager.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/statemanager/MarketsListUMStateManager.kt index f2c6ee64d3..33f89173a9 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/statemanager/MarketsListUMStateManager.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/model/statemanager/MarketsListUMStateManager.kt @@ -8,6 +8,7 @@ import com.tangem.core.ui.event.triggeredEvent import com.tangem.core.ui.extensions.resourceReference import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.features.markets.impl.R +import com.tangem.features.markets.tokenlist.impl.model.MarketsNotificationUM import com.tangem.features.markets.tokenlist.impl.ui.state.* import com.tangem.utils.Provider import kotlinx.collections.immutable.ImmutableList @@ -16,7 +17,6 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.update -import java.math.BigDecimal @Stable @Suppress("LongParameterList") @@ -26,8 +26,6 @@ internal class MarketsListUMStateManager( private val visibleItemsChanged: (itemsKeys: List) -> Unit, private val onRetryButtonClicked: () -> Unit, private val onTokenClick: (MarketsListItemUM) -> Unit, - private val onStakingNotificationClick: () -> Unit, - private val onStakingNotificationCloseClick: () -> Unit, private val onShowTokensUnder100kClicked: () -> Unit, ) { @@ -92,25 +90,25 @@ internal class MarketsListUMStateManager( isInErrorState: Boolean, isSearchNotFound: Boolean, uiItems: ImmutableList, - stakingNotificationMaxApy: BigDecimal?, + marketsNotificationUM: MarketsNotificationUM?, ) { - state.update { + state.update { currentState -> when { isInErrorState -> { - it.copy( + currentState.copy( list = ListUM.LoadingError(onRetryClicked = onRetryButtonClicked), ) } isSearchNotFound -> { - it.copy(list = ListUM.SearchNothingFound) + currentState.copy(list = ListUM.SearchNothingFound) } uiItems.isEmpty() -> { - it.copy(list = ListUM.Loading) + currentState.copy(list = ListUM.Loading) } else -> { - it.updateItems( + currentState.updateItems( newItems = uiItems, - stakingNotificationMaxApy = stakingNotificationMaxApy, + marketsNotificationUM = marketsNotificationUM, ) } } @@ -119,7 +117,7 @@ internal class MarketsListUMStateManager( private fun MarketsListUM.updateItems( newItems: ImmutableList, - stakingNotificationMaxApy: BigDecimal?, + marketsNotificationUM: MarketsNotificationUM?, ): MarketsListUM { val currentState = this @@ -131,7 +129,7 @@ internal class MarketsListUMStateManager( .copy( showUnder100kTokensNotificationWasHidden = currentState.showUnder100kButtonAlreadyPressed(), ), - stakingNotificationMaxApy = stakingNotificationMaxApy, + marketsNotificationUM = marketsNotificationUM, ) } @@ -225,12 +223,7 @@ internal class MarketsListUMStateManager( onOptionClicked = ::onBottomSheetOptionClicked, ), ), - stakingNotificationMaxApy = null, - onStakingNotificationClick = { - onStakingNotificationClick() - selectedSortByType = SortByTypeUM.Staking - }, - onStakingNotificationCloseClick = onStakingNotificationCloseClick, + marketsNotificationUM = null, ) private fun onBottomSheetOptionClicked(sortByTypeUM: SortByTypeUM) { diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/MarketsList.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/MarketsList.kt index 5b80958c46..0930d3c1e4 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/MarketsList.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/MarketsList.kt @@ -22,7 +22,6 @@ import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.res.vectorResource -import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp @@ -38,19 +37,17 @@ import com.tangem.core.ui.components.buttons.segmentedbutton.SegmentedButtons import com.tangem.core.ui.components.fields.SearchBar import com.tangem.core.ui.components.fields.entity.SearchBarUM import com.tangem.core.ui.components.keyboardAsState -import com.tangem.core.ui.components.notifications.NotificationConfig import com.tangem.core.ui.event.consumedEvent import com.tangem.core.ui.extensions.* -import com.tangem.core.ui.format.bigdecimal.format -import com.tangem.core.ui.format.bigdecimal.percent import com.tangem.core.ui.res.LocalMainBottomSheetColor import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.features.markets.impl.R +import com.tangem.features.markets.tokenlist.impl.model.MarketsNotificationUM import com.tangem.features.markets.tokenlist.impl.ui.components.MarketsListLazyColumn import com.tangem.features.markets.tokenlist.impl.ui.components.MarketsListSortByBottomSheet -import com.tangem.features.markets.tokenlist.impl.ui.components.StakingInMarketsPromoNotification +import com.tangem.features.markets.tokenlist.impl.ui.components.YieldSupplyInMarketsPromoNotification import com.tangem.features.markets.tokenlist.impl.ui.preview.MarketChartListItemPreviewDataProvider import com.tangem.features.markets.tokenlist.impl.ui.state.ListUM import com.tangem.features.markets.tokenlist.impl.ui.state.MarketsListUM @@ -58,7 +55,6 @@ import com.tangem.features.markets.tokenlist.impl.ui.state.SortByBottomSheetCont import com.tangem.features.markets.tokenlist.impl.ui.state.SortByTypeUM import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList -import java.math.BigDecimal private const val SHOW_MORE_KEY = "privacyPolicy" @@ -180,38 +176,38 @@ private fun ColumnScope.Content(state: MarketsListUM, modifier: Modifier = Modif ) } + val marketsNotification = state.marketsNotificationUM AnimatedVisibility( state.isInSearchMode.not() && - state.stakingNotificationMaxApy != null && - state.selectedSortBy != SortByTypeUM.Staking, + state.selectedSortBy != SortByTypeUM.YieldSupply, ) { val showMore = stringResourceSafe(R.string.common_show_more) - val description = stringResourceSafe( - R.string.markets_staking_banner_description_placeholder, - showMore, - ) - val clickableDescription = buildAnnotatedString { - append(description.substringBefore(showMore)) + when (marketsNotification) { + is MarketsNotificationUM.YieldSupplyPromo -> { + val description = stringResourceSafe( + R.string.markets_yield_supply_banner_description, + showMore, + ) - pushStringAnnotation(SHOW_MORE_KEY, "") - appendColored(showMore, TangemTheme.colors.text.accent) - pop() + val clickableDescription = annotatedReference { + append(description.substringBefore(showMore)) + + pushStringAnnotation(SHOW_MORE_KEY, "") + appendColored(showMore, TangemTheme.colors.text.accent) + pop() + } + + YieldSupplyInMarketsPromoNotification( + config = marketsNotification.config.copy( + subtitle = clickableDescription, + ), + modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing12), + ) + } + else -> { /* no-op */ + } } - - StakingInMarketsPromoNotification( - config = NotificationConfig( - iconResId = R.drawable.img_staking_in_market_notification, - title = resourceReference( - R.string.markets_staking_banner_title, - wrappedList(state.stakingNotificationMaxApy.format { percent() }), - ), - subtitle = annotatedReference(clickableDescription), - onClick = state.onStakingNotificationClick, - onCloseClick = state.onStakingNotificationCloseClick, - ), - modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing12), - ) } } } @@ -420,9 +416,10 @@ private fun Preview() { onDismissRequest = {}, content = SortByBottomSheetContentUM(selectedOption = SortByTypeUM.Rating) {}, ), - stakingNotificationMaxApy = BigDecimal(0.12345), - onStakingNotificationClick = {}, - onStakingNotificationCloseClick = {}, + marketsNotificationUM = MarketsNotificationUM.YieldSupplyPromo( + onClick = {}, + onCloseClick = {}, + ), ), onHeaderSizeChange = {}, bottomSheetState = BottomSheetState.EXPANDED, diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/components/YieldSupplyInMarketsPromoNotification.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/components/YieldSupplyInMarketsPromoNotification.kt new file mode 100644 index 0000000000..e2f16f2735 --- /dev/null +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/components/YieldSupplyInMarketsPromoNotification.kt @@ -0,0 +1,147 @@ +package com.tangem.features.markets.tokenlist.impl.ui.components + +import android.content.res.Configuration +import androidx.annotation.DrawableRes +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.* +import androidx.compose.material3.Text +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.layout.onSizeChanged +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.tangem.core.ui.R +import com.tangem.core.ui.components.SpacerH +import com.tangem.core.ui.components.notifications.CloseableIconButton +import com.tangem.core.ui.components.notifications.NotificationConfig +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.resolveAnnotatedReference +import com.tangem.core.ui.extensions.resolveReference +import com.tangem.core.ui.extensions.stringReference +import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.TangemThemePreview + +private val bgColor = Color(0x2684B0D7) +private val borderColor = Color(0x2684B0D7) + +@Composable +fun YieldSupplyInMarketsPromoNotification(config: NotificationConfig, modifier: Modifier = Modifier) { + var textHeightDp by remember { mutableStateOf(0.dp) } + + Box( + modifier = modifier + .fillMaxWidth() + .border( + width = 1.dp, + shape = TangemTheme.shapes.roundedCornersXMedium, + color = borderColor, + ) + .clip(shape = TangemTheme.shapes.roundedCornersXMedium) + .background(bgColor) + .clickable { config.onClick?.invoke() }, + ) { + PromoImage( + iconRes = config.iconResId, + modifier = Modifier.height(textHeightDp), + ) + PromoText( + title = config.title, + subtitle = config.subtitle, + onSizeChange = { textHeightDp = it }, + ) + CloseableIconButton( + onClick = config.onCloseClick, + modifier = Modifier.align(alignment = Alignment.TopEnd), + iconTint = TangemTheme.colors.icon.secondary, + ) + } +} + +@Composable +private fun PromoImage(@DrawableRes iconRes: Int, modifier: Modifier = Modifier) { + Box( + modifier = modifier.padding(vertical = 8.dp), + contentAlignment = Alignment.Center, + ) { + Image( + painter = painterResource(id = iconRes), + contentDescription = null, + contentScale = ContentScale.FillWidth, + modifier = Modifier + .requiredWidth(80.dp) + .wrapContentHeight(Alignment.CenterVertically, unbounded = true), + ) + } +} + +@Composable +private fun PromoText(title: TextReference?, subtitle: TextReference, onSizeChange: (Dp) -> Unit) { + val density = LocalDensity.current + + Box( + modifier = Modifier.onSizeChanged { + with(density) { onSizeChange(it.height.toDp()) } + }, + ) { + TextsBlock( + title = title, + subtitle = subtitle, + modifier = Modifier + .wrapContentHeight() + .align(Alignment.CenterStart) + .padding(start = 80.dp, top = 12.dp, end = 12.dp, bottom = 12.dp), + ) + } +} + +@Composable +private fun TextsBlock(title: TextReference?, subtitle: TextReference, modifier: Modifier = Modifier) { + Column(modifier = modifier) { + val titleText = title?.resolveReference() + + if (titleText != null) { + Text( + text = titleText, + color = TangemTheme.colors.text.primary1, + style = TangemTheme.typography.button, + ) + + SpacerH(height = TangemTheme.dimens.spacing2) + } + + Text( + text = subtitle.resolveAnnotatedReference(), + color = TangemTheme.colors.text.secondary, + style = TangemTheme.typography.caption2, + ) + } +} + +// region Preview +@Preview(showBackground = true, widthDp = 360) +@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +private fun RingPromoNotification_Preview() { + TangemThemePreview { + YieldSupplyInMarketsPromoNotification( + config = NotificationConfig( + title = stringReference("Activate Yield Mode"), + subtitle = stringReference("Power up your assets while supplying them with instant access. Show more"), + iconResId = R.drawable.img_yield_supply_in_market_notification, + onCloseClick = { }, + ), + ) + } +} + +// endregion \ No newline at end of file diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/state/MarketsListUM.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/state/MarketsListUM.kt index da29b428d1..8404856a87 100644 --- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/state/MarketsListUM.kt +++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/tokenlist/impl/ui/state/MarketsListUM.kt @@ -8,8 +8,8 @@ import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resourceReference import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.features.markets.impl.R +import com.tangem.features.markets.tokenlist.impl.model.MarketsNotificationUM import kotlinx.collections.immutable.ImmutableList -import java.math.BigDecimal internal data class MarketsListUM( val list: ListUM, @@ -19,9 +19,7 @@ internal data class MarketsListUM( val selectedInterval: TrendInterval, val onIntervalClick: (TrendInterval) -> Unit, val onSortByButtonClick: () -> Unit, - val stakingNotificationMaxApy: BigDecimal?, - val onStakingNotificationClick: () -> Unit, - val onStakingNotificationCloseClick: () -> Unit, + val marketsNotificationUM: MarketsNotificationUM?, ) { val isInSearchMode get() = searchBar.isActive @@ -40,6 +38,7 @@ enum class SortByTypeUM(val text: TextReference) { TopGainers(resourceReference(R.string.markets_sort_by_top_gainers_title)), TopLosers(resourceReference(R.string.markets_sort_by_top_losers_title)), Staking(resourceReference(R.string.common_staking)), + YieldSupply(resourceReference(R.string.yield_module_earn_sheet_title)), } @Immutable