Updated on 2026-08-14

This commit is contained in:
Tangem 2026-06-23 15:14:49 +02:00
parent 9cde8a7ba0
commit 183cb93c1a
13 changed files with 107 additions and 46 deletions

View file

@ -27,13 +27,13 @@ import com.tangem.domain.notifications.SendPushTokenUseCase
import com.tangem.domain.notifications.models.ApplicationId import com.tangem.domain.notifications.models.ApplicationId
import com.tangem.domain.notifications.models.NotificationsError import com.tangem.domain.notifications.models.NotificationsError
import com.tangem.domain.onramp.FetchHotCryptoUseCase import com.tangem.domain.onramp.FetchHotCryptoUseCase
import com.tangem.domain.stories.GetStoryContentUseCase
import com.tangem.domain.stories.models.StoryContentIds
import com.tangem.domain.quotes.multi.MultiQuoteUpdater import com.tangem.domain.quotes.multi.MultiQuoteUpdater
import com.tangem.domain.settings.DeleteDeprecatedLogsUseCase import com.tangem.domain.settings.DeleteDeprecatedLogsUseCase
import com.tangem.domain.settings.IncrementAppLaunchCounterUseCase import com.tangem.domain.settings.IncrementAppLaunchCounterUseCase
import com.tangem.domain.settings.usercountry.FetchUserCountryUseCase import com.tangem.domain.settings.usercountry.FetchUserCountryUseCase
import com.tangem.domain.staking.FetchStakingOptionsUseCase import com.tangem.domain.staking.FetchStakingOptionsUseCase
import com.tangem.domain.stories.GetStoryContentUseCase
import com.tangem.domain.stories.models.StoryContentIds
import com.tangem.domain.wallets.usecase.AssociateWalletsWithApplicationIdUseCase import com.tangem.domain.wallets.usecase.AssociateWalletsWithApplicationIdUseCase
import com.tangem.domain.wallets.usecase.GetSavedWalletsCountUseCase import com.tangem.domain.wallets.usecase.GetSavedWalletsCountUseCase
import com.tangem.domain.wallets.usecase.UpdateRemoteWalletsInfoUseCase import com.tangem.domain.wallets.usecase.UpdateRemoteWalletsInfoUseCase
@ -268,8 +268,12 @@ internal class MainViewModel @Inject constructor(
onShownBalanceToastAction() onShownBalanceToastAction()
} }
}, },
startIconId = if (settings.isBalanceHidden) {
R.drawable.ic_eye_off_outline_24
} else {
R.drawable.ic_eye_outline_24
},
) )
messageSender.send(message) messageSender.send(message)
} }
} }

View file

@ -178,7 +178,7 @@ private fun BottomSheetIcon(icon: MessageBottomSheetUM.Icon, modifier: Modifier
} }
val backgroundColor = when (icon.backgroundType) { val backgroundColor = when (icon.backgroundType) {
MessageBottomSheetUM.Icon.BackgroundType.Unspecified -> Color.Unspecified MessageBottomSheetUM.Icon.BackgroundType.Unspecified -> TangemTheme.colors3.bg.tertiary
MessageBottomSheetUM.Icon.BackgroundType.SameAsTint -> { MessageBottomSheetUM.Icon.BackgroundType.SameAsTint -> {
if (tint == Color.Unspecified) Color.Unspecified else tint.copy(alpha = 0.1f) if (tint == Color.Unspecified) Color.Unspecified else tint.copy(alpha = 0.1f)
} }
@ -217,7 +217,7 @@ private fun BottomSheetVector(vector: MessageBottomSheetUM.Vector, modifier: Mod
} }
val backgroundColor = when (vector.backgroundType) { val backgroundColor = when (vector.backgroundType) {
MessageBottomSheetUM.Vector.BackgroundType.Unspecified -> Color.Unspecified MessageBottomSheetUM.Vector.BackgroundType.Unspecified -> TangemTheme.colors3.bg.tertiary
MessageBottomSheetUM.Vector.BackgroundType.SameAsTint -> tint MessageBottomSheetUM.Vector.BackgroundType.SameAsTint -> tint
MessageBottomSheetUM.Vector.BackgroundType.Accent -> TangemTheme.colors3.bg.status.infoSubtle MessageBottomSheetUM.Vector.BackgroundType.Accent -> TangemTheme.colors3.bg.status.infoSubtle
MessageBottomSheetUM.Vector.BackgroundType.Informative -> TangemTheme.colors3.bg.status.infoSubtle MessageBottomSheetUM.Vector.BackgroundType.Informative -> TangemTheme.colors3.bg.status.infoSubtle

View file

@ -41,7 +41,11 @@ fun TangemTopSnackbar(snackbarMessage: SnackbarMessage, modifier: Modifier = Mod
val action = snackbarMessage.action val action = snackbarMessage.action
val hasAction = actionLabel != null && action != null val hasAction = actionLabel != null && action != null
var isTextOverflowing by remember { mutableStateOf(false) } var isTextOverflowing by remember(
snackbarMessage.message,
snackbarMessage.startIconId,
hasAction,
) { mutableStateOf(false) }
val shape = if (isTextOverflowing) { val shape = if (isTextOverflowing) {
RoundedCornerShape(TangemTheme.dimens2.x5) RoundedCornerShape(TangemTheme.dimens2.x5)
} else { } else {
@ -55,7 +59,7 @@ fun TangemTopSnackbar(snackbarMessage: SnackbarMessage, modifier: Modifier = Mod
.clip(shape) .clip(shape)
.hazeEffectTangem() .hazeEffectTangem()
.sizeIn(minHeight = TangemTheme.dimens2.x11) .sizeIn(minHeight = TangemTheme.dimens2.x11)
.padding(start = TangemTheme.dimens2.x5, end = TangemTheme.dimens2.x1) .padding(start = TangemTheme.dimens2.x5, end = TangemTheme.dimens2.x3)
.padding(vertical = TangemTheme.dimens2.x1), .padding(vertical = TangemTheme.dimens2.x1),
verticalArrangement = Arrangement.Center, verticalArrangement = Arrangement.Center,
) { ) {
@ -81,7 +85,10 @@ fun TangemTopSnackbar(snackbarMessage: SnackbarMessage, modifier: Modifier = Mod
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
maxLines = 1, maxLines = 1,
style = TangemTheme.typography.body2, style = TangemTheme.typography.body2,
onTextLayout = { if (hasAction) isTextOverflowing = it.hasVisualOverflow }, onTextLayout = { layoutResult ->
val isOverflowing = hasAction && layoutResult.hasVisualOverflow
if (isTextOverflowing != isOverflowing) isTextOverflowing = isOverflowing
},
) )
SpacerW(TangemTheme.dimens2.x4) SpacerW(TangemTheme.dimens2.x4)

View file

@ -10,14 +10,17 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawWithContent import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.draw.innerShadow
import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.BlendMode import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.rotate import androidx.compose.ui.graphics.drawscope.rotate
import androidx.compose.ui.graphics.shadow.Shadow
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.haze.hazeForegroundEffectTangem import com.tangem.core.ui.components.haze.hazeForegroundEffectTangem
import com.tangem.core.ui.extensions.conditionalCompose import com.tangem.core.ui.extensions.conditionalCompose
@ -232,15 +235,28 @@ enum class TangemMessageEffect(val isAnimatable: Boolean) {
None -> if (isInDarkTheme) Color(0x1AFFFFFF) else Color.Transparent None -> if (isInDarkTheme) Color(0x1AFFFFFF) else Color.Transparent
} }
} }
/**
* Color of the inner shadow that glows inward evenly from every edge over the card body,
* or `null` when the effect doesn't have one. [None] uses a subtle white 15% highlight
* (Figma: inner shadow X0 Y0 blur 74 spread 0, #FFFFFF · 15%).
*/
@Suppress("MagicNumber")
fun getInnerGlowColor(isInDarkTheme: Boolean): Color? = when (this) {
None -> if (isInDarkTheme) Color(0x26FFFFFF) else null
else -> null
}
} }
/** Applies a message effect background to the [Modifier] based on the provided [messageEffect] and [radius] */ /** Applies a message effect background to the [Modifier] based on the provided [messageEffect] and [radius] */
@Suppress("LongMethod")
@Composable @Composable
fun Modifier.messageEffectBackground(messageEffect: TangemMessageEffect, radius: Dp, contentColor: Color): Modifier { fun Modifier.messageEffectBackground(messageEffect: TangemMessageEffect, radius: Dp, contentColor: Color): Modifier {
val isInDarkTheme = LocalIsInDarkTheme.current val isInDarkTheme = LocalIsInDarkTheme.current
val borderGradientColors = remember(messageEffect, isInDarkTheme) { messageEffect.getBorderGradient(isInDarkTheme) } val borderGradientColors = remember(messageEffect, isInDarkTheme) { messageEffect.getBorderGradient(isInDarkTheme) }
val gradientColors = remember(messageEffect, isInDarkTheme) { messageEffect.getColorGradient(isInDarkTheme) } val gradientColors = remember(messageEffect, isInDarkTheme) { messageEffect.getColorGradient(isInDarkTheme) }
val gradientTint = remember(messageEffect, isInDarkTheme) { messageEffect.getGradientTint(isInDarkTheme) } val gradientTint = remember(messageEffect, isInDarkTheme) { messageEffect.getGradientTint(isInDarkTheme) }
val innerGlowColor = remember(messageEffect, isInDarkTheme) { messageEffect.getInnerGlowColor(isInDarkTheme) }
val angle by if (messageEffect.isAnimatable) { val angle by if (messageEffect.isAnimatable) {
LocalMessageEffectAnimation.current.offsetState LocalMessageEffectAnimation.current.offsetState
@ -293,14 +309,28 @@ fun Modifier.messageEffectBackground(messageEffect: TangemMessageEffect, radius:
blendMode = BlendMode.SrcIn, blendMode = BlendMode.SrcIn,
) )
} }
drawRect( // None ignores contentColor — its body is the white-10% frosted haze, not a solid fill
color = contentColor, if (messageEffect != TangemMessageEffect.None) {
topLeft = Offset(padding, padding), drawRect(
size = Size(size.width - 2 * padding, size.height - 2 * padding), color = contentColor,
) topLeft = Offset(padding, padding),
size = Size(size.width - 2 * padding, size.height - 2 * padding),
)
}
drawContent() drawContent()
} }
} }
.conditionalCompose(innerGlowColor != null) {
innerShadow(
shape = RoundedCornerShape(0.dp),
shadow = Shadow(
radius = 10.dp,
spread = 10.dp,
color = innerGlowColor ?: Color.Transparent,
offset = DpOffset(0.dp, 0.dp),
),
)
}
} }
@Composable @Composable

View file

@ -76,7 +76,7 @@ fun BigDecimalFiatFormat.defaultAmount(): BigDecimalFormat = BigDecimalFormat {
) )
} }
} else { } else {
formatter.format(value) formatter.format(value.zeroIfRoundsToZero(FIAT_MARKET_DEFAULT_DIGITS))
.replace(formatterCurrency.getSymbol(locale), fiatCurrencySymbol) .replace(formatterCurrency.getSymbol(locale), fiatCurrencySymbol)
} }
} }
@ -94,7 +94,7 @@ fun BigDecimalFiatFormatStyled.defaultAmount(spanStyleReference: SpanStyleRefere
val formattingAmount = if (value.isLessThanThreshold()) { val formattingAmount = if (value.isLessThanThreshold()) {
FIAT_FORMAT_THRESHOLD FIAT_FORMAT_THRESHOLD
} else { } else {
value value.zeroIfRoundsToZero(FIAT_MARKET_DEFAULT_DIGITS)
} }
val decimalSeparator = (formatter as? DecimalFormat)?.decimalFormatSymbols?.decimalSeparator val decimalSeparator = (formatter as? DecimalFormat)?.decimalFormatSymbols?.decimalSeparator
@ -273,6 +273,9 @@ fun BigDecimalFiatFormat.optionalDecimals(): BigDecimalFormat = BigDecimalFormat
private fun BigDecimal.isLessThanThreshold() = this > BigDecimal.ZERO && this < FIAT_FORMAT_THRESHOLD private fun BigDecimal.isLessThanThreshold() = this > BigDecimal.ZERO && this < FIAT_FORMAT_THRESHOLD
private fun BigDecimal.zeroIfRoundsToZero(scale: Int): BigDecimal =
if (setScale(scale, RoundingMode.HALF_UP).signum() == 0) BigDecimal.ZERO else this
/** /**
* Returns amount with correct scale * Returns amount with correct scale
*/ */

View file

@ -100,6 +100,38 @@ internal class BigDecimalFiatFormatTest {
.isEqualTo("<" + "0,01".addSymbolWithSpaceRight(usdSymbol)) .isEqualTo("<" + "0,01".addSymbolWithSpaceRight(usdSymbol))
} }
@Test
fun `defaultAmount tiny negative rounding to zero is formatted without sign`() {
val testValue = BigDecimal("-0.0001")
val formatted = testValue.format {
fiat(
fiatCurrencyCode = usdCurrencyCode,
fiatCurrencySymbol = usdSymbol,
locale = testLocale,
).defaultAmount()
}
Truth.assertThat(formatted)
.isEqualTo("0.00".addUsdSymbolLeft())
}
@Test
fun `defaultAmount negative rounding away from zero keeps sign`() {
val testValue = BigDecimal("-0.005")
val formatted = testValue.format {
fiat(
fiatCurrencyCode = usdCurrencyCode,
fiatCurrencySymbol = usdSymbol,
locale = testLocale,
).defaultAmount()
}
Truth.assertThat(formatted)
.isEqualTo("-" + "0.01".addUsdSymbolLeft())
}
// === approximateAmount() === // === approximateAmount() ===
@Test @Test

View file

@ -307,7 +307,6 @@ internal class DefaultFeedEntryComponent @AssistedInject constructor(
preselectedNetworkId: String? = null, preselectedNetworkId: String? = null,
): DefaultEarnComponent.Params = DefaultEarnComponent.Params( ): DefaultEarnComponent.Params = DefaultEarnComponent.Params(
onBackClick = onBack, onBackClick = onBack,
onSearchClicked = clickIntents::openSearch,
preselectedEarnType = preselectedEarnType, preselectedEarnType = preselectedEarnType,
preselectedNetworkId = preselectedNetworkId, preselectedNetworkId = preselectedNetworkId,
) )

View file

@ -27,7 +27,10 @@ import com.tangem.core.ui.components.bottomsheets.state.BottomSheetState
import com.tangem.core.ui.components.haze.hazeEffectTangem import com.tangem.core.ui.components.haze.hazeEffectTangem
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.core.ui.decompose.ComposableModularBottomSheetContentComponent import com.tangem.core.ui.decompose.ComposableModularBottomSheetContentComponent
import com.tangem.core.ui.ds.topbar.TangemTopBar
import com.tangem.core.ui.ds.topbar.TangemTopBarType
import com.tangem.core.ui.extensions.clickableSingle import com.tangem.core.ui.extensions.clickableSingle
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.LocalMainBottomSheetColor import com.tangem.core.ui.res.LocalMainBottomSheetColor
import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.LocalRedesignEnabled
@ -36,7 +39,7 @@ import com.tangem.domain.models.earn.PreselectedEarnType
import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioComponent import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioComponent
import com.tangem.features.feed.components.feed.FeedBottomSheetRoute import com.tangem.features.feed.components.feed.FeedBottomSheetRoute
import com.tangem.features.feed.model.earn.EarnModel import com.tangem.features.feed.model.earn.EarnModel
import com.tangem.features.feed.ui.components.FeedSearchBar import com.tangem.features.feed.ui.LocalIsOpenedInBottomSheet
import com.tangem.features.feed.ui.earn.EarnContent import com.tangem.features.feed.ui.earn.EarnContent
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@ -60,9 +63,13 @@ internal class DefaultEarnComponent(
val background = LocalMainBottomSheetColor.current.value val background = LocalMainBottomSheetColor.current.value
val state by earnModel.state.collectAsStateWithLifecycle() val state by earnModel.state.collectAsStateWithLifecycle()
if (LocalRedesignEnabled.current) { if (LocalRedesignEnabled.current) {
FeedSearchBar( TangemTopBar(
isSearchBarClickable = bottomSheetState.value == BottomSheetState.EXPANDED, title = resourceReference(R.string.earn_title),
feedListSearchBar = state.feedListSearchBar, type = if (LocalIsOpenedInBottomSheet.current) {
TangemTopBarType.BottomSheet
} else {
TangemTopBarType.Default
},
startContent = { startContent = {
Icon( Icon(
imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back_28), imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back_28),
@ -136,7 +143,6 @@ internal class DefaultEarnComponent(
@Serializable @Serializable
data class Params( data class Params(
val onBackClick: () -> Unit, val onBackClick: () -> Unit,
val onSearchClicked: (source: String) -> Unit,
val preselectedEarnType: PreselectedEarnType? = null, val preselectedEarnType: PreselectedEarnType? = null,
val preselectedNetworkId: String? = null, val preselectedNetworkId: String? = null,
) )

View file

@ -8,7 +8,6 @@ import com.arkivanov.decompose.router.slot.dismiss
import com.tangem.common.routing.AppRoute import com.tangem.common.routing.AppRoute
import com.tangem.common.routing.AppRouter import com.tangem.common.routing.AppRouter
import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer import com.tangem.core.decompose.model.ParamsContainer
@ -22,8 +21,8 @@ import com.tangem.domain.markets.TokenMarketInfo
import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.earn.EarnNetworks import com.tangem.domain.models.earn.EarnNetworks
import com.tangem.domain.models.earn.EarnTokenWithCurrency import com.tangem.domain.models.earn.EarnTokenWithCurrency
import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioManager
import com.tangem.domain.models.earn.PreselectedEarnType import com.tangem.domain.models.earn.PreselectedEarnType
import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioManager
import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioManager.AnalyticsParams.Companion.CategoryEarn import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioManager.AnalyticsParams.Companion.CategoryEarn
import com.tangem.features.feed.components.earn.DefaultEarnComponent import com.tangem.features.feed.components.earn.DefaultEarnComponent
import com.tangem.features.feed.components.earn.EarnNetworkFilterComponent import com.tangem.features.feed.components.earn.EarnNetworkFilterComponent
@ -400,7 +399,6 @@ internal class EarnModel @Inject constructor(
onNetworkFilterClick = ::onNetworkFilterClick, onNetworkFilterClick = ::onNetworkFilterClick,
onTypeFilterClick = ::onTypeFilterClick, onTypeFilterClick = ::onTypeFilterClick,
onScroll = ::onMostlyUsedScrolled, onScroll = ::onMostlyUsedScrolled,
onSearchBarClicked = { params.onSearchClicked(AnalyticsParam.ScreensSources.Earn.value) },
), ),
) )
} }

View file

@ -1,10 +1,8 @@
package com.tangem.features.feed.model.earn.state package com.tangem.features.feed.model.earn.state
import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.ui.extensions.TextReference
import com.tangem.features.feed.model.earn.state.transformers.EarnUMTransformer import com.tangem.features.feed.model.earn.state.transformers.EarnUMTransformer
import com.tangem.features.feed.ui.earn.state.* import com.tangem.features.feed.ui.earn.state.*
import com.tangem.features.feed.ui.feed.state.FeedListSearchBar
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
@ -36,10 +34,6 @@ internal class EarnStateController @Inject constructor() {
onNetworkFilterClick = {}, onNetworkFilterClick = {},
onTypeFilterClick = {}, onTypeFilterClick = {},
onSliderScroll = {}, onSliderScroll = {},
feedListSearchBar = FeedListSearchBar(
placeholderText = TextReference.EMPTY,
onBarClick = {},
),
) )
} }
} }

View file

@ -1,16 +1,12 @@
package com.tangem.features.feed.model.earn.state.transformers package com.tangem.features.feed.model.earn.state.transformers
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.features.feed.impl.R
import com.tangem.features.feed.ui.earn.state.EarnUM import com.tangem.features.feed.ui.earn.state.EarnUM
import com.tangem.features.feed.ui.feed.state.FeedListSearchBar
internal class UpdateEarnUMInitialStateTransformer( internal class UpdateEarnUMInitialStateTransformer(
private val onBackClick: () -> Unit, private val onBackClick: () -> Unit,
private val onNetworkFilterClick: () -> Unit, private val onNetworkFilterClick: () -> Unit,
private val onTypeFilterClick: () -> Unit, private val onTypeFilterClick: () -> Unit,
private val onScroll: () -> Unit, private val onScroll: () -> Unit,
private val onSearchBarClicked: () -> Unit,
) : EarnUMTransformer { ) : EarnUMTransformer {
override fun transform(prevState: EarnUM): EarnUM { override fun transform(prevState: EarnUM): EarnUM {
@ -19,10 +15,6 @@ internal class UpdateEarnUMInitialStateTransformer(
onNetworkFilterClick = onNetworkFilterClick, onNetworkFilterClick = onNetworkFilterClick,
onTypeFilterClick = onTypeFilterClick, onTypeFilterClick = onTypeFilterClick,
onSliderScroll = onScroll, onSliderScroll = onScroll,
feedListSearchBar = FeedListSearchBar(
onBarClick = onSearchBarClicked,
placeholderText = resourceReference(id = R.string.markets_search_title_placeholder),
),
) )
} }
} }

View file

@ -22,12 +22,14 @@ import com.tangem.core.ui.components.*
import com.tangem.core.ui.components.currency.icon.CurrencyIconState import com.tangem.core.ui.components.currency.icon.CurrencyIconState
import com.tangem.core.ui.components.list.InfiniteListHandler import com.tangem.core.ui.components.list.InfiniteListHandler
import com.tangem.core.ui.decorations.roundedShapeItemDecoration import com.tangem.core.ui.decorations.roundedShapeItemDecoration
import com.tangem.core.ui.extensions.* import com.tangem.core.ui.extensions.conditional
import com.tangem.core.ui.extensions.conditionalCompose
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.* import com.tangem.core.ui.res.*
import com.tangem.domain.models.earn.EarnType import com.tangem.domain.models.earn.EarnType
import com.tangem.features.feed.ui.earn.components.* import com.tangem.features.feed.ui.earn.components.*
import com.tangem.features.feed.ui.earn.state.* import com.tangem.features.feed.ui.earn.state.*
import com.tangem.features.feed.ui.feed.state.FeedListSearchBar
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
private const val EARN_LOAD_MORE_BUFFER = 3 private const val EARN_LOAD_MORE_BUFFER = 3
@ -663,10 +665,6 @@ private fun previewEarnUM(
onNetworkFilterClick = {}, onNetworkFilterClick = {},
onTypeFilterClick = {}, onTypeFilterClick = {},
onSliderScroll = {}, onSliderScroll = {},
feedListSearchBar = FeedListSearchBar(
placeholderText = TextReference.Str("Search tokens & news"),
onBarClick = {},
),
) )
private const val PLACEHOLDER_ITEMS_COUNT = 8 private const val PLACEHOLDER_ITEMS_COUNT = 8

View file

@ -1,7 +1,6 @@
package com.tangem.features.feed.ui.earn.state package com.tangem.features.feed.ui.earn.state
import androidx.compose.runtime.Immutable import androidx.compose.runtime.Immutable
import com.tangem.features.feed.ui.feed.state.FeedListSearchBar
@Immutable @Immutable
internal data class EarnUM( internal data class EarnUM(
@ -12,5 +11,4 @@ internal data class EarnUM(
val onNetworkFilterClick: () -> Unit, val onNetworkFilterClick: () -> Unit,
val onTypeFilterClick: () -> Unit, val onTypeFilterClick: () -> Unit,
val onSliderScroll: () -> Unit, val onSliderScroll: () -> Unit,
val feedListSearchBar: FeedListSearchBar,
) )