From 61a1a25067a9e8d9b5670b057026c9565be44c9d Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 16 Jan 2026 15:06:01 +0100 Subject: [PATCH] Updated on 2026-08-14 --- .../com/tangem/common/ui/news/ArticleCard.kt | 7 +- .../ui/components/label/entity/LabelUM.kt | 1 + .../tangem/features/feed/ui/feed/FeedList.kt | 167 ++++++++++-------- .../feed/ui/market/list/MarketsList.kt | 2 +- 4 files changed, 98 insertions(+), 79 deletions(-) diff --git a/common/ui/src/main/java/com/tangem/common/ui/news/ArticleCard.kt b/common/ui/src/main/java/com/tangem/common/ui/news/ArticleCard.kt index d73e4e8486..06cf750dac 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/news/ArticleCard.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/news/ArticleCard.kt @@ -174,7 +174,12 @@ private fun Tags(tags: ImmutableList, modifier: Modifier = Modifier) { val expandIndicator = remember { ContextualFlowRowOverflow.expandIndicator { val remainingItems = tags.size - shownItemCount - Label(state = LabelUM(TextReference.Str("${StringsSigns.PLUS}$remainingItems"))) + Label( + state = LabelUM( + text = TextReference.Str("${StringsSigns.PLUS}$remainingItems"), + maxLines = 1, + ), + ) } } ContextualFlowRow( diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/label/entity/LabelUM.kt b/core/ui/src/main/java/com/tangem/core/ui/components/label/entity/LabelUM.kt index 131469bd96..1a6f10a087 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/label/entity/LabelUM.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/label/entity/LabelUM.kt @@ -12,6 +12,7 @@ data class LabelUM( @DrawableRes val icon: Int? = null, val onIconClick: (() -> Unit)? = null, val onClick: (() -> Unit)? = null, + val maxLines: Int = Int.MAX_VALUE, ) @Immutable diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/FeedList.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/FeedList.kt index 4a5825783f..5cf729b8ba 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/FeedList.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/FeedList.kt @@ -1,6 +1,9 @@ package com.tangem.features.feed.ui.feed -import androidx.compose.animation.* +import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.togetherWith import androidx.compose.foundation.* import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.* @@ -60,7 +63,7 @@ internal fun FeedListHeader(feedListSearchBar: FeedListSearchBar, modifier: Modi modifier = modifier .drawBehind { drawRect(background) } .padding(horizontal = 16.dp) - .padding(bottom = 12.dp), + .padding(bottom = 8.dp), ) } @@ -70,6 +73,7 @@ internal fun FeedList(state: FeedListUM, modifier: Modifier = Modifier) { AnimatedContent( modifier = modifier, targetState = state.globalState, + transitionSpec = { fadeIn() togetherWith fadeOut() }, ) { animatedState -> when (animatedState) { is GlobalFeedState.Loading -> { @@ -84,6 +88,7 @@ internal fun FeedList(state: FeedListUM, modifier: Modifier = Modifier) { FeedListGlobalError( onRetryClick = animatedState.onRetryClicked, modifier = Modifier.drawBehind { drawRect(background) }, + currentDate = state.currentDate, ) } is GlobalFeedState.Content -> { @@ -130,83 +135,67 @@ private fun FeedListContent(state: FeedListUM, modifier: Modifier = Modifier) { modifier = modifier .fillMaxSize() .verticalScroll(rememberScrollState()) + .padding(bottom = WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding()) .drawBehind { drawRect(background) }, ) { - Column( - modifier = Modifier - .fillMaxSize() - .padding(WindowInsets.navigationBars.asPaddingValues()), - ) { - SpacerH(20.dp) + DateBlock(state.currentDate) + SpacerH(32.dp) - Text( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 20.dp), - text = stringResourceSafe(R.string.feed_market_and_news), - style = TangemTheme.typography.h2, - color = TangemTheme.colors.text.primary1, - ) - Text( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 20.dp), - text = state.currentDate, - style = TangemTheme.typography.h2, - color = TangemTheme.colors.text.tertiary, - ) + MarketBlock( + marketChart = state.marketChartConfig.marketCharts[SortByTypeUM.Rating], + feedListCallbacks = state.feedListCallbacks, + ) - SpacerH(32.dp) + NewsBlock( + news = state.news, + feedListCallbacks = state.feedListCallbacks, + trendingArticle = state.trendingArticle, + ) - AnimatedVisibility(state.marketChartConfig.marketCharts[SortByTypeUM.Rating] != null) { - val marketChart = remember(state.marketChartConfig.marketCharts[SortByTypeUM.Rating]) { - state.marketChartConfig.marketCharts[SortByTypeUM.Rating] - } - if (marketChart != null) { - MarketBlock( - marketChart = marketChart, - feedListCallbacks = state.feedListCallbacks, - ) - } - } - - NewsBlock( - news = state.news, - feedListCallbacks = state.feedListCallbacks, - trendingArticle = state.trendingArticle, - ) - - MarketPulseBlock( - marketChartConfig = state.marketChartConfig, - feedListCallbacks = state.feedListCallbacks, - ) - } + MarketPulseBlock( + marketChartConfig = state.marketChartConfig, + feedListCallbacks = state.feedListCallbacks, + ) } } @Composable -private fun MarketBlock(marketChart: MarketChartUM, feedListCallbacks: FeedListCallbacks) { - Column(modifier = Modifier.fillMaxWidth()) { - Header( - title = { - Text( - text = stringResourceSafe(R.string.markets_common_title), - style = TangemTheme.typography.h3, - color = TangemTheme.colors.text.primary1, - ) - }, - onSeeAllClick = { feedListCallbacks.onMarketOpenClick(SortByTypeUM.Rating) }, - ) +private fun MarketBlock(marketChart: MarketChartUM?, feedListCallbacks: FeedListCallbacks) { + AnimatedContent( + targetState = marketChart, + label = "MarketBlockChartAnimation", + transitionSpec = { fadeIn() togetherWith fadeOut() }, + ) { currentChart -> + when (currentChart) { + is MarketChartUM.Content, + MarketChartUM.Loading, + is MarketChartUM.LoadingError, + -> { + Column(modifier = Modifier.fillMaxWidth()) { + Header( + title = { + Text( + text = stringResourceSafe(R.string.markets_common_title), + style = TangemTheme.typography.h3, + color = TangemTheme.colors.text.primary1, + ) + }, + onSeeAllClick = { feedListCallbacks.onMarketOpenClick(SortByTypeUM.Rating) }, + ) - SpacerH(12.dp) + SpacerH(12.dp) - Charts( - onItemClick = feedListCallbacks.onMarketItemClick, - modifier = Modifier.padding(horizontal = 16.dp), - marketChart = marketChart, - ) + Charts( + onItemClick = feedListCallbacks.onMarketItemClick, + modifier = Modifier.padding(horizontal = 16.dp), + marketChart = currentChart, + ) - SpacerH(32.dp) + SpacerH(32.dp) + } + } + null -> Unit + } } } @@ -490,16 +479,19 @@ private fun FilterChip(sortByTypeUM: SortByTypeUM, isSelected: Boolean, onClick: } @Composable -private fun FeedListGlobalError(onRetryClick: () -> Unit, modifier: Modifier = Modifier) { +private fun FeedListGlobalError(onRetryClick: () -> Unit, currentDate: String, modifier: Modifier = Modifier) { val background = LocalMainBottomSheetColor.current.value - Box( - modifier = modifier - .fillMaxSize() - .drawBehind { drawRect(background) } - .padding(16.dp), - contentAlignment = Alignment.Center, - ) { - UnableToLoadData(onRetryClick = onRetryClick) + Column(modifier) { + DateBlock(currentDate) + Box( + modifier = Modifier + .fillMaxSize() + .drawBehind { drawRect(background) } + .padding(16.dp), + contentAlignment = Alignment.Center, + ) { + UnableToLoadData(onRetryClick = onRetryClick) + } } } @@ -519,7 +511,6 @@ private fun NewsErrorBlock(onRetryClick: () -> Unit) { onSeeAllClick = {}, ) SpacerH(12.dp) - BlockCard( modifier = Modifier.padding(horizontal = 16.dp), colors = TangemBlockCardColors.copy(containerColor = TangemTheme.colors.background.action), @@ -531,9 +522,31 @@ private fun NewsErrorBlock(onRetryClick: () -> Unit) { .padding(vertical = 35.dp, horizontal = 10.dp), ) } + SpacerH(32.dp) } } +@Composable +private fun ColumnScope.DateBlock(currentDate: String) { + SpacerH(20.dp) + Text( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp), + text = stringResourceSafe(R.string.feed_market_and_news), + style = TangemTheme.typography.h2, + color = TangemTheme.colors.text.primary1, + ) + Text( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp), + text = currentDate, + style = TangemTheme.typography.h2, + color = TangemTheme.colors.text.tertiary, + ) +} + private const val DEFAULT_CHART_SIZE_IN_MARKET = 5 private const val FOURTH_ITEM_INDEX = 3 private const val GRADIENT_START = 0f diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/MarketsList.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/MarketsList.kt index d9194f707f..368afe2910 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/MarketsList.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/MarketsList.kt @@ -83,7 +83,7 @@ internal fun TopBarWithSearch( modifier = Modifier .drawBehind { drawRect(background) } .padding(horizontal = 16.dp) - .padding(bottom = 12.dp), + .padding(bottom = 8.dp), state = marketsSearchBar.searchBarUM, colors = TangemSearchBarDefaults.defaultTextFieldColors.copy( focusedContainerColor = TangemTheme.colors.field.focused,