From 84198eb1037fe003d1bed2acb7046a1135f97837 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 17 Jul 2026 00:31:23 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../feed/components/FeedEntryChildFactory.kt | 6 - .../components/earn/DefaultEarnComponent.kt | 66 ++-- .../DefaultMarketsTokenDetailsComponent.kt | 27 +- .../api/MarketsPortfolioComponent.kt | 30 -- .../impl/DefaultMarketsPortfolioComponent.kt | 87 ----- .../impl/analytics/PortfolioAnalyticsEvent.kt | 41 --- .../portfolio/impl/di/ComponentModule.kt | 20 - .../details/portfolio/impl/di/ModelModule.kt | 20 - .../impl/model/MarketsPortfolioDelegate.kt | 347 ------------------ .../impl/model/MarketsPortfolioModel.kt | 170 --------- .../impl/model/MarketsPortfolioRoute.kt | 17 - .../impl/model/PortfolioTokenUMConverter.kt | 72 ---- .../details/portfolio/impl/ui/MyPortfolio.kt | 333 ----------------- .../portfolio/impl/ui/PortfolioItem.kt | 156 -------- .../impl/ui/PortfolioQuickActions.kt | 263 ------------- .../preview/PreviewMyPortfolioUMProvider.kt | 142 ------- .../portfolio/impl/ui/state/MyPortfolioUM.kt | 37 -- .../impl/ui/state/PortfolioTokenUM.kt | 33 -- .../list/DefaultMarketsTokenListComponent.kt | 60 ++- .../details/DefaultNewsDetailsComponent.kt | 102 ++--- .../news/list/DefaultNewsListComponent.kt | 66 ++-- .../feed/model/feed/FeedComponentModel.kt | 14 +- .../details/MarketsTokenDetailsModel.kt | 20 +- .../details/converter/MetricsConverter.kt | 7 +- .../converter/TokenMarketInfoConverter.kt | 2 - .../model/news/details/NewsDetailsModel.kt | 3 - .../details/NewsDetailsPaginationManager.kt | 2 - .../feed/model/news/list/NewsListModel.kt | 3 - .../statemanager/NewsListBatchFlowManager.kt | 7 +- .../tangem/features/feed/ui/EntryContent.kt | 84 +---- .../feed/ui/components/FeedSearchBar.kt | 60 +-- .../features/feed/ui/earn/EarnContent.kt | 163 ++------ .../earn/components/BestOpportunitiesEmpty.kt | 41 +-- .../BestOpportunitiesEmptyFiltered.kt | 38 +- .../EarnFilterByNetworkBottomSheet.kt | 183 --------- .../components/EarnFilterByTypeBottomSheet.kt | 57 --- .../feed/ui/earn/components/EarnListItem.kt | 135 ++----- .../ui/earn/components/EarnListPlaceholder.kt | 79 ---- .../feed/ui/earn/components/FilterButtons.kt | 61 +-- .../feed/ui/earn/components/MostlyUsedCard.kt | 96 +---- .../earn/components/MostlyUsedPlaceholder.kt | 40 +- .../tangem/features/feed/ui/feed/FeedList.kt | 19 +- .../feed/ui/feed/components/BlockHeader.kt | 62 ++-- .../ui/feed/components/ChartsFilterChip.kt | 51 --- .../feed/ui/feed/components/DateBlock.kt | 32 -- .../feed/ui/feed/components/EarnBlock.kt | 99 +---- .../ui/feed/components/FeedListLoading.kt | 179 +++------ .../feed/ui/feed/components/MarketsBlock.kt | 66 +--- .../feed/ui/feed/components/NewsBlock.kt | 62 +--- .../feed/ui/feed/components/NewsSlider.kt | 3 - .../feed/components/articles/ArticleCard.kt | 29 +- .../feed/components/articles/ArticleCardV1.kt | 273 -------------- .../feed/components/articles/ArticleHeader.kt | 84 +---- .../feed/components/articles/ArticleInfo.kt | 61 --- .../components/articles/ArticleLoadingCard.kt | 105 +----- .../articles/ShowMoreArticlesCard.kt | 8 +- .../feed/ui/feed/components/articles/Tags.kt | 65 ++-- .../detailed/MarketsTokenDetailsContent.kt | 202 +--------- .../detailed/MarketsTokenDetailsTitle.kt | 29 +- .../components/ExchangesBottomSheet.kt | 148 +------- .../detailed/components/InfoBottomSheet.kt | 67 +--- .../market/detailed/components/InfoPoint.kt | 189 +--------- .../detailed/components/InsightsBlock.kt | 210 +---------- .../market/detailed/components/LinksBlock.kt | 212 +---------- .../detailed/components/ListedOnBlock.kt | 130 +------ .../detailed/components/MetricsBlock.kt | 175 +-------- .../detailed/components/MetricsCards.kt | 198 +++++----- .../components/PricePerformanceBlock.kt | 269 -------------- .../detailed/components/ScoreStarsBlock.kt | 104 +----- .../detailed/components/SecurityScoreBlock.kt | 163 +------- .../components/SecurityScoreBottomSheet.kt | 182 +-------- .../components/TokenMarketDetailsBody.kt | 244 +----------- .../feed/ui/market/list/MarketsList.kt | 146 +------- .../list/components/MarketsListLazyColumn.kt | 18 +- .../feed/ui/market/list/components/Options.kt | 86 +---- .../ui/news/details/NewsDetailsContent.kt | 56 +-- .../news/details/components/ArticleDetail.kt | 156 +------- .../components/NewsDetailsPlaceholder.kt | 96 +---- .../ui/news/details/components/QuickRecap.kt | 47 +-- .../details/components/RelatedNewsItem.kt | 77 +--- .../details/components/RelatedTokensBlock.kt | 72 +--- .../feed/ui/news/list/NewsListContent.kt | 59 +-- .../list/components/NewsListLazyColumn.kt | 3 - .../feed/model/feed/FeedComponentModelTest.kt | 4 - 84 files changed, 601 insertions(+), 7129 deletions(-) delete mode 100644 features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/api/MarketsPortfolioComponent.kt delete mode 100644 features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/DefaultMarketsPortfolioComponent.kt delete mode 100644 features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/analytics/PortfolioAnalyticsEvent.kt delete mode 100644 features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/di/ComponentModule.kt delete mode 100644 features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/di/ModelModule.kt delete mode 100644 features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/model/MarketsPortfolioDelegate.kt delete mode 100644 features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/model/MarketsPortfolioModel.kt delete mode 100644 features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/model/MarketsPortfolioRoute.kt delete mode 100644 features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/model/PortfolioTokenUMConverter.kt delete mode 100644 features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/MyPortfolio.kt delete mode 100644 features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/PortfolioItem.kt delete mode 100644 features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/PortfolioQuickActions.kt delete mode 100644 features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/preview/PreviewMyPortfolioUMProvider.kt delete mode 100644 features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/state/MyPortfolioUM.kt delete mode 100644 features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/state/PortfolioTokenUM.kt delete mode 100644 features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/ChartsFilterChip.kt delete mode 100644 features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleCardV1.kt delete mode 100644 features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleInfo.kt delete mode 100644 features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/PricePerformanceBlock.kt diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/FeedEntryChildFactory.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/FeedEntryChildFactory.kt index fa763968ca..42896e7e2d 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/FeedEntryChildFactory.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/FeedEntryChildFactory.kt @@ -5,7 +5,6 @@ import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.decompose.navigation.Route -import com.tangem.core.ui.DesignFeatureToggles import com.tangem.core.ui.decompose.ComposableModularBottomSheetContentComponent import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.wallet.UserWalletId @@ -15,7 +14,6 @@ import com.tangem.features.feed.components.earn.DefaultEarnComponent import com.tangem.features.feed.components.feed.DefaultFeedComponent import com.tangem.features.feed.components.feed.DefaultFeedComponent.FeedParams import com.tangem.features.feed.components.market.details.DefaultMarketsTokenDetailsComponent -import com.tangem.features.feed.components.market.details.portfolio.api.MarketsPortfolioComponent import com.tangem.features.feed.components.market.details.portfolioblock.PortfolioBlockComponent import com.tangem.features.feed.components.market.list.DefaultMarketsTokenListComponent import com.tangem.features.feed.components.news.details.DefaultNewsDetailsComponent @@ -32,12 +30,10 @@ import javax.inject.Inject @Suppress("LongParameterList") internal class FeedEntryChildFactory @Inject constructor( private val analyticsEventHandler: AnalyticsEventHandler, - private val portfolioComponentFactory: MarketsPortfolioComponent.Factory, private val portfolioBlockComponentFactory: PortfolioBlockComponent.Factory, private val addToPortfolioComponentFactory: AddToPortfolioComponent.Factory, private val manageFundsComponentFactory: ManageFundsComponent.Factory, private val promoBannersBlockComponentFactory: PromoBannersBlockComponent.Factory, - private val designFeatureToggles: DesignFeatureToggles, private val forYouComponentFactory: ForYouComponent.Factory, private val tokenSummaryComponentFactory: TokenSummaryComponent.Factory, private val marketingBannerComponentFactory: MarketingBannerComponent.Factory, @@ -100,9 +96,7 @@ internal class FeedEntryChildFactory @Inject constructor( appComponentContext = appComponentContext, params = child.params, analyticsEventHandler = analyticsEventHandler, - portfolioComponentFactory = portfolioComponentFactory, portfolioBlockComponentFactory = portfolioBlockComponentFactory, - designFeatureToggles = designFeatureToggles, addToPortfolioComponentFactory = addToPortfolioComponentFactory, manageFundsComponentFactory = manageFundsComponentFactory, marketingBannerComponentFactory = marketingBannerComponentFactory, diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/earn/DefaultEarnComponent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/earn/DefaultEarnComponent.kt index 24d2d2fead..1293e7330e 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/earn/DefaultEarnComponent.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/earn/DefaultEarnComponent.kt @@ -21,8 +21,6 @@ import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.decompose.context.childByContext import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.core.ui.R -import com.tangem.core.ui.components.appbar.TangemTopAppBar -import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM import com.tangem.core.ui.components.bottomsheets.state.BottomSheetState import com.tangem.core.ui.components.haze.hazeEffectTangem import com.tangem.core.ui.decompose.ComposableBottomSheetComponent @@ -31,9 +29,6 @@ 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.resourceReference -import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.LocalMainBottomSheetColor -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.domain.models.earn.PreselectedEarnType import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioComponent @@ -60,44 +55,31 @@ internal class DefaultEarnComponent( @Composable override fun Title(bottomSheetState: State) { - val background = LocalMainBottomSheetColor.current.value val state by earnModel.state.collectAsStateWithLifecycle() - if (LocalRedesignEnabled.current) { - TangemTopBar( - title = resourceReference(R.string.earn_title), - type = if (LocalIsOpenedInBottomSheet.current) { - TangemTopBarType.BottomSheet - } else { - TangemTopBarType.Default - }, - startContent = { - Icon( - imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back_28), - contentDescription = null, - tint = TangemTheme.colors2.graphic.neutral.primary, - modifier = Modifier - .size(TangemTheme.dimens2.x11) - .clip(CircleShape) - .hazeEffectTangem { blurRadius = 8.dp } - .clickableSingle( - onClick = state.onBackClick, - enabled = bottomSheetState.value == BottomSheetState.EXPANDED, - ) - .padding(TangemTheme.dimens2.x2), - ) - }, - ) - } else { - TangemTopAppBar( - containerColor = background, - title = stringResourceSafe(R.string.earn_title), - startButton = TopAppBarButtonUM.Icon( - iconRes = R.drawable.ic_back_24, - onClicked = state.onBackClick, - isEnabled = bottomSheetState.value == BottomSheetState.EXPANDED, - ), - ) - } + TangemTopBar( + title = resourceReference(R.string.earn_title), + type = if (LocalIsOpenedInBottomSheet.current) { + TangemTopBarType.BottomSheet + } else { + TangemTopBarType.Default + }, + startContent = { + Icon( + imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back_28), + contentDescription = null, + tint = TangemTheme.colors2.graphic.neutral.primary, + modifier = Modifier + .size(TangemTheme.dimens2.x11) + .clip(CircleShape) + .hazeEffectTangem { blurRadius = 8.dp } + .clickableSingle( + onClick = state.onBackClick, + enabled = bottomSheetState.value == BottomSheetState.EXPANDED, + ) + .padding(TangemTheme.dimens2.x2), + ) + }, + ) } @Composable diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/DefaultMarketsTokenDetailsComponent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/DefaultMarketsTokenDetailsComponent.kt index e49e5ee19c..7cdcaab3ee 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/DefaultMarketsTokenDetailsComponent.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/DefaultMarketsTokenDetailsComponent.kt @@ -18,7 +18,6 @@ import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.decompose.context.child import com.tangem.core.decompose.context.childByContext import com.tangem.core.decompose.model.getOrCreateModel -import com.tangem.core.ui.DesignFeatureToggles import com.tangem.core.ui.components.bottomsheets.state.BottomSheetState import com.tangem.core.ui.decompose.ComposableBottomSheetComponent import com.tangem.core.ui.decompose.ComposableModularBottomSheetContentComponent @@ -29,7 +28,6 @@ import com.tangem.domain.markets.TokenMarketParams import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioComponent import com.tangem.features.commonfeatures.api.managefunds.ManageFundsComponent -import com.tangem.features.feed.components.market.details.portfolio.api.MarketsPortfolioComponent import com.tangem.features.feed.components.market.details.portfolioblock.PortfolioBlockComponent import com.tangem.features.feed.components.market.details.portfolioblock.PortfolioBlockParentClickIntents import com.tangem.features.feed.model.market.details.MarketsTokenDetailsModel @@ -46,8 +44,6 @@ import kotlinx.serialization.Serializable internal class DefaultMarketsTokenDetailsComponent( appComponentContext: AppComponentContext, analyticsEventHandler: AnalyticsEventHandler, - designFeatureToggles: DesignFeatureToggles, - portfolioComponentFactory: MarketsPortfolioComponent.Factory, portfolioBlockComponentFactory: PortfolioBlockComponent.Factory, val params: Params, private val addToPortfolioComponentFactory: AddToPortfolioComponent.Factory, @@ -69,21 +65,8 @@ internal class DefaultMarketsTokenDetailsComponent( params = MarketingBannerComponent.Params.Standalone(requestFlow = model.marketingRequest), ) - private val portfolioComponent: MarketsPortfolioComponent? = - if (updatedParams.shouldShowPortfolio && !designFeatureToggles.isRedesignEnabled) { - portfolioComponentFactory.create( - context = child("my_portfolio"), - params = MarketsPortfolioComponent.Params( - updatedParams.token, - analyticsParams = analyticsParams?.source?.let { MarketsPortfolioComponent.AnalyticsParams(it) }, - ), - ) - } else { - null - } - private val portfolioBlockComponent: PortfolioBlockComponent? = - if (updatedParams.shouldShowPortfolio && designFeatureToggles.isRedesignEnabled) { + if (updatedParams.shouldShowPortfolio) { portfolioBlockComponentFactory.create( context = child("portfolio_block"), params = PortfolioBlockComponent.Params(token = updatedParams.token), @@ -126,11 +109,9 @@ internal class DefaultMarketsTokenDetailsComponent( when (state) { is TokenNetworksState.NetworksAvailable -> { portfolioBlockComponent?.setTokenNetworks(state.networks) - portfolioComponent?.setTokenNetworks(state.networks) } TokenNetworksState.NoNetworksAvailable -> { portfolioBlockComponent?.setNoNetworksAvailable() - portfolioComponent?.setNoNetworksAvailable() } else -> {} } @@ -180,7 +161,6 @@ internal class DefaultMarketsTokenDetailsComponent( val state by model.state.collectAsStateWithLifecycle() MarketsTokenDetailsTitle( state = state, - backgroundColor = LocalMainBottomSheetColor.current.value, isBackButtonEnabled = bottomSheetState.value == BottomSheetState.EXPANDED, onBackClick = { params.onBackClicked() }, ) @@ -211,11 +191,6 @@ internal class DefaultMarketsTokenDetailsComponent( modifier = modifier, backgroundColor = LocalMainBottomSheetColor.current.value, state = state, - portfolioBlock = portfolioComponent?.let { component -> - { blockModifier -> - component.Content(blockModifier) - } - }, portfolioFloatingBlock = portfolioBlockComponent?.let { component -> { blockModifier -> component.Content(blockModifier) diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/api/MarketsPortfolioComponent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/api/MarketsPortfolioComponent.kt deleted file mode 100644 index 9e689855ae..0000000000 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/api/MarketsPortfolioComponent.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.tangem.features.feed.components.market.details.portfolio.api - -import androidx.compose.runtime.Stable -import com.tangem.core.decompose.factory.ComponentFactory -import com.tangem.core.ui.decompose.ComposableContentComponent -import com.tangem.domain.markets.TokenMarketInfo -import com.tangem.domain.markets.TokenMarketParams -import kotlinx.serialization.Serializable - -@Deprecated("Will be removed in favor of PortfolioComponent with redesigned UI") -@Stable -interface MarketsPortfolioComponent : ComposableContentComponent { - - @Serializable - data class Params( - val token: TokenMarketParams, - val analyticsParams: AnalyticsParams?, - ) - - @Serializable - data class AnalyticsParams( - val source: String, - ) - - fun setTokenNetworks(networks: List) - - fun setNoNetworksAvailable() - - interface Factory : ComponentFactory -} \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/DefaultMarketsPortfolioComponent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/DefaultMarketsPortfolioComponent.kt deleted file mode 100644 index 8e86530324..0000000000 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/DefaultMarketsPortfolioComponent.kt +++ /dev/null @@ -1,87 +0,0 @@ -package com.tangem.features.feed.components.market.details.portfolio.impl - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Stable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Modifier -import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.arkivanov.decompose.ComponentContext -import com.arkivanov.decompose.extensions.compose.subscribeAsState -import com.arkivanov.decompose.router.slot.childSlot -import com.arkivanov.decompose.router.slot.dismiss -import com.tangem.core.decompose.context.AppComponentContext -import com.tangem.core.decompose.context.childByContext -import com.tangem.core.decompose.model.getOrCreateModel -import com.tangem.core.ui.decompose.ComposableBottomSheetComponent -import com.tangem.domain.markets.TokenMarketInfo -import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioComponent -import com.tangem.features.feed.components.market.details.portfolio.api.MarketsPortfolioComponent -import com.tangem.features.feed.components.market.details.portfolio.impl.model.MarketsPortfolioModel -import com.tangem.features.feed.components.market.details.portfolio.impl.model.MarketsPortfolioRoute -import com.tangem.features.feed.components.market.details.portfolio.impl.ui.MyPortfolio -import com.tangem.features.tokenreceive.TokenReceiveComponent -import dagger.assisted.Assisted -import dagger.assisted.AssistedFactory -import dagger.assisted.AssistedInject - -@Stable -internal class DefaultMarketsPortfolioComponent @AssistedInject constructor( - @Assisted context: AppComponentContext, - @Assisted private val params: MarketsPortfolioComponent.Params, - private val tokenReceiveComponentFactory: TokenReceiveComponent.Factory, - private val addToPortfolioComponentFactory: AddToPortfolioComponent.Factory, -) : AppComponentContext by context, MarketsPortfolioComponent { - - private val model: MarketsPortfolioModel = getOrCreateModel(params) - - private val bottomSheetSlot = childSlot( - source = model.bottomSheetNavigation, - serializer = MarketsPortfolioRoute.serializer(), - handleBackButton = false, - childFactory = ::bottomSheetChild, - ) - - override fun setTokenNetworks(networks: List) { - model.setTokenNetworks(networks) - } - - override fun setNoNetworksAvailable() { - model.setNoNetworksAvailable() - } - - @Composable - override fun Content(modifier: Modifier) { - val state by model.state.collectAsStateWithLifecycle() - val bottomSheet by bottomSheetSlot.subscribeAsState() - - MyPortfolio(modifier = modifier, state = state) - bottomSheet.child?.instance?.BottomSheet() - } - - private fun bottomSheetChild( - config: MarketsPortfolioRoute, - componentContext: ComponentContext, - ): ComposableBottomSheetComponent = when (config) { - MarketsPortfolioRoute.AddToPortfolio -> addToPortfolioComponentFactory.create( - context = childByContext(componentContext), - params = AddToPortfolioComponent.Params( - addToPortfolioManager = model.addToPortfolioManager, - ), - ) - is MarketsPortfolioRoute.TokenReceive -> tokenReceiveComponentFactory.create( - context = childByContext(componentContext), - params = TokenReceiveComponent.Params( - config = config.config, - onDismiss = model.bottomSheetNavigation::dismiss, - ), - ) - } - - @AssistedFactory - interface Factory : MarketsPortfolioComponent.Factory { - override fun create( - context: AppComponentContext, - params: MarketsPortfolioComponent.Params, - ): DefaultMarketsPortfolioComponent - } -} \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/analytics/PortfolioAnalyticsEvent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/analytics/PortfolioAnalyticsEvent.kt deleted file mode 100644 index 80c831f780..0000000000 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/analytics/PortfolioAnalyticsEvent.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.tangem.features.feed.components.market.details.portfolio.impl.analytics - -import com.tangem.common.ui.markets.action.TokenActionsBSContentUM -import com.tangem.core.analytics.models.AnalyticsEvent - -internal class PortfolioAnalyticsEvent( - event: String, - params: Map = emptyMap(), -) : AnalyticsEvent(category = "Markets / Chart", event = event, params = params) { - - data class EventBuilder( - val tokenSymbol: String, - val source: String?, - ) { - - fun addToPortfolioClicked() = PortfolioAnalyticsEvent( - event = "Button - Add To Portfolio", - params = buildMap { - put("Token", tokenSymbol) - if (source != null) put("Source", source) - }, - ) - - fun quickActionClick(actionUM: TokenActionsBSContentUM.Action, blockchainName: String) = - PortfolioAnalyticsEvent( - event = when (actionUM) { - TokenActionsBSContentUM.Action.Buy -> "Button - Buy" - TokenActionsBSContentUM.Action.Receive -> "Button - Receive" - TokenActionsBSContentUM.Action.Exchange -> "Button - Swap" - TokenActionsBSContentUM.Action.Stake -> "Button - Stake" - TokenActionsBSContentUM.Action.YieldMode -> "Button - Yield Mode" - else -> "error" - }, - params = buildMap { - put("Token", tokenSymbol) - if (source != null) put("Source", source) - put("blockchain", blockchainName) - }, - ) - } -} \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/di/ComponentModule.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/di/ComponentModule.kt deleted file mode 100644 index beb881a924..0000000000 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/di/ComponentModule.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.tangem.features.feed.components.market.details.portfolio.impl.di - -import com.tangem.features.feed.components.market.details.portfolio.api.MarketsPortfolioComponent -import com.tangem.features.feed.components.market.details.portfolio.impl.DefaultMarketsPortfolioComponent -import dagger.Binds -import dagger.Module -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import javax.inject.Singleton - -@Module -@InstallIn(SingletonComponent::class) -internal interface ComponentModule { - - @Binds - @Singleton - fun bindMarketsPortfolioComponent( - factory: DefaultMarketsPortfolioComponent.Factory, - ): MarketsPortfolioComponent.Factory -} \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/di/ModelModule.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/di/ModelModule.kt deleted file mode 100644 index 4656963d6b..0000000000 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/di/ModelModule.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.tangem.features.feed.components.market.details.portfolio.impl.di - -import com.tangem.core.decompose.di.ModelComponent -import com.tangem.core.decompose.model.Model -import com.tangem.features.feed.components.market.details.portfolio.impl.model.MarketsPortfolioModel -import dagger.Binds -import dagger.Module -import dagger.hilt.InstallIn -import dagger.multibindings.ClassKey -import dagger.multibindings.IntoMap - -@Module -@InstallIn(ModelComponent::class) -internal interface ModelModule { - - @Binds - @IntoMap - @ClassKey(MarketsPortfolioModel::class) - fun provideMarketsPortfolioModel(model: MarketsPortfolioModel): Model -} \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/model/MarketsPortfolioDelegate.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/model/MarketsPortfolioDelegate.kt deleted file mode 100644 index f4ba22eab4..0000000000 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/model/MarketsPortfolioDelegate.kt +++ /dev/null @@ -1,347 +0,0 @@ -package com.tangem.features.feed.components.market.details.portfolio.impl.model - -import arrow.core.getOrElse -import com.tangem.blockchainsdk.compatibility.getTokenIdIfL2Network -import com.tangem.common.ui.account.AccountTitleUM -import com.tangem.common.ui.account.CryptoPortfolioIconConverter -import com.tangem.common.ui.account.toUM -import com.tangem.common.ui.markets.action.CryptoCurrencyData -import com.tangem.common.ui.markets.action.TokenActionsHandler -import com.tangem.core.ui.DesignFeatureToggles -import com.tangem.core.ui.extensions.TextReference -import com.tangem.core.ui.extensions.stringReference -import com.tangem.domain.account.models.AccountStatusList -import com.tangem.domain.account.status.supplier.MultiAccountStatusListSupplier -import com.tangem.domain.account.status.usecase.GetCryptoCurrencyActionsUseCaseV2 -import com.tangem.domain.account.status.usecase.IsAccountsModeEnabledUseCase -import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase -import com.tangem.domain.appcurrency.model.AppCurrency -import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase -import com.tangem.domain.markets.TokenMarketInfo -import com.tangem.domain.markets.TokenMarketParams -import com.tangem.domain.models.account.Account -import com.tangem.domain.models.account.AccountStatus -import com.tangem.domain.models.account.filterCryptoPortfolio -import com.tangem.domain.models.currency.CryptoCurrency -import com.tangem.domain.models.currency.CryptoCurrencyStatus -import com.tangem.domain.models.wallet.UserWallet -import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.domain.models.wallet.isMultiCurrency -import com.tangem.domain.tokens.model.TokenActionsState -import com.tangem.domain.wallets.usecase.GetUserWalletUseCase -import com.tangem.domain.yield.supply.models.YieldSupplyAvailability -import com.tangem.domain.yield.supply.usecase.YieldSupplyGetAvailabilityUseCase -import com.tangem.features.feed.components.market.details.portfolio.impl.ui.state.MyPortfolioUM -import com.tangem.features.feed.components.market.details.portfolio.impl.ui.state.PortfolioHeader -import com.tangem.features.feed.components.market.details.portfolio.impl.ui.state.PortfolioListItem -import com.tangem.features.feed.components.market.details.portfolio.impl.ui.state.WalletHeader -import com.tangem.utils.extensions.isZero -import dagger.assisted.Assisted -import dagger.assisted.AssistedFactory -import dagger.assisted.AssistedInject -import kotlinx.collections.immutable.toImmutableList -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.flow.* - -@OptIn(ExperimentalCoroutinesApi::class) -@Suppress("LongParameterList") -internal class MarketsPortfolioDelegate @AssistedInject constructor( - getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, - getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase, - private val allAccountSupplier: MultiAccountStatusListSupplier, - private val getCryptoCurrencyActionsUseCase: GetCryptoCurrencyActionsUseCaseV2, - private val getUserWalletUseCase: GetUserWalletUseCase, - private val yieldSupplyGetAvailabilityUseCase: YieldSupplyGetAvailabilityUseCase, - private val designFeatureToggles: DesignFeatureToggles, - isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase, - @Assisted private val scope: CoroutineScope, - @Assisted private val token: TokenMarketParams, - @Assisted private val tokenActionsHandler: TokenActionsHandler, - @Assisted private val buttonState: Flow, - @Assisted private val onAddClick: () -> Unit, -) { - - private val currencyRawId: CryptoCurrency.RawID = token.id - private var expandedHolder: MutableStateFlow>>? = null - - private val settingsFlow: Flow = combine( - flow = getSelectedAppCurrencyUseCase.invokeOrDefault(), - flow2 = getBalanceHidingSettingsUseCase.isBalanceHidden(), - flow3 = isAccountsModeEnabledUseCase(), - transform = ::SettingsBox, - ).shareIn( - replay = 1, - started = SharingStarted.Eagerly, - scope = scope, - ).distinctUntilChanged() - - private val availableNetworks = MutableSharedFlow>( - replay = 1, - onBufferOverflow = BufferOverflow.DROP_OLDEST, - ) - - fun setTokenNetworks(networks: List) { - availableNetworks.tryEmit(networks) - } - - fun combineData(): Flow { - return availableNetworks.transformLatest { availableNetworks -> - when { - availableNetworks.isEmpty() -> emit(MyPortfolioUM.Unavailable) - else -> emitAll(onAvailableNetworksFlow().distinctUntilChanged()) - } - }.distinctUntilChanged() - } - - private fun onAvailableNetworksFlow(): Flow = - portfolioWithThisCurrencyFLow().transformLatest { portfolioWithCurrency -> - when (portfolioWithCurrency.flattenAddedCurrency.isEmpty()) { - false -> emitAll(contentFlow(portfolioWithCurrency).distinctUntilChanged()) - true -> when (portfolioWithCurrency.hasMultiWallets) { - true -> emitAll(addFirstTokenFlow()) - false -> emit(MyPortfolioUM.UnavailableForWallet) - } - } - } - - private fun addFirstTokenFlow(): Flow = buttonState.map { state -> - when (state) { - MyPortfolioUM.Tokens.AddButtonState.Loading -> MyPortfolioUM.Loading - MyPortfolioUM.Tokens.AddButtonState.Available -> MyPortfolioUM.AddFirstToken(onAddClick = onAddClick) - MyPortfolioUM.Tokens.AddButtonState.Unavailable -> MyPortfolioUM.Unavailable - } - } - - private fun contentFlow(portfoliosWithThisCurrency: PortfoliosWithThisCurrency): Flow { - fun Portfolio.actionsFoAccountCurrencies(): List>> = - accountsWithAdded.map { account -> - fun CryptoCurrencyStatus.actionsFlow(): Flow> = flow { - val yieldSupplyAvailability = yieldSupplyGetAvailabilityUseCase(this@actionsFlow.currency) - .getOrElse { YieldSupplyAvailability.Unavailable } - emitAll( - getCryptoCurrencyActionsUseCase( - accountId = account.accountStatus.account.accountId, - currency = this@actionsFlow.currency, - yieldSupplyAvailability = yieldSupplyAvailability, - ).map { actionsState -> actionsState.cryptoCurrencyStatus.currency to actionsState }, - ) - } - account.addedCurrency.map { it.actionsFlow() } - }.flatten() - - val allAddedTokenActions = - portfoliosWithThisCurrency.portfolios.map { portfolio -> portfolio.actionsFoAccountCurrencies() }.flatten() - - return combine( - flow = combine(allAddedTokenActions) { it.toMap() }.distinctUntilChanged(), - flow2 = buttonState.distinctUntilChanged(), - flow3 = getExpandedHolder(portfoliosWithThisCurrency), - flow4 = settingsFlow.distinctUntilChanged(), - transform = { actions, addButtonState, expanded, settings -> - buildContentState( - portfolio = portfoliosWithThisCurrency, - allActions = actions, - addButtonState = addButtonState, - expanded = expanded, - settings = settings, - ) - }, - ) - } - - private fun getExpandedHolder( - portfolio: PortfoliosWithThisCurrency, - ): StateFlow>> { - val expandedHolder = this.expandedHolder - if (expandedHolder != null) return expandedHolder - val allAddedCurrency = portfolio.flattenAddedCurrency - val shouldForceExpand = allAddedCurrency.size == 1 && - allAddedCurrency.first().value.amount?.isZero() == true - - val initValue = when { - shouldForceExpand -> { - val currency = allAddedCurrency.first() - // find userWallet than have this single added token - portfolio.portfolios - .find { it.accountsWithAdded.any { account -> account.addedCurrency.isNotEmpty() } } - ?.userWallet - ?.let { setOf(it.walletId to currency.currency.id) } - .orEmpty() - } - else -> emptySet() - } - return MutableStateFlow(initValue) - .also { this.expandedHolder = it } - } - - private fun portfolioWithThisCurrencyFLow(): Flow = - allAccountSupplier().map { list -> list.map { it.addedAccountsFlow() } }.flatMapLatest { flows -> - combine(flows) { portfolios -> - PortfoliosWithThisCurrency( - currencyRawId = currencyRawId, - portfolios = portfolios.toList(), - ) - } - }.distinctUntilChanged() - - private fun AccountStatusList.addedAccountsFlow(): Flow = - getUserWalletUseCase.invokeFlow(this.userWalletId).mapNotNull { it.getOrNull() }.map { wallet -> - Portfolio( - userWallet = wallet, - accountStatusList = this, - accountsWithAdded = this.filterByRawID(), - ) - }.distinctUntilChanged() - - private fun AccountStatusList.filterByRawID(): List { - fun AccountStatus.CryptoPortfolio.filterByRawID(): List = tokenList.flattenCurrencies() - .filter { status -> - val currencyId = status.currency.id.rawCurrencyId ?: return@filter false - getTokenIdIfL2Network(currencyId.value) == currencyRawId.value - } - return accountStatuses.filterCryptoPortfolio().map { accountStatus -> - AccountWithAdded( - accountStatus = accountStatus, - addedCurrency = accountStatus.filterByRawID(), - ) - } - } - - private fun buildContentState( - portfolio: PortfoliosWithThisCurrency, - allActions: Map, - addButtonState: MyPortfolioUM.Tokens.AddButtonState, - expanded: Set>, - settings: SettingsBox, - ): MyPortfolioUM.Content { - val appCurrency = settings.appCurrency - val isBalanceHidden = settings.isBalanceHidden - val isAccountMode = settings.isAccountMode - val uiItems: MutableList = mutableListOf() - - fun toggleQuickActions(key: Pair) = expandedHolder?.update { expanded -> - val isExpand = expanded.contains(key) - if (isExpand) expanded.minus(key) else expanded.plus(key) - } - - val tokenUMConverter = PortfolioTokenUMConverter( - appCurrency = appCurrency, - isBalanceHidden = isBalanceHidden, - onTokenItemClick = { }, - tokenActionsHandler = tokenActionsHandler, - isRedesignEnabled = designFeatureToggles.isRedesignEnabled, - ) - - portfolio.portfolios.forEach { portfolioItem -> - if (portfolioItem.flattenAddedCurrency.isEmpty()) return@forEach - val userWallet = portfolioItem.userWallet - if (isAccountMode) { - uiItems.add(portfolioItem.userWallet.toWalletHeader()) - } else { - uiItems.add(portfolioItem.userWallet.toWalletPortfolioHeader()) - } - - portfolioItem.accountsWithAdded.forEach { accountWithAdded -> - if (accountWithAdded.addedCurrency.isEmpty()) return@forEach - if (isAccountMode) { - val account = accountWithAdded.accountStatus.account - uiItems.add(account.toAccountPortfolioHeader()) - } - - accountWithAdded.addedCurrency.forEach { currencyStatus -> - val actions = allActions[currencyStatus.currency]?.states.orEmpty() - val value = CryptoCurrencyData( - userWallet = userWallet, - status = currencyStatus, - actions = actions, - isAccountMode = isAccountMode, - account = accountWithAdded.accountStatus, - ) - val expandedKey = portfolioItem.userWallet.walletId to currencyStatus.currency.id - val isExpand = expanded.contains(expandedKey) - - val tokenItem = tokenUMConverter.convertV2( - onTokenItemClick = { wallet, status -> - toggleQuickActions(wallet.walletId to status.currency.id) - }, - value = value, - isQuickActionsShown = isExpand, - ) - uiItems.add(tokenItem) - } - } - } - - return MyPortfolioUM.Content( - items = uiItems.toImmutableList(), - buttonState = addButtonState, - onAddClick = onAddClick, - ) - } - - private fun Account.CryptoPortfolio.toAccountPortfolioHeader(): PortfolioHeader = PortfolioHeader( - id = this.accountId.value, - state = AccountTitleUM.Account( - prefixText = TextReference.EMPTY, - name = this.accountName.toUM().value, - icon = CryptoPortfolioIconConverter.convert(this.icon), - ), - ) - - private fun UserWallet.toWalletPortfolioHeader(): PortfolioHeader = PortfolioHeader( - id = this.walletId.stringValue, - state = AccountTitleUM.Text( - title = stringReference(this.name), - ), - ) - - private fun UserWallet.toWalletHeader(): WalletHeader = WalletHeader( - id = this.walletId.stringValue, - name = stringReference(this.name), - ) - - @Suppress("LongParameterList") - @AssistedFactory - interface Factory { - fun create( - scope: CoroutineScope, - token: TokenMarketParams, - tokenActionsHandler: TokenActionsHandler, - buttonState: Flow, - onAddClick: () -> Unit, - ): MarketsPortfolioDelegate - } -} - -private data class PortfoliosWithThisCurrency( - val currencyRawId: CryptoCurrency.RawID, - val portfolios: List, -) { - - val hasMultiWallets: Boolean = portfolios.any { it.userWallet.isMultiCurrency } - - val flattenAddedCurrency: List = - portfolios.map { portfolio -> portfolio.flattenAddedCurrency }.flatten() -} - -private data class Portfolio( - val userWallet: UserWallet, - val accountStatusList: AccountStatusList, - val accountsWithAdded: List, -) { - val flattenAddedCurrency: List = - accountsWithAdded.map { it.addedCurrency }.flatten() -} - -private data class AccountWithAdded( - val addedCurrency: List, - val accountStatus: AccountStatus.CryptoPortfolio, -) - -private data class SettingsBox( - val appCurrency: AppCurrency, - val isBalanceHidden: Boolean, - val isAccountMode: Boolean, -) \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/model/MarketsPortfolioModel.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/model/MarketsPortfolioModel.kt deleted file mode 100644 index bee93e82b3..0000000000 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/model/MarketsPortfolioModel.kt +++ /dev/null @@ -1,170 +0,0 @@ -package com.tangem.features.feed.components.market.details.portfolio.impl.model - -import androidx.compose.runtime.Stable -import arrow.core.getOrElse -import com.arkivanov.decompose.router.slot.SlotNavigation -import com.arkivanov.decompose.router.slot.activate -import com.arkivanov.decompose.router.slot.dismiss -import com.tangem.common.routing.AppRoute -import com.tangem.common.routing.AppRouter -import com.tangem.common.ui.markets.action.TokenActionsBSContentUM -import com.tangem.common.ui.markets.action.TokenActionsHandler -import com.tangem.core.analytics.api.AnalyticsEventHandler -import com.tangem.core.decompose.di.ModelScoped -import com.tangem.core.decompose.model.Model -import com.tangem.core.decompose.model.ParamsContainer -import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase -import com.tangem.domain.appcurrency.model.AppCurrency -import com.tangem.domain.markets.TokenMarketInfo -import com.tangem.domain.transaction.usecase.ReceiveAddressesFactory -import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioManager -import com.tangem.features.feed.components.market.details.portfolio.api.MarketsPortfolioComponent -import com.tangem.features.feed.components.market.details.portfolio.impl.analytics.PortfolioAnalyticsEvent -import com.tangem.features.feed.components.market.details.portfolio.impl.ui.state.MyPortfolioUM -import com.tangem.utils.Provider -import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import kotlinx.coroutines.flow.* -import kotlinx.coroutines.launch -import javax.inject.Inject - -@Suppress("LongParameterList") -@Stable -@ModelScoped -internal class MarketsPortfolioModel @Inject constructor( - paramsContainer: ParamsContainer, - private val addToPortfolioManagerFactory: AddToPortfolioManager.Factory, - private val marketsPortfolioDelegateFactory: MarketsPortfolioDelegate.Factory, - private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, - private val tokenActionsHandlerFactory: TokenActionsHandler.Factory, - private val receiveAddressesFactory: ReceiveAddressesFactory, - private val analyticsEventHandler: AnalyticsEventHandler, - private val appRouter: AppRouter, - override val dispatchers: CoroutineDispatcherProvider, -) : Model() { - - val state: StateFlow - field = MutableStateFlow(value = MyPortfolioUM.Loading) - - private val params = paramsContainer.require() - - private val analyticsEventBuilder = PortfolioAnalyticsEvent.EventBuilder( - tokenSymbol = params.token.symbol, - source = params.analyticsParams?.source, - ) - - private val currentAppCurrency = createAppCurrencyFlow() - private val tokenActionsHandler = createTokenActionsHandler() - - val addToPortfolioManager: AddToPortfolioManager = createAddToPortfolioManager() - private val marketsPortfolioDelegate: MarketsPortfolioDelegate = createMarketsPortfolioDelegate() - - val bottomSheetNavigation: SlotNavigation = SlotNavigation() - - init { - marketsPortfolioDelegate.combineData() - .onEach { state.value = it } - .flowOn(dispatchers.default) - .launchIn(modelScope) - addToPortfolioManager.onDismiss.receiveAsFlow() - .onEach { bottomSheetNavigation.dismiss() } - .launchIn(modelScope) - addToPortfolioManager.onSuccessAdded.receiveAsFlow() - .onEach { bottomSheetNavigation.dismiss() } - .launchIn(modelScope) - addToPortfolioManager.onAddedTokenClick.receiveAsFlow() - .onEach { result -> - bottomSheetNavigation.dismiss() - appRouter.push( - AppRoute.CurrencyDetails( - userWalletId = result.wallet.walletId, - currency = result.addedCurrency.currency, - ), - ) - } - .launchIn(modelScope) - } - - fun setTokenNetworks(networks: List) { - addToPortfolioManager.setTokenNetworks(networks) - marketsPortfolioDelegate.setTokenNetworks(networks) - } - - fun setNoNetworksAvailable() { - addToPortfolioManager.setTokenNetworks(emptyList()) - marketsPortfolioDelegate.setTokenNetworks(emptyList()) - } - - private fun createAddToPortfolioManager(): AddToPortfolioManager { - return addToPortfolioManagerFactory.create( - scope = modelScope, - settings = AddToPortfolioManager.Settings.DefaultMarket, - analyticsParams = AddToPortfolioManager.AnalyticsParams(params.analyticsParams?.source), - ).also { addToPortfolioManager -> addToPortfolioManager.setTokenParams(params.token) } - } - - private fun createMarketsPortfolioDelegate(): MarketsPortfolioDelegate { - return marketsPortfolioDelegateFactory.create( - scope = modelScope, - token = params.token, - tokenActionsHandler = tokenActionsHandler, - buttonState = addToPortfolioManager.state.map { state -> - when (state) { - is AddToPortfolioManager.State.Ready -> { - if (state.isAvailableToAdd) { - MyPortfolioUM.Tokens.AddButtonState.Available - } else { - MyPortfolioUM.Tokens.AddButtonState.Unavailable - } - } - AddToPortfolioManager.State.Loading -> MyPortfolioUM.Tokens.AddButtonState.Loading - } - }, - onAddClick = { - analyticsEventHandler.send(analyticsEventBuilder.addToPortfolioClicked()) - bottomSheetNavigation.activate(MarketsPortfolioRoute.AddToPortfolio) - }, - ) - } - - private fun createAppCurrencyFlow(): StateFlow { - return getSelectedAppCurrencyUseCase() - .map { maybeAppCurrency -> - maybeAppCurrency.getOrElse { AppCurrency.Default } - } - .stateIn( - scope = modelScope, - started = SharingStarted.Eagerly, - initialValue = AppCurrency.Default, - ) - } - - private fun createTokenActionsHandler(): TokenActionsHandler { - return tokenActionsHandlerFactory.create( - currentAppCurrency = Provider { currentAppCurrency.value }, - onHandleQuickAction = { handledAction, _ -> - val currency = handledAction.cryptoCurrencyData.status.currency - analyticsEventHandler.send( - analyticsEventBuilder.quickActionClick( - actionUM = handledAction.action, - blockchainName = currency.network.name, - ), - ) - configureReceiveAddresses(handledAction) - }, - coroutineScope = modelScope, - ) - } - - private fun configureReceiveAddresses(quickAction: TokenActionsHandler.HandledQuickAction) { - val isNewReceive = quickAction.action == TokenActionsBSContentUM.Action.Receive - if (isNewReceive) { - modelScope.launch { - val tokenConfig = receiveAddressesFactory.create( - status = quickAction.cryptoCurrencyData.status, - userWalletId = quickAction.cryptoCurrencyData.userWallet.walletId, - ) ?: return@launch - bottomSheetNavigation.activate(MarketsPortfolioRoute.TokenReceive(tokenConfig)) - } - } - } -} \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/model/MarketsPortfolioRoute.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/model/MarketsPortfolioRoute.kt deleted file mode 100644 index 684f586b8a..0000000000 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/model/MarketsPortfolioRoute.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.tangem.features.feed.components.market.details.portfolio.impl.model - -import com.tangem.core.decompose.navigation.Route -import com.tangem.domain.models.TokenReceiveConfig -import kotlinx.serialization.Serializable - -@Serializable -sealed interface MarketsPortfolioRoute : Route { - - @Serializable - data object AddToPortfolio : MarketsPortfolioRoute - - @Serializable - data class TokenReceive( - val config: TokenReceiveConfig, - ) : MarketsPortfolioRoute -} \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/model/PortfolioTokenUMConverter.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/model/PortfolioTokenUMConverter.kt deleted file mode 100644 index 30ca070cee..0000000000 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/model/PortfolioTokenUMConverter.kt +++ /dev/null @@ -1,72 +0,0 @@ -package com.tangem.features.feed.components.market.details.portfolio.impl.model - -import com.tangem.common.ui.markets.action.CryptoCurrencyData -import com.tangem.common.ui.markets.action.QuickActionsConverter.quickActions -import com.tangem.common.ui.markets.action.TokenActionsHandler -import com.tangem.common.ui.tokens.TokenItemStateConverter -import com.tangem.core.ui.components.token.state.TokenItemState -import com.tangem.core.ui.extensions.stringReference -import com.tangem.domain.appcurrency.model.AppCurrency -import com.tangem.domain.models.currency.CryptoCurrencyStatus -import com.tangem.domain.models.wallet.UserWallet -import com.tangem.features.feed.components.market.details.portfolio.impl.ui.state.PortfolioTokenUM -import com.tangem.utils.converter.Converter - -/** - * Converter from [UserWallet] and [CryptoCurrencyStatus] to [PortfolioTokenUM] - * -[REDACTED_AUTHOR] - */ -internal class PortfolioTokenUMConverter( - private val appCurrency: AppCurrency, - private val isBalanceHidden: Boolean, - private val onTokenItemClick: (CryptoCurrencyStatus) -> Unit, - private val tokenActionsHandler: TokenActionsHandler, - private val isRedesignEnabled: Boolean, -) : Converter { - - fun convertV2( - value: CryptoCurrencyData, - isQuickActionsShown: Boolean, - onTokenItemClick: (UserWallet, CryptoCurrencyStatus) -> Unit, - ): PortfolioTokenUM { - val tokenItemStateConverter = TokenItemStateConverter( - appCurrency = appCurrency, - onItemClick = { _, status -> onTokenItemClick(value.userWallet, status) }, - ) - return PortfolioTokenUM( - tokenItemState = tokenItemStateConverter.convert(value = value.status), - walletId = value.userWallet.walletId, - isBalanceHidden = isBalanceHidden, - isQuickActionsShown = isQuickActionsShown, - quickActions = quickActions( - cryptoData = value, - tokenActionsHandler = tokenActionsHandler, - isRedesignEnabled = isRedesignEnabled, - ), - ) - } - - override fun convert(value: CryptoCurrencyData): PortfolioTokenUM { - val tokenItemStateConverter = TokenItemStateConverter( - appCurrency = appCurrency, - titleStateProvider = { TokenItemState.TitleState.Content(text = stringReference(value.userWallet.name)) }, - subtitleStateProvider = { - TokenItemState.SubtitleState.TextContent(value = stringReference(value.status.currency.name)) - }, - onItemClick = { _, status -> onTokenItemClick(status) }, - ) - - return PortfolioTokenUM( - tokenItemState = tokenItemStateConverter.convert(value = value.status), - walletId = value.userWallet.walletId, - isBalanceHidden = isBalanceHidden, - isQuickActionsShown = false, - quickActions = quickActions( - cryptoData = value, - tokenActionsHandler = tokenActionsHandler, - isRedesignEnabled = isRedesignEnabled, - ), - ) - } -} \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/MyPortfolio.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/MyPortfolio.kt deleted file mode 100644 index c7c885eca6..0000000000 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/MyPortfolio.kt +++ /dev/null @@ -1,333 +0,0 @@ -package com.tangem.features.feed.components.market.details.portfolio.impl.ui - -import android.content.res.Configuration -import androidx.annotation.StringRes -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.key -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.unit.dp -import androidx.compose.ui.util.fastForEachIndexed -import com.tangem.common.ui.account.AccountTitle -import com.tangem.core.ui.components.PrimaryButton -import com.tangem.core.ui.components.RectangleShimmer -import com.tangem.core.ui.components.SmallButtonShimmer -import com.tangem.core.ui.components.TextShimmer -import com.tangem.core.ui.components.block.information.InformationBlock -import com.tangem.core.ui.components.buttons.SecondarySmallButton -import com.tangem.core.ui.components.buttons.SmallButtonConfig -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.stringResourceSafe -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.features.feed.components.market.details.portfolio.impl.ui.preview.PreviewMyPortfolioUMProvider -import com.tangem.features.feed.components.market.details.portfolio.impl.ui.state.* -import com.tangem.features.feed.impl.R - -@Composable -internal fun MyPortfolio(state: MyPortfolioUM, modifier: Modifier = Modifier) { - if (state is MyPortfolioUM.Content) { - val contentModifier = Modifier.padding( - start = TangemTheme.dimens.spacing16, - top = TangemTheme.dimens.spacing20, - end = TangemTheme.dimens.spacing16, - bottom = TangemTheme.dimens.spacing32, - ) - PortfolioList(state, contentModifier) - return - } - InformationBlock( - modifier = modifier, - contentHorizontalPadding = TangemTheme.dimens.spacing0, - title = { Title() }, - action = { - if (state !is MyPortfolioUM.Tokens) return@InformationBlock - - AddButton(state = state.buttonState, onClick = state.onAddClick) - }, - ) { - val contentModifier = Modifier.padding( - start = TangemTheme.dimens.spacing12, - end = TangemTheme.dimens.spacing12, - bottom = TangemTheme.dimens.spacing12, - ) - - when (state) { - is MyPortfolioUM.Tokens -> TokenList(state = state) - is MyPortfolioUM.AddFirstToken -> AddFirstTokenContent(state = state, modifier = contentModifier) - MyPortfolioUM.Loading -> LoadingPlaceholder(modifier = contentModifier) - MyPortfolioUM.Unavailable -> UnavailableAsset(modifier = contentModifier) - MyPortfolioUM.UnavailableForWallet -> UnavailableAssetForWallet(modifier = contentModifier) - is MyPortfolioUM.Content -> PortfolioList(state = state) - } - } -} - -@Composable -private fun Title() { - Text( - text = stringResourceSafe(R.string.markets_common_my_portfolio), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.tertiary, - ) -} - -@Composable -private fun AddButton(state: MyPortfolioUM.Tokens.AddButtonState, onClick: () -> Unit) { - when (state) { - MyPortfolioUM.Tokens.AddButtonState.Loading -> { - Box { - SmallButtonShimmer( - modifier = Modifier.width(width = TangemTheme.dimens.size63), - shape = RoundedCornerShape(TangemTheme.dimens.radius3), - withIcon = true, - ) - - Box( - Modifier - .matchParentSize() - .background(TangemTheme.colors.background.action), - ) - - RectangleShimmer( - modifier = Modifier - .align(Alignment.Center) - .size(width = TangemTheme.dimens.size63, height = TangemTheme.dimens.size18), - radius = TangemTheme.dimens.radius3, - ) - } - } - MyPortfolioUM.Tokens.AddButtonState.Available, - MyPortfolioUM.Tokens.AddButtonState.Unavailable, - -> { - SecondarySmallButton( - config = SmallButtonConfig( - text = resourceReference(R.string.markets_add_token), - icon = TangemButtonIconPosition.Start(R.drawable.ic_plus_24), - onClick = onClick, - isEnabled = state == MyPortfolioUM.Tokens.AddButtonState.Available, - ), - ) - } - } -} - -@Composable -private fun TokenList(state: MyPortfolioUM.Tokens, modifier: Modifier = Modifier) { - Column(modifier) { - state.tokens.fastForEachIndexed { index, token -> - key(token.tokenItemState.id) { - PortfolioItem( - modifier = Modifier.background(color = TangemTheme.colors.background.action), - state = token, - lastInList = index == state.tokens.size - 1, - ) - } - } - } -} - -@Composable -private fun PortfolioList(state: MyPortfolioUM.Content, modifier: Modifier = Modifier) { - Column(modifier) { - key("PortfolioListHeader") { - Row( - modifier = Modifier.padding(horizontal = 4.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - modifier = Modifier.weight(1f), - text = stringResourceSafe(R.string.markets_common_my_portfolio), - style = TangemTheme.typography.h3, - color = TangemTheme.colors.text.primary1, - ) - AddButton(state = state.buttonState, onClick = state.onAddClick) - } - } - - state.items.fastForEachIndexed { index, item -> - val previousItem = state.items.getOrNull(index.dec()) - val nextItem = state.items.getOrNull(index.inc()) - val itemModifier = Modifier - .fillMaxWidth() - .getOffsetModifier(item, previousItem) - .getBackgroundModifier(item, previousItem, nextItem) - - key(item.id) { - PortfolioItem( - item = item, - modifier = itemModifier, - lastInList = index == state.items.size - 1, - ) - } - } - } -} - -@Composable -private fun Modifier.getBackgroundModifier( - item: PortfolioListItem, - previousItem: PortfolioListItem?, - nextItem: PortfolioListItem?, -): Modifier { - val color = TangemTheme.colors.background.action - val radius = 14.dp - val topRound = RoundedCornerShape(topStart = radius, topEnd = radius) - val bottomRound = RoundedCornerShape(bottomStart = radius, bottomEnd = radius) - val allRound = RoundedCornerShape(size = radius) - val backgroundModifier = when (item) { - is WalletHeader -> this - is PortfolioHeader -> this - .clip(topRound) - .background(color = color) - is PortfolioTokenUM -> when { - previousItem is PortfolioHeader && nextItem !is PortfolioTokenUM -> this - .clip(bottomRound) - .background(color = color) - previousItem is WalletHeader && nextItem !is PortfolioTokenUM -> this - .clip(allRound) - .background(color = color) - previousItem is PortfolioTokenUM && nextItem !is PortfolioTokenUM -> this - .clip(bottomRound) - .background(color = color) - else -> this.background(color = color) - } - } - return backgroundModifier -} - -private fun Modifier.getOffsetModifier(item: PortfolioListItem, previousItem: PortfolioListItem?): Modifier = when { - item is WalletHeader -> this.padding(top = 20.dp, start = 4.dp, end = 4.dp) - item is PortfolioHeader && previousItem is PortfolioTokenUM -> this.padding(top = 12.dp) - item is PortfolioHeader && previousItem == null -> this.padding(top = 20.dp) - previousItem is WalletHeader -> this.padding(top = 12.dp) - previousItem is PortfolioTokenUM -> this - else -> this -} - -@Composable -private fun PortfolioItem(item: PortfolioListItem, lastInList: Boolean, modifier: Modifier = Modifier) { - when (item) { - is PortfolioHeader -> AccountTitle( - modifier = modifier.padding( - start = 12.dp, - top = 12.dp, - bottom = 8.dp, - ), - accountTitleUM = item.state, - textStyle = TangemTheme.typography.caption1, - textColor = TangemTheme.colors.text.primary1, - ) - is PortfolioTokenUM -> PortfolioItem( - state = item, - modifier = modifier, - lastInList = lastInList, - ) - is WalletHeader -> Text( - modifier = modifier, - text = item.name.resolveReference(), - style = TangemTheme.typography.subtitle1, - color = TangemTheme.colors.text.primary1, - ) - } -} - -@Composable -fun UnavailableAsset(modifier: Modifier = Modifier) { - UnavailableContent( - textId = R.string.markets_add_to_my_portfolio_unavailable_description, - modifier = modifier, - ) -} - -@Composable -fun UnavailableAssetForWallet(modifier: Modifier = Modifier) { - UnavailableContent( - textId = R.string.markets_add_to_my_portfolio_unavailable_for_wallet_description, - modifier = modifier, - ) -} - -@Composable -private fun UnavailableContent(@StringRes textId: Int, modifier: Modifier = Modifier) { - Text( - modifier = modifier, - text = stringResourceSafe(textId), - style = TangemTheme.typography.body2, - color = TangemTheme.colors.text.tertiary, - ) -} - -@Composable -private fun AddFirstTokenContent(state: MyPortfolioUM.AddFirstToken, modifier: Modifier = Modifier) { - Column( - modifier = modifier, - verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12), - ) { - Text( - text = stringResourceSafe(R.string.markets_add_to_my_portfolio_description), - style = TangemTheme.typography.body2, - color = TangemTheme.colors.text.tertiary, - ) - - PrimaryButton( - modifier = Modifier.fillMaxWidth(), - text = stringResourceSafe(R.string.common_add_to_portfolio), - onClick = state.onAddClick, - ) - } -} - -@Composable -private fun LoadingPlaceholder(modifier: Modifier = Modifier) { - Column(modifier = modifier) { - TextShimmer( - modifier = Modifier.fillMaxWidth(), - style = TangemTheme.typography.body2, - textSizeHeight = true, - ) - - TextShimmer( - modifier = Modifier.fillMaxWidth(fraction = 0.7f), - style = TangemTheme.typography.body2, - textSizeHeight = true, - ) - } -} - -@Preview -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun Preview(@PreviewParameter(PreviewMyPortfolioUMProvider::class) state: MyPortfolioUM) { - TangemThemePreview { - Box( - modifier = Modifier - .background(TangemTheme.colors.background.tertiary), - ) { - MyPortfolio(state) - } - } -} - -@Preview -@Composable -private fun PreviewRtl(@PreviewParameter(PreviewMyPortfolioUMProvider::class) state: MyPortfolioUM) { - TangemThemePreview(rtl = true) { - Box( - modifier = Modifier - .background(TangemTheme.colors.background.tertiary) - .padding(TangemTheme.dimens.spacing8), - ) { - MyPortfolio(state) - } - } -} \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/PortfolioItem.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/PortfolioItem.kt deleted file mode 100644 index 7d605e621d..0000000000 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/PortfolioItem.kt +++ /dev/null @@ -1,156 +0,0 @@ -package com.tangem.features.feed.components.market.details.portfolio.impl.ui - -import android.content.res.Configuration -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.padding -import androidx.compose.runtime.* -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.testTag -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider -import com.tangem.core.ui.components.icons.IconTint -import com.tangem.core.ui.components.token.TokenItem -import com.tangem.core.ui.components.token.state.TokenItemState -import com.tangem.core.ui.haptic.TangemHapticEffect -import com.tangem.core.ui.res.LocalHapticManager -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.core.ui.test.MarketTokenDetailsBottomSheetTestTags -import com.tangem.features.feed.components.market.details.portfolio.impl.ui.preview.PreviewMyPortfolioUMProvider -import com.tangem.features.feed.components.market.details.portfolio.impl.ui.state.PortfolioTokenUM -import com.tangem.features.feed.impl.R -import com.tangem.utils.StringsSigns.DASH_SIGN -import kotlinx.collections.immutable.persistentListOf -import com.tangem.core.ui.components.token.state.TokenItemState.FiatAmountState as TokenFiatAmountState - -@Composable -internal fun PortfolioItem(state: PortfolioTokenUM, lastInList: Boolean, modifier: Modifier = Modifier) { - Column(modifier) { - val hapticManager = LocalHapticManager.current - val tokenItemState = remember(state.tokenItemState) { - when (state.tokenItemState) { - is TokenItemState.Content -> state.tokenItemState.copy( - onItemClick = { tokenItemState -> - val onClick = state.tokenItemState.onItemClick - if (onClick != null) { - hapticManager.perform(TangemHapticEffect.View.ContextClick) - onClick.invoke(tokenItemState) - } - }, - ) - else -> state.tokenItemState - } - } - TokenItem( - state = tokenItemState, - isBalanceHidden = state.isBalanceHidden, - itemPaddingValues = PaddingValues( - start = TangemTheme.dimens.spacing10, - end = TangemTheme.dimens.spacing12, - ), - modifier = Modifier.testTag(MarketTokenDetailsBottomSheetTestTags.PORTFOLIO_TOKEN_ITEM), - ) - - PortfolioQuickActions( - modifier = Modifier - .padding( - bottom = if (lastInList) { - TangemTheme.dimens.spacing12 - } else { - TangemTheme.dimens.spacing24 - }, - ), - actions = state.quickActions.actions, - isVisible = state.isQuickActionsShown, - onActionClick = state.quickActions.onQuickActionClick, - onActionLongClick = state.quickActions.onQuickActionLongClick, - ) - } -} - -@Preview -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun Preview(@PreviewParameter(PortfolioTokenUMProvider::class) tokenUM: PortfolioTokenUM) { - TangemThemePreview { - var isQuickActionsShown by remember { mutableStateOf(value = false) } - - val onItemClick = { - isQuickActionsShown = isQuickActionsShown.not() - } - - PortfolioItem( - modifier = Modifier.background(color = TangemTheme.colors.background.action), - state = tokenUM.copy( - tokenItemState = when (tokenUM.tokenItemState) { - is TokenItemState.Content -> tokenUM.tokenItemState.copy(onItemClick = { onItemClick() }) - is TokenItemState.Unreachable -> tokenUM.tokenItemState.copy(onItemClick = { onItemClick() }) - else -> tokenUM.tokenItemState - }, - isQuickActionsShown = isQuickActionsShown, - ), - lastInList = true, - ) - } -} - -private class PortfolioTokenUMProvider : CollectionPreviewParameterProvider( - collection = listOf( - tokenUM.copy( - tokenItemState = (tokenUM.tokenItemState as TokenItemState.Content).copy( - fiatAmountState = contentFiatAmount?.copy( - icons = persistentListOf( - TokenFiatAmountState.Content.IconUM( - iconRes = R.drawable.ic_staking_24, - tint = IconTint.Accent, - ), - ), - ), - ), - ), - tokenUM.copy( - tokenItemState = tokenUM.tokenItemState.copy( - fiatAmountState = contentFiatAmount?.copy(text = DASH_SIGN), - subtitle2State = (tokenUM.tokenItemState.subtitle2State as? TokenItemState.Subtitle2State.TextContent) - ?.copy(text = DASH_SIGN), - ), - ), - tokenUM.copy(isBalanceHidden = true), - tokenUM.copy( - tokenItemState = TokenItemState.Unreachable( - id = tokenUM.tokenItemState.id, - iconState = tokenUM.tokenItemState.iconState, - titleState = tokenUM.tokenItemState.titleState, - subtitleState = tokenUM.tokenItemState.subtitleState, - onItemClick = {}, - onItemLongClick = {}, - ), - ), - tokenUM.copy( - tokenItemState = TokenItemState.NoAddress( - id = tokenUM.tokenItemState.id, - iconState = tokenUM.tokenItemState.iconState, - titleState = tokenUM.tokenItemState.titleState, - subtitleState = tokenUM.tokenItemState.subtitleState, - onItemLongClick = {}, - ), - ), - tokenUM.copy( - tokenItemState = TokenItemState.Loading( - id = tokenUM.tokenItemState.id, - iconState = tokenUM.tokenItemState.iconState, - titleState = tokenUM.tokenItemState.titleState as TokenItemState.TitleState.Content, - subtitleState = tokenUM.tokenItemState.subtitleState, - ), - ), - ), -) { - - companion object { - val tokenUM = PreviewMyPortfolioUMProvider().sampleToken - val contentFiatAmount = tokenUM.tokenItemState.fiatAmountState as? TokenFiatAmountState.Content - } -} \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/PortfolioQuickActions.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/PortfolioQuickActions.kt deleted file mode 100644 index 8c447cad20..0000000000 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/PortfolioQuickActions.kt +++ /dev/null @@ -1,263 +0,0 @@ -package com.tangem.features.feed.components.market.details.portfolio.impl.ui - -import android.content.res.Configuration -import androidx.compose.animation.* -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.spring -import androidx.compose.foundation.Canvas -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.Button -import androidx.compose.material3.Icon -import androidx.compose.material3.Text -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.drawWithContent -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.platform.LocalLayoutDirection -import androidx.compose.ui.platform.testTag -import androidx.compose.ui.res.vectorResource -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.LayoutDirection -import androidx.compose.ui.unit.dp -import androidx.compose.ui.util.fastForEach -import com.tangem.common.ui.markets.action.QuickActionUM -import com.tangem.core.ui.components.SpacerH4 -import com.tangem.core.ui.components.icons.badge.drawBadge -import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.haptic.TangemHapticEffect -import com.tangem.core.ui.res.LocalHapticManager -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.core.ui.test.MarketTokenDetailsBottomSheetTestTags -import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.persistentListOf - -@Composable -internal fun PortfolioQuickActions( - actions: ImmutableList, - isVisible: Boolean, - onActionClick: (QuickActionUM) -> Unit, - onActionLongClick: (QuickActionUM) -> Unit, - modifier: Modifier = Modifier, -) { - if (actions.isEmpty()) return - - AnimatedVisibility( - modifier = modifier, - visible = isVisible, - enter = expandVertically(expandFrom = Alignment.Top), - exit = shrinkVertically(shrinkTowards = Alignment.Top), - ) { - Column { - actions.fastForEach { action -> - LineSeparator() - QuickActionItem( - state = action, - onClick = { onActionClick(action) }, - onLongClick = { onActionLongClick(action) }.takeIf { action.isLongClickAvailable }, - ) - } - } - } -} - -@Composable -private fun AnimatedVisibilityScope.LineSeparator(modifier: Modifier = Modifier) { - val lineColor = TangemTheme.colors.stroke.primary - val strokeWidth = TangemTheme.dimens.size1 - val isLtr = LocalLayoutDirection.current == LayoutDirection.Ltr - val startPadding = TangemTheme.dimens.spacing30 - - val height = TangemTheme.dimens.size16 - - Canvas( - modifier = modifier - .animateEnterExit( - enter = expandVertically( - animationSpec = spring( - stiffness = Spring.StiffnessLow, - ), - expandFrom = Alignment.Top, - ) + fadeIn(), - exit = shrinkVertically( - spring( - stiffness = Spring.StiffnessLow, - ), - shrinkTowards = Alignment.Top, - ) + fadeOut(), - ) - .fillMaxWidth() - .height(height), - ) { - val x = if (isLtr) startPadding.toPx() else size.width - startPadding.toPx() - - drawLine( - color = lineColor, - start = Offset(x, 0f), - end = Offset(x, size.height), - strokeWidth = strokeWidth.toPx(), - ) - } -} - -@OptIn(ExperimentalFoundationApi::class) -@Composable -private fun AnimatedVisibilityScope.QuickActionItem( - state: QuickActionUM, - onClick: () -> Unit, - onLongClick: (() -> Unit)?, - modifier: Modifier = Modifier, -) { - val hapticManager = LocalHapticManager.current - val onLongClickInternal: (() -> Unit)? = if (onLongClick != null) { - { - hapticManager.perform(TangemHapticEffect.View.LongPress) - onLongClick() - } - } else { - null - } - - Row( - modifier = modifier - .fillMaxWidth() - .combinedClickable( - onLongClick = onLongClickInternal, - onClick = { - hapticManager.perform(TangemHapticEffect.View.SegmentTick) - onClick() - }, - ) - .padding(horizontal = TangemTheme.dimens.spacing14, vertical = TangemTheme.dimens.spacing4) - .testTag(MarketTokenDetailsBottomSheetTestTags.PORTFOLIO_QUICK_ACTION_BUTTON), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing18), - ) { - QuickActionIcon(state) - Column( - modifier = Modifier - .animateEnterExit( - enter = fadeIn(), - exit = fadeOut(), - ), - verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing2), - ) { - Text( - text = state.title.resolveReference(), - style = TangemTheme.typography.body2, - color = TangemTheme.colors.text.primary1, - modifier = Modifier.testTag(MarketTokenDetailsBottomSheetTestTags.PORTFOLIO_QUICK_ACTION_BUTTON_TITLE), - ) - Text( - text = state.description.resolveReference(), - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.tertiary, - ) - } - } -} - -@Composable -private fun AnimatedVisibilityScope.QuickActionIcon(state: QuickActionUM) { - val containerColor = TangemTheme.colors.background.action - Box( - Modifier - .animateEnterExit( - enter = scaleIn(), - exit = scaleOut(), - ) - .background( - color = TangemTheme.colors.button.secondary, - shape = CircleShape, - ) - .size(TangemTheme.dimens.size32) - .semantics { - contentDescription = if (state is QuickActionUM.V1.Exchange && state.shouldShowBadge) { - "Badge shown" - } else { - "Badge hidden" - } - } - .drawWithContent { - drawContent() - if (state is QuickActionUM.V1.Exchange && state.shouldShowBadge) { - drawBadge(containerColor = containerColor, offset = 4.dp) - } - }, - contentAlignment = Alignment.Center, - ) { - Icon( - modifier = Modifier - .requiredSize(TangemTheme.dimens.size16) - .testTag(MarketTokenDetailsBottomSheetTestTags.PORTFOLIO_QUICK_ACTION_BUTTON_ICON), - imageVector = ImageVector.vectorResource(id = state.icon), - contentDescription = null, - tint = TangemTheme.colors.button.primary, - ) - } -} - -@Preview -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun Preview() { - TangemThemePreview { - var isVisible by remember { mutableStateOf(true) } - - Column( - modifier = Modifier - .fillMaxWidth() - .height(680.dp), - ) { - Button( - onClick = { isVisible = !isVisible }, - modifier = Modifier.padding(TangemTheme.dimens.spacing12), - ) { - Text(text = "Toggle") - } - SpacerH4() - Box( - modifier = Modifier.background(color = TangemTheme.colors.background.action), - ) { - PortfolioQuickActions( - actions = persistentListOf( - QuickActionUM.V1.Buy, - QuickActionUM.V1.Exchange(shouldShowBadge = true), - QuickActionUM.V1.Receive, - ), - isVisible = isVisible, - onActionClick = {}, - onActionLongClick = {}, - ) - } - } - } -} - -@Preview -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun PreviewRtl() { - TangemThemePreview(rtl = true) { - Box(modifier = Modifier.background(color = TangemTheme.colors.background.action)) { - PortfolioQuickActions( - actions = persistentListOf( - QuickActionUM.V1.Buy, - QuickActionUM.V1.Exchange(shouldShowBadge = true), - QuickActionUM.V1.Receive, - ), - isVisible = true, - onActionClick = {}, - onActionLongClick = {}, - ) - } - } -} \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/preview/PreviewMyPortfolioUMProvider.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/preview/PreviewMyPortfolioUMProvider.kt deleted file mode 100644 index 38675976ef..0000000000 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/preview/PreviewMyPortfolioUMProvider.kt +++ /dev/null @@ -1,142 +0,0 @@ -package com.tangem.features.feed.components.market.details.portfolio.impl.ui.preview - -import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import com.tangem.common.ui.account.AccountIconPreviewData -import com.tangem.common.ui.account.AccountTitleUM -import com.tangem.common.ui.markets.action.QuickActionUM -import com.tangem.common.ui.markets.action.QuickActions -import com.tangem.core.ui.components.currency.icon.CurrencyIconState -import com.tangem.core.ui.components.token.state.TokenItemState -import com.tangem.core.ui.components.token.state.TokenItemState.FiatAmountState -import com.tangem.core.ui.extensions.TextReference -import com.tangem.core.ui.extensions.stringReference -import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.features.feed.components.market.details.portfolio.impl.ui.state.* -import kotlinx.collections.immutable.persistentListOf -import java.util.UUID - -@Suppress("PropertyUsedBeforeDeclaration") -internal class PreviewMyPortfolioUMProvider : PreviewParameterProvider { - - override val values: Sequence - get() = sequenceOf( - MyPortfolioUM.Tokens( - tokens = persistentListOf(sampleToken, sampleToken), - buttonState = MyPortfolioUM.Tokens.AddButtonState.Available, - onAddClick = {}, - ), - MyPortfolioUM.Tokens( - tokens = persistentListOf(sampleToken, sampleToken.copy(isQuickActionsShown = true)), - buttonState = MyPortfolioUM.Tokens.AddButtonState.Unavailable, - onAddClick = {}, - ), - MyPortfolioUM.Tokens( - tokens = persistentListOf(sampleToken.copy(isQuickActionsShown = true), sampleToken), - buttonState = MyPortfolioUM.Tokens.AddButtonState.Loading, - onAddClick = {}, - ), - MyPortfolioUM.AddFirstToken(onAddClick = {}), - MyPortfolioUM.Content( - items = persistentListOf( - walletPortfolioHeader, - accountToken, - accountToken, - ), - buttonState = MyPortfolioUM.Tokens.AddButtonState.Available, - onAddClick = {}, - ), - MyPortfolioUM.Content( - items = persistentListOf( - walletHeader, - accountHeader, - accountToken, - accountToken, - ), - buttonState = MyPortfolioUM.Tokens.AddButtonState.Available, - onAddClick = {}, - ), - MyPortfolioUM.Content( - items = persistentListOf( - walletHeader, - accountHeader, - accountToken.copy(isQuickActionsShown = true), - accountToken, - ), - buttonState = MyPortfolioUM.Tokens.AddButtonState.Available, - onAddClick = {}, - ), - MyPortfolioUM.Loading, - MyPortfolioUM.Unavailable, - MyPortfolioUM.UnavailableForWallet, - ) - - val walletHeader - get() = WalletHeader( - id = UUID.randomUUID().toString(), - name = stringReference("Wallet 1"), - ) - - val walletPortfolioHeader - get() = PortfolioHeader( - state = AccountTitleUM.Text(title = stringReference("Wallet 1")), - id = UUID.randomUUID().toString(), - ) - - val accountHeader - get() = PortfolioHeader( - state = AccountTitleUM.Account( - icon = AccountIconPreviewData.randomAccountIcon(), - name = stringReference("Main Account"), - prefixText = TextReference.EMPTY, - ), - id = UUID.randomUUID().toString(), - ) - val coinIconState - get() = CurrencyIconState.CoinIcon( - url = null, - fallbackResId = com.tangem.core.ui.R.drawable.img_polygon_22, - isGrayscale = false, - shouldShowCustomBadge = false, - ) - val accountToken - get() = sampleToken.copy( - tokenItemState = TokenItemState.Content( - id = UUID.randomUUID().toString(), - iconState = coinIconState, - titleState = TokenItemState.TitleState.Content(text = stringReference(value = "Polygon")), - fiatAmountState = FiatAmountState.Content(text = "321 $"), - subtitle2State = TokenItemState.Subtitle2State.TextContent(text = "5,412 MATIC"), - subtitleState = TokenItemState.SubtitleState.TextContent(stringReference(value = "Token")), - onItemClick = {}, - onItemLongClick = {}, - ), - ) - - val sampleToken - get() = PortfolioTokenUM( - tokenItemState = TokenItemState.Content( - id = UUID.randomUUID().toString(), - iconState = CurrencyIconState.Locked, - titleState = TokenItemState.TitleState.Content(text = stringReference(value = "My wallet")), - fiatAmountState = FiatAmountState.Content(text = "486,65 \$"), - subtitle2State = TokenItemState.Subtitle2State.TextContent(text = "733,71097 MATIC"), - subtitleState = TokenItemState.SubtitleState.TextContent( - value = stringReference(value = "XRP Ledger token"), - ), - onItemClick = {}, - onItemLongClick = {}, - ), - isQuickActionsShown = false, - quickActions = QuickActions( - actions = persistentListOf( - QuickActionUM.V1.Buy, - QuickActionUM.V1.Exchange(shouldShowBadge = true), - QuickActionUM.V1.Receive, - ), - onQuickActionClick = {}, - onQuickActionLongClick = {}, - ), - isBalanceHidden = false, - walletId = UserWalletId(""), - ) -} \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/state/MyPortfolioUM.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/state/MyPortfolioUM.kt deleted file mode 100644 index b9d4593c30..0000000000 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/state/MyPortfolioUM.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.tangem.features.feed.components.market.details.portfolio.impl.ui.state - -import androidx.compose.runtime.Immutable -import kotlinx.collections.immutable.ImmutableList - -@Immutable -internal sealed class MyPortfolioUM { - - data class Tokens( - val tokens: ImmutableList, - val buttonState: AddButtonState, - val onAddClick: () -> Unit, - ) : MyPortfolioUM() { - - enum class AddButtonState { - Loading, - Available, - Unavailable, - } - } - - data class Content( - val items: ImmutableList, - val buttonState: Tokens.AddButtonState, - val onAddClick: () -> Unit, - ) : MyPortfolioUM() - - data class AddFirstToken( - val onAddClick: () -> Unit, - ) : MyPortfolioUM() - - data object Loading : MyPortfolioUM() - - data object Unavailable : MyPortfolioUM() - - data object UnavailableForWallet : MyPortfolioUM() -} \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/state/PortfolioTokenUM.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/state/PortfolioTokenUM.kt deleted file mode 100644 index cad0269803..0000000000 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/portfolio/impl/ui/state/PortfolioTokenUM.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.tangem.features.feed.components.market.details.portfolio.impl.ui.state - -import androidx.compose.runtime.Immutable -import com.tangem.common.ui.account.AccountTitleUM -import com.tangem.common.ui.markets.action.QuickActions -import com.tangem.core.ui.components.token.state.TokenItemState -import com.tangem.core.ui.extensions.TextReference -import com.tangem.domain.models.wallet.UserWalletId - -@Immutable -internal sealed interface PortfolioListItem { - val id: String -} - -internal data class WalletHeader( - override val id: String, - val name: TextReference, -) : PortfolioListItem - -internal data class PortfolioHeader( - override val id: String, - val state: AccountTitleUM, -) : PortfolioListItem - -internal data class PortfolioTokenUM( - val tokenItemState: TokenItemState, - val walletId: UserWalletId, - val isBalanceHidden: Boolean, - val isQuickActionsShown: Boolean, - val quickActions: QuickActions, -) : PortfolioListItem { - override val id: String = tokenItemState.id -} \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/list/DefaultMarketsTokenListComponent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/list/DefaultMarketsTokenListComponent.kt index ab0c54f7c1..8fc7598702 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/list/DefaultMarketsTokenListComponent.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/list/DefaultMarketsTokenListComponent.kt @@ -27,7 +27,6 @@ import com.tangem.core.ui.decompose.ComposableModularBottomSheetContentComponent import com.tangem.core.ui.extensions.clickableSingle import com.tangem.core.ui.extensions.conditional import com.tangem.core.ui.res.LocalMainBottomSheetColor -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.markets.TokenMarketParams @@ -36,7 +35,6 @@ import com.tangem.features.feed.model.market.list.state.MarketsListUM import com.tangem.features.feed.model.market.list.state.SortByTypeUM import com.tangem.features.feed.ui.components.FeedSearchBar import com.tangem.features.feed.ui.market.list.MarketsList -import com.tangem.features.feed.ui.market.list.TopBarWithSearch import kotlinx.serialization.Serializable internal class DefaultMarketsTokenListComponent( @@ -55,41 +53,31 @@ internal class DefaultMarketsTokenListComponent( @Composable override fun Title(bottomSheetState: State) { val state by model.state.collectAsStateWithLifecycle() - val bsState by bottomSheetState - if (LocalRedesignEnabled.current) { - val bottomSheetColor = LocalMainBottomSheetColor.current.value - FeedSearchBar( - isSearchBarClickable = bottomSheetState.value == BottomSheetState.EXPANDED, - feedListSearchBar = state.feedListSearchBar, - modifier = Modifier.conditional(bottomSheetColor.isSpecified) { - background(bottomSheetColor.copy(alpha = .95f)) - }, - startContent = { - Icon( - imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back_28), - contentDescription = null, - tint = TangemTheme.colors2.graphic.neutral.primary, - modifier = Modifier - .size(TangemTheme.dimens2.x11) - .clip(CircleShape) - .hazeEffectTangem { blurRadius = 8.dp } - .clickableSingle( - onClick = clickIntents.onBackClicked, - enabled = bottomSheetState.value == BottomSheetState.EXPANDED, - ) - .padding(TangemTheme.dimens2.x2), - ) - }, - ) - } else { - TopBarWithSearch( - onBackClick = clickIntents.onBackClicked, - onSearchClick = state.onSearchClicked, - marketsSearchBar = state.marketsSearchBar, - bottomSheetState = bsState, - ) - } + val bottomSheetColor = LocalMainBottomSheetColor.current.value + FeedSearchBar( + isSearchBarClickable = bottomSheetState.value == BottomSheetState.EXPANDED, + feedListSearchBar = state.feedListSearchBar, + modifier = Modifier.conditional(bottomSheetColor.isSpecified) { + background(bottomSheetColor.copy(alpha = .95f)) + }, + startContent = { + Icon( + imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back_28), + contentDescription = null, + tint = TangemTheme.colors2.graphic.neutral.primary, + modifier = Modifier + .size(TangemTheme.dimens2.x11) + .clip(CircleShape) + .hazeEffectTangem { blurRadius = 8.dp } + .clickableSingle( + onClick = clickIntents.onBackClicked, + enabled = bottomSheetState.value == BottomSheetState.EXPANDED, + ) + .padding(TangemTheme.dimens2.x2), + ) + }, + ) } @Composable diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/news/details/DefaultNewsDetailsComponent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/news/details/DefaultNewsDetailsComponent.kt index 9e2476e982..72dd29e76e 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/news/details/DefaultNewsDetailsComponent.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/news/details/DefaultNewsDetailsComponent.kt @@ -17,16 +17,12 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.core.ui.R -import com.tangem.core.ui.components.appbar.TangemTopAppBar -import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM import com.tangem.core.ui.components.bottomsheets.state.BottomSheetState import com.tangem.core.ui.components.haze.hazeEffectTangem 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.res.LocalMainBottomSheetColor -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.markets.TokenMarketParams @@ -46,65 +42,47 @@ internal class DefaultNewsDetailsComponent( @Composable override fun Title(bottomSheetState: State) { - val background = LocalMainBottomSheetColor.current.value val state by newsDetailsModel.state.collectAsStateWithLifecycle() - if (LocalRedesignEnabled.current) { - TangemTopBar( - type = if (LocalIsOpenedInBottomSheet.current) { - TangemTopBarType.BottomSheet - } else { - TangemTopBarType.Default - }, - startContent = { - Icon( - imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back_28), - contentDescription = null, - tint = TangemTheme.colors2.graphic.neutral.primary, - modifier = Modifier - .size(TangemTheme.dimens2.x11) - .clip(CircleShape) - .hazeEffectTangem { blurRadius = 8.dp } - .clickableSingle( - onClick = state.onBackClick, - enabled = bottomSheetState.value == BottomSheetState.EXPANDED, - ) - .padding(TangemTheme.dimens2.x2), - ) - }, - endContent = { - Icon( - imageVector = ImageVector.vectorResource(id = R.drawable.ic_share_new_24), - contentDescription = null, - tint = TangemTheme.colors2.graphic.neutral.primary, - modifier = Modifier - .size(TangemTheme.dimens2.x11) - .clip(CircleShape) - .hazeEffectTangem { blurRadius = 8.dp } - .clickableSingle( - onClick = state.onShareClick, - enabled = bottomSheetState.value == BottomSheetState.EXPANDED && - state.articlesStateUM is ArticlesStateUM.Content, - ) - .padding(TangemTheme.dimens2.x2_5), - ) - }, - ) - } else { - TangemTopAppBar( - containerColor = background, - startButton = TopAppBarButtonUM.Icon( - iconRes = R.drawable.ic_back_24, - onClicked = state.onBackClick, - isEnabled = bottomSheetState.value == BottomSheetState.EXPANDED, - ), - endButton = TopAppBarButtonUM.Icon( - iconRes = R.drawable.ic_share_24, - onClicked = state.onShareClick, - isEnabled = bottomSheetState.value == BottomSheetState.EXPANDED && - state.articlesStateUM is ArticlesStateUM.Content, - ), - ) - } + TangemTopBar( + type = if (LocalIsOpenedInBottomSheet.current) { + TangemTopBarType.BottomSheet + } else { + TangemTopBarType.Default + }, + startContent = { + Icon( + imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back_28), + contentDescription = null, + tint = TangemTheme.colors2.graphic.neutral.primary, + modifier = Modifier + .size(TangemTheme.dimens2.x11) + .clip(CircleShape) + .hazeEffectTangem { blurRadius = 8.dp } + .clickableSingle( + onClick = state.onBackClick, + enabled = bottomSheetState.value == BottomSheetState.EXPANDED, + ) + .padding(TangemTheme.dimens2.x2), + ) + }, + endContent = { + Icon( + imageVector = ImageVector.vectorResource(id = R.drawable.ic_share_new_24), + contentDescription = null, + tint = TangemTheme.colors2.graphic.neutral.primary, + modifier = Modifier + .size(TangemTheme.dimens2.x11) + .clip(CircleShape) + .hazeEffectTangem { blurRadius = 8.dp } + .clickableSingle( + onClick = state.onShareClick, + enabled = bottomSheetState.value == BottomSheetState.EXPANDED && + state.articlesStateUM is ArticlesStateUM.Content, + ) + .padding(TangemTheme.dimens2.x2_5), + ) + }, + ) } @Composable diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/news/list/DefaultNewsListComponent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/news/list/DefaultNewsListComponent.kt index 247990641c..94894974f0 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/news/list/DefaultNewsListComponent.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/news/list/DefaultNewsListComponent.kt @@ -18,8 +18,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.core.ui.R -import com.tangem.core.ui.components.appbar.TangemTopAppBar -import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM import com.tangem.core.ui.components.bottomsheets.state.BottomSheetState import com.tangem.core.ui.components.haze.hazeEffectTangem import com.tangem.core.ui.decompose.ComposableModularBottomSheetContentComponent @@ -27,9 +25,7 @@ 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.resourceReference -import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.res.LocalMainBottomSheetColor -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.domain.news.model.NewsListConfig import com.tangem.features.feed.model.news.list.NewsListModel @@ -48,43 +44,31 @@ internal class DefaultNewsListComponent( override fun Title(bottomSheetState: State) { val background = LocalMainBottomSheetColor.current.value val state by newsListModel.state.collectAsStateWithLifecycle() - if (LocalRedesignEnabled.current) { - TangemTopBar( - modifier = Modifier.background(background.copy(alpha = .95f)), - title = resourceReference(R.string.common_news), - type = if (LocalIsOpenedInBottomSheet.current) { - TangemTopBarType.BottomSheet - } else { - TangemTopBarType.Default - }, - startContent = { - Icon( - imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back_28), - contentDescription = null, - tint = TangemTheme.colors2.graphic.neutral.primary, - modifier = Modifier - .size(TangemTheme.dimens2.x11) - .clip(CircleShape) - .hazeEffectTangem { blurRadius = 8.dp } - .clickableSingle( - onClick = state.onBackClick, - enabled = bottomSheetState.value == BottomSheetState.EXPANDED, - ) - .padding(TangemTheme.dimens2.x2), - ) - }, - ) - } else { - TangemTopAppBar( - containerColor = background, - title = stringResourceSafe(R.string.common_news), - startButton = TopAppBarButtonUM.Icon( - iconRes = R.drawable.ic_back_24, - onClicked = state.onBackClick, - isEnabled = bottomSheetState.value == BottomSheetState.EXPANDED, - ), - ) - } + TangemTopBar( + modifier = Modifier.background(background.copy(alpha = .95f)), + title = resourceReference(R.string.common_news), + type = if (LocalIsOpenedInBottomSheet.current) { + TangemTopBarType.BottomSheet + } else { + TangemTopBarType.Default + }, + startContent = { + Icon( + imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back_28), + contentDescription = null, + tint = TangemTheme.colors2.graphic.neutral.primary, + modifier = Modifier + .size(TangemTheme.dimens2.x11) + .clip(CircleShape) + .hazeEffectTangem { blurRadius = 8.dp } + .clickableSingle( + onClick = state.onBackClick, + enabled = bottomSheetState.value == BottomSheetState.EXPANDED, + ) + .padding(TangemTheme.dimens2.x2), + ) + }, + ) } @Composable 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 ba06896031..3e97dd9b20 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 @@ -13,7 +13,6 @@ import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer -import com.tangem.core.ui.DesignFeatureToggles import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.utils.DateTimeFormatters import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase @@ -60,7 +59,6 @@ internal class FeedComponentModel @Inject constructor( private val fetchTopEarnTokensUseCase: FetchTopEarnTokensUseCase, private val getTopEarnTokensUseCase: GetTopEarnTokensUseCase, private val appRouter: AppRouter, - private val designFeatureToggles: DesignFeatureToggles, private val addToPortfolioManagerFactory: AddToPortfolioManager.Factory, private val forYouFeatureToggles: ForYouFeatureToggles, getTopFiveMarketTokenUseCase: GetTopFiveMarketTokenUseCase, @@ -229,19 +227,11 @@ internal class FeedComponentModel @Inject constructor( currentDate = getCurrentDate(), feedListSearchBar = FeedListSearchBar( placeholderText = resourceReference( - id = if (designFeatureToggles.isRedesignEnabled) { - R.string.markets_search_title_placeholder - } else { - R.string.markets_search_header_title - }, + id = R.string.markets_search_title_placeholder, ), onBarClick = { analyticsEventHandler.send(FeedAnalyticsEvent.TokenSearchedClicked()) - if (designFeatureToggles.isRedesignEnabled) { - params.feedClickIntents.openSearch(AnalyticsParam.ScreensSources.Markets.value) - } else { - params.feedClickIntents.onMarketOpenClick(null) - } + params.feedClickIntents.openSearch(AnalyticsParam.ScreensSources.Markets.value) }, ), feedListCallbacks = FeedListCallbacks( diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/MarketsTokenDetailsModel.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/MarketsTokenDetailsModel.kt index a9006e4bdd..b172858b37 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/MarketsTokenDetailsModel.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/MarketsTokenDetailsModel.kt @@ -21,7 +21,6 @@ import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer import com.tangem.core.navigation.share.ShareManager import com.tangem.core.navigation.url.UrlOpener -import com.tangem.core.ui.DesignFeatureToggles import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent import com.tangem.core.ui.components.marketprice.PriceChangeType @@ -59,7 +58,6 @@ import com.tangem.features.feed.impl.R import com.tangem.features.feed.model.converter.ShortArticleToArticleConfigUMConverter import com.tangem.features.feed.model.market.details.analytics.MarketDetailsAnalyticsEvent import com.tangem.features.feed.model.market.details.converter.DescriptionConverter -import com.tangem.features.feed.model.market.details.converter.ExchangeItemStateConverter import com.tangem.features.feed.model.market.details.converter.ExchangeItemStateConverterV2 import com.tangem.features.feed.model.market.details.converter.TokenMarketInfoConverter import com.tangem.features.feed.model.market.details.formatter.* @@ -92,7 +90,6 @@ internal class MarketsTokenDetailsModel @Inject constructor( getUserCountryUseCase: GetUserCountryUseCase, paramsContainer: ParamsContainer, addToPortfolioManagerFactory: AddToPortfolioManager.Factory, - private val designFeatureToggles: DesignFeatureToggles, private val getTokenPriceChartUseCase: GetTokenPriceChartUseCase, private val getTokenMarketInfoUseCase: GetTokenMarketInfoUseCase, private val getTokenFullQuotesUseCase: GetTokenFullQuotesUseCase, @@ -165,7 +162,6 @@ internal class MarketsTokenDetailsModel @Inject constructor( needApplyFCARestrictions = Provider { userCountry.needApplyFCARestrictions() }, - isRedesignEnabled = designFeatureToggles.isRedesignEnabled, // ================== ) @@ -203,7 +199,7 @@ internal class MarketsTokenDetailsModel @Inject constructor( marketChartLook.copy( type = percentChangeType.toChartType(), - isMinMaxLook = designFeatureToggles.isRedesignEnabled, + isMinMaxLook = true, xAxisFormatter = MarketsDateTimeFormatters.getChartXFormatterByInterval(PriceChangeInterval.H24), yAxisFormatter = { value -> value.format { @@ -244,7 +240,7 @@ internal class MarketsTokenDetailsModel @Inject constructor( val addFundsSheetNavigation = SlotNavigation() private val isAddToPortfolioAvailable: Boolean = - params.shouldShowPortfolio && designFeatureToggles.isRedesignEnabled + params.shouldShowPortfolio val addToPortfolioManager: AddToPortfolioManager = addToPortfolioManagerFactory.create( scope = modelScope, settings = AddToPortfolioManager.Settings( @@ -846,15 +842,9 @@ internal class MarketsTokenDetailsModel @Inject constructor( ExchangesBottomSheetContent.Error(onRetryClick = { onListedOnClick(exchangesCount) }) }, ifRight = { list -> - if (designFeatureToggles.isRedesignEnabled) { - ExchangesBottomSheetContent.ContentV2( - exchangeItemsV2 = ExchangeItemStateConverterV2.convertList(list).toImmutableList(), - ) - } else { - ExchangesBottomSheetContent.ContentV1( - exchangeItems = ExchangeItemStateConverter.convertList(list).toImmutableList(), - ) - } + ExchangesBottomSheetContent.ContentV2( + exchangeItemsV2 = ExchangeItemStateConverterV2.convertList(list).toImmutableList(), + ) }, ) diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/converter/MetricsConverter.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/converter/MetricsConverter.kt index ffd70f6371..00edd6ac64 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/converter/MetricsConverter.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/converter/MetricsConverter.kt @@ -25,7 +25,6 @@ internal class MetricsConverter( private val appCurrency: Provider, private val tokenSymbol: String, private val onInfoClick: (InfoBottomSheetContent) -> Unit, - private val isRedesignEnabled: Boolean, ) : Converter { @Suppress("LongMethod") @@ -118,11 +117,7 @@ internal class MetricsConverter( }, ), ), - metricsV2 = if (isRedesignEnabled) { - convertToMetricsV2UM(value) - } else { - null - }, + metricsV2 = convertToMetricsV2UM(value), ) } } diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/converter/TokenMarketInfoConverter.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/converter/TokenMarketInfoConverter.kt index b564fce453..b0c2eddb35 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/converter/TokenMarketInfoConverter.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/converter/TokenMarketInfoConverter.kt @@ -15,7 +15,6 @@ import com.tangem.utils.converter.Converter @Stable @Suppress("LongParameterList") internal class TokenMarketInfoConverter( - private val isRedesignEnabled: Boolean, private val appCurrency: Provider, private val needApplyFCARestrictions: Provider, private val onInfoClick: (TangemBottomSheetConfigContent) -> Unit, @@ -48,7 +47,6 @@ internal class TokenMarketInfoConverter( tokenSymbol = value.symbol, appCurrency = appCurrency, onInfoClick = onInfoClick, - isRedesignEnabled = isRedesignEnabled, ) val exchangesAmount = value.exchangesAmount diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/details/NewsDetailsModel.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/details/NewsDetailsModel.kt index 15677f60a6..4046160b7a 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/details/NewsDetailsModel.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/details/NewsDetailsModel.kt @@ -9,7 +9,6 @@ import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer import com.tangem.core.navigation.share.ShareManager import com.tangem.core.navigation.url.UrlOpener -import com.tangem.core.ui.DesignFeatureToggles import com.tangem.datasource.api.common.response.ApiResponseError import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase import com.tangem.domain.appcurrency.model.AppCurrency @@ -54,7 +53,6 @@ internal class NewsDetailsModel @Inject constructor( private val markArticleAsViewedUseCase: MarkArticleAsViewedUseCase, private val toggleArticleLikedUseCase: ToggleArticleLikedUseCase, private val analyticsEventHandler: AnalyticsEventHandler, - private val designFeatureToggles: DesignFeatureToggles, paramsContainer: ParamsContainer, ) : Model() { @@ -70,7 +68,6 @@ internal class NewsDetailsModel @Inject constructor( dispatchers = dispatchers, observeNewsDetailsUseCase = observeNewsDetailsUseCase, prefetchedIds = params.preselectedArticlesId.toSet(), - isRedesignEnabled = designFeatureToggles.isRedesignEnabled, ) } diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/details/NewsDetailsPaginationManager.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/details/NewsDetailsPaginationManager.kt index 359d174d80..361f5833f1 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/details/NewsDetailsPaginationManager.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/details/NewsDetailsPaginationManager.kt @@ -19,13 +19,11 @@ internal class NewsDetailsPaginationManager( currentCategoryIds: Provider>, modelScope: CoroutineScope, prefetchedIds: Set, - isRedesignEnabled: Boolean, ) : NewsListBatchFlowManager( getNewsListBatchFlowUseCase = getNewsListBatchFlowUseCase, currentCategoryIds = currentCategoryIds, modelScope = modelScope, dispatchers = dispatchers, - isRedesignEnabled = isRedesignEnabled, ) { private val _cachedPrefetchedIds = MutableStateFlow(prefetchedIds) diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/list/NewsListModel.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/list/NewsListModel.kt index 5975c578b9..df9abe4f57 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/list/NewsListModel.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/list/NewsListModel.kt @@ -4,7 +4,6 @@ import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer -import com.tangem.core.ui.DesignFeatureToggles import com.tangem.core.ui.components.chip.entity.ChipUM import com.tangem.core.ui.event.consumedEvent import com.tangem.core.ui.event.triggeredEvent @@ -36,7 +35,6 @@ internal class NewsListModel @Inject constructor( private val getNewsCategoriesUseCase: GetNewsCategoriesUseCase, private val getNewsListBatchFlowUseCase: GetNewsListBatchFlowUseCase, private val analyticsEventHandler: AnalyticsEventHandler, - private val designFeatureToggles: DesignFeatureToggles, paramsContainer: ParamsContainer, ) : Model() { @@ -59,7 +57,6 @@ internal class NewsListModel @Inject constructor( }, modelScope = modelScope, dispatchers = dispatchers, - isRedesignEnabled = designFeatureToggles.isRedesignEnabled, ) } diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/list/statemanager/NewsListBatchFlowManager.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/list/statemanager/NewsListBatchFlowManager.kt index 03565cab2b..3168369541 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/list/statemanager/NewsListBatchFlowManager.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/news/list/statemanager/NewsListBatchFlowManager.kt @@ -21,7 +21,6 @@ import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch internal open class NewsListBatchFlowManager( - private val isRedesignEnabled: Boolean, getNewsListBatchFlowUseCase: GetNewsListBatchFlowUseCase, private val currentCategoryIds: Provider>, protected val modelScope: CoroutineScope, @@ -30,11 +29,7 @@ internal open class NewsListBatchFlowManager( private val actionsFlow = MutableSharedFlow>() private val converter by lazy { ShortArticleToArticleConfigUMConverter( - isTrending = if (isRedesignEnabled) { - null - } else { - false - }, + isTrending = null, ) } diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/EntryContent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/EntryContent.kt index caf9e63bde..02450a98fb 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/EntryContent.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/EntryContent.kt @@ -3,7 +3,6 @@ package com.tangem.features.feed.ui import androidx.compose.animation.AnimatedContent import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* -import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.runtime.* import androidx.compose.ui.Alignment @@ -22,9 +21,7 @@ import com.tangem.core.ui.components.topFade import com.tangem.core.ui.decompose.ComposableModularBottomSheetContentComponent import com.tangem.core.ui.res.LocalHazeState import com.tangem.core.ui.res.LocalMainBottomSheetColor -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.utils.WindowInsetsZero import com.tangem.features.feed.components.FeedEntryChildFactory import com.tangem.features.feed.ui.utils.FadeConstants.BASE_FADE_LEVEL import com.tangem.features.feed.ui.utils.contentFeedEntryStackAnimation @@ -51,82 +48,11 @@ internal fun EntryContent( isOpenedInBottomSheet: Boolean, ) { CompositionLocalProvider(LocalIsOpenedInBottomSheet provides isOpenedInBottomSheet) { - if (LocalRedesignEnabled.current) { - EntryContentV2( - bottomSheetState = bottomSheetState, - stackState = stackState, - onHeaderSizeChange = onHeaderSizeChange, - onExpandSheet = onExpandSheet, - ) - } else { - EntryContentV1( - bottomSheetState = bottomSheetState, - stackState = stackState, - onHeaderSizeChange = onHeaderSizeChange, - onExpandSheet = onExpandSheet, - ) - } - } -} - -@Composable -private fun EntryContentV1( - bottomSheetState: State, - stackState: State>, - onHeaderSizeChange: (Dp) -> Unit, - onExpandSheet: () -> Unit, -) { - val density = LocalDensity.current - val background = LocalMainBottomSheetColor.current.value - val stackAnimation = remember { contentFeedEntryStackAnimation() } - val isOpenedInBottomSheet = LocalIsOpenedInBottomSheet.current - - Surface(contentColor = background) { - Scaffold( - containerColor = background, - contentWindowInsets = WindowInsetsZero, - topBar = { - Box( - modifier = Modifier - .then( - if (!isOpenedInBottomSheet) { - Modifier.statusBarsPadding() - } else { - Modifier - }, - ) - .onGloballyPositioned { coordinates -> - if (coordinates.size.height > 0) { - with(density) { - onHeaderSizeChange(coordinates.size.height.toDp()) - } - } - }, - ) { - Children( - stack = stackState.value, - animation = stackAnimation, - ) { child -> - child.instance.Title(bottomSheetState) - } - CollapsedTitleClickOverlay( - bottomSheetState = bottomSheetState, - onExpandSheet = onExpandSheet, - ) - } - }, - content = { contentPadding -> - Children( - stack = stackState.value, - animation = stackAnimation, - ) { child -> - child.instance.Content( - modifier = Modifier.padding(contentPadding), - bottomSheetState = bottomSheetState, - contentPadding = PaddingValues(), - ) - } - }, + EntryContentV2( + bottomSheetState = bottomSheetState, + stackState = stackState, + onHeaderSizeChange = onHeaderSizeChange, + onExpandSheet = onExpandSheet, ) } } diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/components/FeedSearchBar.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/components/FeedSearchBar.kt index 23256b58e3..aaf1258e74 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/components/FeedSearchBar.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/components/FeedSearchBar.kt @@ -1,10 +1,8 @@ package com.tangem.features.feed.ui.components -import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -21,7 +19,6 @@ import com.tangem.core.ui.ds.topbar.TangemTopBar import com.tangem.core.ui.ds.topbar.TangemTopBarType import com.tangem.core.ui.extensions.conditional import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.features.feed.ui.LocalIsOpenedInBottomSheet import com.tangem.features.feed.ui.feed.state.FeedListSearchBar @@ -34,56 +31,13 @@ internal fun FeedSearchBar( startContent: @Composable (() -> Unit)? = null, endContent: @Composable (() -> Unit)? = null, ) { - if (LocalRedesignEnabled.current) { - FeedSearchBarV2( - isSearchBarClickable = isSearchBarClickable, - feedListSearchBar = feedListSearchBar, - modifier = modifier, - startContent = startContent, - endContent = endContent, - ) - } else { - FeedSearchBarV1( - isSearchBarClickable = isSearchBarClickable, - feedListSearchBar = feedListSearchBar, - modifier = modifier, - ) - } -} - -@Composable -private fun FeedSearchBarV1( - isSearchBarClickable: Boolean, - feedListSearchBar: FeedListSearchBar, - modifier: Modifier = Modifier, -) { - Row( - modifier = modifier - .padding(horizontal = 16.dp) - .padding(bottom = 8.dp) - .fillMaxWidth() - .clip(RoundedCornerShape(36.dp)) - .background(color = TangemTheme.colors.field.focused) - .conditional(condition = isSearchBarClickable) { - clickable(onClick = feedListSearchBar.onBarClick) - } - .padding(14.dp), - ) { - Icon( - modifier = Modifier.size(TangemTheme.dimens.size20), - imageVector = ImageVector.vectorResource(id = R.drawable.ic_search_24), - tint = TangemTheme.colors.icon.informative, - contentDescription = null, - ) - - SpacerW(14.dp) - - Text( - text = feedListSearchBar.placeholderText.resolveReference(), - style = TangemTheme.typography.body2, - color = TangemTheme.colors.text.tertiary, - ) - } + FeedSearchBarV2( + isSearchBarClickable = isSearchBarClickable, + feedListSearchBar = feedListSearchBar, + modifier = modifier, + startContent = startContent, + endContent = endContent, + ) } @Composable diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/EarnContent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/EarnContent.kt index 60dec31652..5be8e6dd22 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/EarnContent.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/EarnContent.kt @@ -23,7 +23,6 @@ import com.tangem.core.ui.components.currency.icon.CurrencyIconState import com.tangem.core.ui.components.list.InfiniteListHandler import com.tangem.core.ui.decorations.roundedShapeItemDecoration 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.* @@ -40,7 +39,6 @@ internal fun EarnContent(contentPadding: PaddingValues, state: EarnUM, modifier: val density = LocalDensity.current val bottomBarHeight = with(density) { WindowInsets.systemBars.getBottom(this).toDp() } val listState = rememberLazyListState() - val isRedesignEnabled = LocalRedesignEnabled.current if (state.bestOpportunities is EarnBestOpportunitiesUM.Content) { PaginationHandler( @@ -60,7 +58,7 @@ internal fun EarnContent(contentPadding: PaddingValues, state: EarnUM, modifier: SectionHeader( title = stringResourceSafe(R.string.earn_mostly_used), modifier = Modifier.padding( - top = if (isRedesignEnabled) 10.dp else 16.dp, + top = 10.dp, ), ) } @@ -76,7 +74,7 @@ internal fun EarnContent(contentPadding: PaddingValues, state: EarnUM, modifier: SectionHeader( title = stringResourceSafe(R.string.earn_best_opportunities), modifier = Modifier.padding( - top = if (isRedesignEnabled) 32.dp else 20.dp, + top = 32.dp, ), ) } @@ -91,17 +89,12 @@ internal fun EarnContent(contentPadding: PaddingValues, state: EarnUM, modifier: ) } - if (isRedesignEnabled) { - bestOpportunitiesItemsV2(state = state.bestOpportunities) - } else { - bestOpportunitiesItemsV1(state = state.bestOpportunities) - } + bestOpportunitiesItemsV2(state = state.bestOpportunities) } } @Composable private fun MostlyUsedContent(state: EarnListUM, onScroll: () -> Unit) { - val isRedesignEnabled = LocalRedesignEnabled.current AnimatedContent( targetState = state, contentKey = { it::class.java }, @@ -136,20 +129,9 @@ private fun MostlyUsedContent(state: EarnListUM, onScroll: () -> Unit) { modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 12.dp) - .conditionalCompose( - condition = isRedesignEnabled, - modifier = { - background( - color = TangemTheme.colors2.surface.level3, - shape = RoundedCornerShape(TangemTheme.dimens2.x4), - ) - }, - otherModifier = { - background( - color = TangemTheme.colors.background.action, - shape = TangemTheme.shapes.roundedCornersXMedium, - ) - }, + .background( + color = TangemTheme.colors2.surface.level3, + shape = RoundedCornerShape(TangemTheme.dimens2.x4), ) .padding(vertical = 32.dp, horizontal = 12.dp), contentAlignment = Alignment.Center, @@ -177,76 +159,6 @@ private fun BestOpportunitiesFilters( } } -private fun LazyListScope.bestOpportunitiesItemsV1(state: EarnBestOpportunitiesUM) { - when (state) { - is EarnBestOpportunitiesUM.Loading -> { - val lastIndex = PLACEHOLDER_ITEMS_COUNT - 1 - items( - count = PLACEHOLDER_ITEMS_COUNT, - key = { "placeholder_$it" }, - ) { index -> - EarnItemPlaceholderV1( - modifier = Modifier - .roundedShapeItemDecoration( - currentIndex = index, - lastIndex = lastIndex, - backgroundColor = TangemTheme.colors.background.action, - ), - ) - } - } - is EarnBestOpportunitiesUM.Empty -> { - item(key = "best_opportunities_empty") { - SpacerH(12.dp) - BestOpportunitiesEmpty() - } - } - is EarnBestOpportunitiesUM.EmptyFiltered -> { - item(key = "best_opportunities_empty_filtered") { - SpacerH(12.dp) - BestOpportunitiesEmptyFiltered(onClearFilterClick = state.onClearFilterClick) - } - } - is EarnBestOpportunitiesUM.Content -> { - if (state.items.isNotEmpty()) { - val lastIndex = state.items.lastIndex - itemsIndexed( - items = state.items, - key = { _, item -> "${item.tokenName}-${item.network}" }, - ) { index, item -> - EarnListItem( - item = item, - modifier = Modifier - .roundedShapeItemDecoration( - currentIndex = index, - lastIndex = lastIndex, - backgroundColor = TangemTheme.colors.background.action, - ), - ) - } - } - } - is EarnBestOpportunitiesUM.Error -> { - item(key = "best_opportunities_error") { - SpacerH(12.dp) - Box( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .background( - color = TangemTheme.colors.background.action, - shape = TangemTheme.shapes.roundedCornersXMedium, - ) - .padding(vertical = 32.dp, horizontal = 12.dp), - contentAlignment = Alignment.Center, - ) { - UnableToLoadData(onRetryClick = state.onRetryClicked) - } - } - } - } -} - private fun LazyListScope.bestOpportunitiesItemsV2(state: EarnBestOpportunitiesUM) { when (state) { is EarnBestOpportunitiesUM.Loading -> { @@ -320,53 +232,32 @@ private fun LazyListScope.bestOpportunitiesItemsV2(state: EarnBestOpportunitiesU @Composable private fun FilterButtonsShimmer(modifier: Modifier = Modifier) { Row(modifier = modifier.padding(horizontal = 16.dp, vertical = 4.dp)) { - if (LocalRedesignEnabled.current) { - RectangleShimmer( - modifier = Modifier - .width(130.dp) - .height(36.dp), - radius = TangemTheme.dimens2.x25, - ) - SpacerWMax() - RectangleShimmer( - modifier = Modifier - .width(106.dp) - .height(36.dp), - radius = TangemTheme.dimens2.x25, - ) - } else { - SmallButtonShimmer( - modifier = Modifier.width(110.dp), - ) - SpacerWMax() - SmallButtonShimmer( - modifier = Modifier.width(90.dp), - ) - } + RectangleShimmer( + modifier = Modifier + .width(130.dp) + .height(36.dp), + radius = TangemTheme.dimens2.x25, + ) + SpacerWMax() + RectangleShimmer( + modifier = Modifier + .width(106.dp) + .height(36.dp), + radius = TangemTheme.dimens2.x25, + ) } } @Composable private fun SectionHeader(title: String, modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - Text( - modifier = modifier - .fillMaxWidth() - .padding(horizontal = 24.dp), - text = title, - style = TangemTheme.typography2.headingSemibold20, - color = TangemTheme.colors2.text.neutral.primary, - ) - } else { - Text( - modifier = modifier - .fillMaxWidth() - .padding(start = 20.dp, end = 16.dp), - text = title, - style = TangemTheme.typography.h3, - color = TangemTheme.colors.text.primary1, - ) - } + Text( + modifier = modifier + .fillMaxWidth() + .padding(horizontal = 24.dp), + text = title, + style = TangemTheme.typography2.headingSemibold20, + color = TangemTheme.colors2.text.neutral.primary, + ) } @Composable diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/BestOpportunitiesEmpty.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/BestOpportunitiesEmpty.kt index 2eac5ad631..c9cc65dc3d 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/BestOpportunitiesEmpty.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/BestOpportunitiesEmpty.kt @@ -10,55 +10,16 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp import com.tangem.core.ui.R import com.tangem.core.ui.components.SpacerH import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme @Composable internal fun BestOpportunitiesEmpty(modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - BestOpportunitiesEmptyV2(modifier) - } else { - BestOpportunitiesEmptyV1(modifier) - } -} - -@Composable -private fun BestOpportunitiesEmptyV1(modifier: Modifier = Modifier) { - Column( - modifier = modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .background( - color = TangemTheme.colors.background.action, - shape = TangemTheme.shapes.roundedCornersXMedium, - ) - .padding(vertical = 32.dp, horizontal = 12.dp), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Icon( - modifier = Modifier - .fillMaxWidth(), - painter = painterResource(R.drawable.ic_empty_64), - contentDescription = null, - tint = Color.Unspecified, - ) - SpacerH(TangemTheme.dimens2.x6) - Text( - modifier = Modifier - .padding(horizontal = TangemTheme.dimens2.x8), - text = stringResourceSafe(R.string.earn_empty), - style = TangemTheme.typography.body2, - color = TangemTheme.colors.text.tertiary, - textAlign = TextAlign.Center, - ) - } + BestOpportunitiesEmptyV2(modifier) } @Composable diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/BestOpportunitiesEmptyFiltered.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/BestOpportunitiesEmptyFiltered.kt index 755b7df0a2..ddd943fe85 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/BestOpportunitiesEmptyFiltered.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/BestOpportunitiesEmptyFiltered.kt @@ -9,24 +9,16 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -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.buttons.SecondarySmallButton -import com.tangem.core.ui.components.buttons.SmallButtonConfig import com.tangem.core.ui.ds.button.* import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme @Composable internal fun BestOpportunitiesEmptyFiltered(onClearFilterClick: () -> Unit, modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - BestOpportunitiesEmptyFilteredV2(onClearFilterClick, modifier) - } else { - BestOpportunitiesEmptyFilteredV1(onClearFilterClick, modifier) - } + BestOpportunitiesEmptyFilteredV2(onClearFilterClick, modifier) } @Composable @@ -58,32 +50,4 @@ private fun BestOpportunitiesEmptyFilteredV2(onClearFilterClick: () -> Unit, mod ), ) } -} - -@Composable -private fun BestOpportunitiesEmptyFilteredV1(onClearFilterClick: () -> Unit, modifier: Modifier = Modifier) { - Column( - modifier = modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .background( - color = TangemTheme.colors.background.action, - shape = TangemTheme.shapes.roundedCornersXMedium, - ) - .padding(vertical = 32.dp, horizontal = 12.dp), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Text( - text = stringResourceSafe(R.string.earn_no_results), - style = TangemTheme.typography.body2, - color = TangemTheme.colors.text.tertiary, - ) - SpacerH(12.dp) - SecondarySmallButton( - config = SmallButtonConfig( - text = resourceReference(R.string.earn_clear_filter), - onClick = onClearFilterClick, - ), - ) - } } \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/EarnFilterByNetworkBottomSheet.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/EarnFilterByNetworkBottomSheet.kt index bb5e5b99d4..c8b0498530 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/EarnFilterByNetworkBottomSheet.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/EarnFilterByNetworkBottomSheet.kt @@ -3,39 +3,25 @@ package com.tangem.features.feed.ui.earn.components import android.content.res.Configuration import androidx.compose.foundation.* import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.LazyListScope -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.layoutId -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.util.fastForEachIndexed -import com.tangem.core.ui.components.SpacerH import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig -import com.tangem.core.ui.components.bottomsheets.sheet.TangemBottomSheet -import com.tangem.core.ui.components.inputrow.InputRowChecked -import com.tangem.core.ui.components.inputrow.inner.DividerContainer -import com.tangem.core.ui.components.rows.RowContentContainer -import com.tangem.core.ui.components.rows.RowText import com.tangem.core.ui.decorations.roundedShapeItemDecoration import com.tangem.core.ui.ds.checkbox.TangemCheckbox import com.tangem.core.ui.ds.row.TangemRowContainer import com.tangem.core.ui.ds.row.TangemRowLayoutId import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.res.TangemThemePreviewRedesign @@ -48,62 +34,12 @@ import kotlinx.collections.immutable.toImmutableList @Composable internal fun EarnFilterByNetworkBottomSheet(config: TangemBottomSheetConfig) { - if (LocalRedesignEnabled.current) { - EarnFilterByNetworkBottomSheetV2(config = config) - } else { - EarnFilterByNetworkBottomSheetV1(config = config) - } -} - -@Composable -private fun EarnFilterByNetworkBottomSheetV1(config: TangemBottomSheetConfig) { - TangemBottomSheet( - config = config, - titleText = resourceReference(R.string.earn_filter_by), - containerColor = TangemTheme.colors.background.tertiary, - content = { ContentV1(it) }, - ) -} - -@Composable -private fun EarnFilterByNetworkBottomSheetV2(config: TangemBottomSheetConfig) { EarnFilterBottomSheet( config = config, content = { ContentV2(it) }, ) } -@Composable -private fun ContentV1(content: EarnFilterByNetworkBottomSheetContentUM) { - val allMyNetworks = remember(content) { - content.networks.filterIsInstance() + - content.networks.filterIsInstance() - } - val specificNetworks = remember(content) { content.networks.filterIsInstance() } - - LazyColumn( - contentPadding = PaddingValues( - start = TangemTheme.dimens.spacing16, - end = TangemTheme.dimens.spacing16, - bottom = TangemTheme.dimens.spacing16, - ), - ) { - allMyNetworksList( - allMyNetworks = allMyNetworks, - onOptionClicked = content.onOptionClick, - ) - - if (specificNetworks.isNotEmpty()) { - networksHeader() - - specificNetworksList( - specificNetworks = specificNetworks, - onOptionClicked = content.onOptionClick, - ) - } - } -} - @Composable private fun ContentV2(content: EarnFilterByNetworkBottomSheetContentUM) { val allMyNetworks = remember(content) { @@ -250,125 +186,6 @@ private fun SpecificNetworksBlock( } } -private fun LazyListScope.allMyNetworksList( - allMyNetworks: List, - onOptionClicked: (EarnFilterNetworkUM) -> Unit, -) { - itemsIndexed( - items = allMyNetworks, - key = { _, item -> - when (item) { - is EarnFilterNetworkUM.AllNetworks -> "all_networks" - is EarnFilterNetworkUM.MyNetworks -> "my_networks" - is EarnFilterNetworkUM.Network -> item.id - } - }, - ) { index, item -> - DividerContainer( - modifier = Modifier - .roundedShapeItemDecoration( - currentIndex = index, - lastIndex = allMyNetworks.lastIndex, - addDefaultPadding = false, - ) - .background(TangemTheme.colors.background.action) - .clickable { onOptionClicked(item) }, - showDivider = index != allMyNetworks.lastIndex, - ) { - InputRowChecked( - text = when (item) { - is EarnFilterNetworkUM.AllNetworks -> TextReference.Res(R.string.earn_filter_all_networks) - is EarnFilterNetworkUM.MyNetworks -> TextReference.Res(R.string.earn_filter_my_networks) - is EarnFilterNetworkUM.Network -> TextReference.Str(item.text) - }, - checked = item.isSelected, - ) - } - } -} - -private fun LazyListScope.networksHeader() { - item(key = "networks_header") { - SpacerH(TangemTheme.dimens.spacing16) - - Text( - modifier = Modifier - .fillMaxWidth() - .background( - color = TangemTheme.colors.background.action, - shape = RoundedCornerShape( - topStart = 16.dp, - topEnd = 16.dp, - ), - ) - .padding( - start = 12.dp, - end = 12.dp, - top = 12.dp, - bottom = 4.dp, - ), - text = stringResourceSafe(id = R.string.earn_filter_networks), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.tertiary, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - } -} - -private fun LazyListScope.specificNetworksList( - specificNetworks: List, - onOptionClicked: (EarnFilterNetworkUM) -> Unit, -) { - itemsIndexed( - items = specificNetworks, - key = { _, item -> item.id }, - ) { index, item -> - DividerContainer( - modifier = Modifier - .height(52.dp) - .roundedShapeItemDecoration( - currentIndex = index + 1, - lastIndex = specificNetworks.lastIndex + 1, - addDefaultPadding = false, - ) - .background(TangemTheme.colors.background.action) - .clickable { onOptionClicked(item) }, - showDivider = false, - ) { - RowContentContainer( - modifier = Modifier - .heightIn(52.dp) - .padding(horizontal = 12.dp), - icon = { - Image( - modifier = Modifier.size(22.dp), - imageVector = ImageVector.vectorResource(item.iconRes), - contentDescription = item.symbol, - ) - }, - text = { - RowText( - mainText = item.text, - secondText = item.symbol, - accentMainText = true, - accentSecondText = false, - ) - }, - action = { - if (item.isSelected) { - Icon( - painter = painterResource(R.drawable.ic_check_24), - contentDescription = null, - tint = TangemTheme.colors.icon.accent, - ) - } - }, - ) - } - } -} - @Preview(widthDp = 360, heightDp = 800) @Preview(widthDp = 360, heightDp = 800, uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/EarnFilterByTypeBottomSheet.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/EarnFilterByTypeBottomSheet.kt index 6b6da63857..29d665f07d 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/EarnFilterByTypeBottomSheet.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/EarnFilterByTypeBottomSheet.kt @@ -4,7 +4,6 @@ import android.content.res.Configuration import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text @@ -15,81 +14,25 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig -import com.tangem.core.ui.components.bottomsheets.sheet.TangemBottomSheet -import com.tangem.core.ui.components.inputrow.InputRowChecked -import com.tangem.core.ui.components.inputrow.inner.DividerContainer import com.tangem.core.ui.decorations.roundedShapeItemDecoration import com.tangem.core.ui.ds.checkbox.TangemCheckbox import com.tangem.core.ui.ds.row.TangemRowContainer import com.tangem.core.ui.ds.row.TangemRowLayoutId import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.extensions.resourceReference -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.res.TangemThemePreviewRedesign -import com.tangem.features.feed.impl.R import com.tangem.features.feed.ui.earn.state.EarnFilterByTypeBottomSheetContentUM import com.tangem.features.feed.ui.earn.state.EarnFilterTypeUM @Composable internal fun EarnFilterByTypeBottomSheet(config: TangemBottomSheetConfig) { - if (LocalRedesignEnabled.current) { - EarnFilterByTypeBottomSheetV2(config) - } else { - EarnFilterByTypeBottomSheetV1(config) - } -} - -@Composable -private fun EarnFilterByTypeBottomSheetV1(config: TangemBottomSheetConfig) { - TangemBottomSheet( - config = config, - titleText = resourceReference(R.string.earn_filter_by), - containerColor = TangemTheme.colors.background.tertiary, - content = { ContentV1(it) }, - ) -} - -@Composable -private fun EarnFilterByTypeBottomSheetV2(config: TangemBottomSheetConfig) { EarnFilterBottomSheet( config = config, content = { ContentV2(it) }, ) } -@Composable -private fun ContentV1(content: EarnFilterByTypeBottomSheetContentUM) { - Column( - modifier = Modifier - .padding( - start = TangemTheme.dimens.spacing16, - end = TangemTheme.dimens.spacing16, - bottom = TangemTheme.dimens.spacing16, - ), - ) { - EarnFilterTypeUM.entries.forEachIndexed { index, type -> - DividerContainer( - modifier = Modifier - .roundedShapeItemDecoration( - currentIndex = index, - lastIndex = EarnFilterTypeUM.entries.lastIndex, - addDefaultPadding = false, - ) - .background(TangemTheme.colors.background.action) - .clickable { content.onOptionClick(type) }, - showDivider = index != EarnFilterTypeUM.entries.lastIndex, - ) { - InputRowChecked( - text = type.text, - checked = type == content.selectedOption, - ) - } - } - } -} - @Composable private fun ContentV2(content: EarnFilterByTypeBottomSheetContentUM) { CardFilterBlock( diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/EarnListItem.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/EarnListItem.kt index b4b2932dca..0770f57f0d 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/EarnListItem.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/EarnListItem.kt @@ -9,8 +9,6 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.layoutId import androidx.compose.ui.res.vectorResource @@ -20,7 +18,6 @@ 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.SpacerW -import com.tangem.core.ui.components.currency.icon.CurrencyIcon import com.tangem.core.ui.components.currency.icon.CurrencyIconState import com.tangem.core.ui.ds.image.TangemIcon import com.tangem.core.ui.ds.image.TangemIconUM @@ -35,74 +32,10 @@ import com.tangem.features.feed.ui.earn.state.EarnListItemUM @Composable internal fun EarnListItem(item: EarnListItemUM, modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - EarnListItemV2( - item = item, - modifier = modifier, - ) - } else { - EarnListItemV1( - item = item, - modifier = modifier, - ) - } -} - -@Composable -private fun EarnListItemV1(item: EarnListItemUM, modifier: Modifier = Modifier) { - Row( - modifier = modifier - .fillMaxWidth() - .clip(RectangleShape) - .clickable { item.onItemClick() } - .padding( - horizontal = 12.dp, - vertical = 15.dp, - ), - verticalAlignment = Alignment.CenterVertically, - ) { - CurrencyIcon( - modifier = Modifier.size(36.dp), - state = item.currencyIconState, - shouldDisplayNetwork = true, - networkBadgeBackground = TangemTheme.colors.background.action, - ) - - SpacerW(12.dp) - - Column(modifier = Modifier.weight(1f)) { - TokenTitle( - name = item.tokenName.resolveReference(), - symbol = item.symbol.resolveReference(), - ) - SpacerH(2.dp) - Text( - text = item.network.resolveReference(), - color = TangemTheme.colors.text.tertiary, - style = TangemTheme.typography.caption2, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - } - - SpacerW(8.dp) - - Column(horizontalAlignment = Alignment.End) { - Text( - text = item.earnValue.resolveReference(), - color = TangemTheme.colors.text.accent, - style = TangemTheme.typography.body2, - maxLines = 1, - ) - SpacerH(2.dp) - Text( - text = item.earnTypeTitle.resolveReference(), - color = TangemTheme.colors.text.tertiary, - style = TangemTheme.typography.caption2, - maxLines = 1, - ) - } - } + EarnListItemV2( + item = item, + modifier = modifier, + ) } @Composable @@ -158,47 +91,25 @@ private fun EarnListItemV2(item: EarnListItemUM, modifier: Modifier = Modifier) @Composable private fun TokenTitle(name: String, symbol: String, modifier: Modifier = Modifier) { Row(modifier = modifier) { - if (LocalRedesignEnabled.current) { - Text( - modifier = Modifier - .weight(1f, fill = false) - .alignByBaseline(), - text = name, - color = TangemTheme.colors2.text.neutral.primary, - style = TangemTheme.typography2.bodySemibold16, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - SpacerW(4.dp) - Text( - modifier = Modifier.alignByBaseline(), - text = symbol, - color = TangemTheme.colors2.text.neutral.secondary, - style = TangemTheme.typography2.captionSemibold12, - maxLines = 1, - overflow = TextOverflow.Visible, - ) - } else { - Text( - modifier = Modifier - .weight(1f, fill = false) - .alignByBaseline(), - text = name, - color = TangemTheme.colors.text.primary1, - style = TangemTheme.typography.subtitle2, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - SpacerW(4.dp) - Text( - modifier = Modifier.alignByBaseline(), - text = symbol, - color = TangemTheme.colors.text.tertiary, - style = TangemTheme.typography.body2, - maxLines = 1, - overflow = TextOverflow.Visible, - ) - } + Text( + modifier = Modifier + .weight(1f, fill = false) + .alignByBaseline(), + text = name, + color = TangemTheme.colors2.text.neutral.primary, + style = TangemTheme.typography2.bodySemibold16, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + SpacerW(4.dp) + Text( + modifier = Modifier.alignByBaseline(), + text = symbol, + color = TangemTheme.colors2.text.neutral.secondary, + style = TangemTheme.typography2.captionSemibold12, + maxLines = 1, + overflow = TextOverflow.Visible, + ) } } diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/EarnListPlaceholder.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/EarnListPlaceholder.kt index 021838ec9a..975ec82ab1 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/EarnListPlaceholder.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/EarnListPlaceholder.kt @@ -10,71 +10,8 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.tangem.core.ui.components.* import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.res.TangemThemePreviewRedesign -@Composable -internal fun EarnItemPlaceholderV1(modifier: Modifier = Modifier) { - Row( - modifier = modifier - .fillMaxWidth() - .padding( - horizontal = 16.dp, - vertical = 12.dp, - ), - verticalAlignment = Alignment.CenterVertically, - ) { - CircleShimmer(modifier = Modifier.size(36.dp)) - - SpacerW(12.dp) - - Column( - modifier = Modifier - .weight(1f) - .padding(top = 4.dp), - ) { - Row( - modifier = Modifier.fillMaxWidth(), - ) { - RectangleShimmer( - modifier = Modifier - .width(70.dp) - .height(12.dp), - radius = 4.dp, - ) - SpacerWMax() - RectangleShimmer( - modifier = Modifier - .width(40.dp) - .height(12.dp), - radius = 4.dp, - ) - } - - SpacerH(8.dp) - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - ) { - RectangleShimmer( - modifier = Modifier - .width(52.dp) - .height(12.dp), - radius = 4.dp, - ) - SpacerWMax() - RectangleShimmer( - modifier = Modifier - .width(40.dp) - .height(12.dp), - radius = 4.dp, - ) - } - } - } -} - @Composable internal fun EarnItemPlaceholderV2(modifier: Modifier = Modifier) { Row( @@ -127,22 +64,6 @@ internal fun EarnItemPlaceholderV2(modifier: Modifier = Modifier) { private const val PLACEHOLDER_ITEMS_COUNT = 8 -@Preview(showBackground = true, widthDp = 360) -@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun EarnListPlaceholderPreviewV1() { - TangemThemePreview { - Column( - modifier = Modifier - .background(TangemTheme.colors.background.tertiary), - ) { - repeat(PLACEHOLDER_ITEMS_COUNT) { - EarnItemPlaceholderV1() - } - } - } -} - @Preview(showBackground = true, widthDp = 360) @Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/FilterButtons.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/FilterButtons.kt index ad1a4bae06..d95a4bdbef 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/FilterButtons.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/FilterButtons.kt @@ -7,15 +7,11 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.tangem.core.ui.R import com.tangem.core.ui.components.SpacerWMax -import com.tangem.core.ui.components.buttons.SecondarySmallButton -import com.tangem.core.ui.components.buttons.SmallButtonConfig -import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition import com.tangem.core.ui.ds.button.PrimaryInverseTangemButton import com.tangem.core.ui.ds.button.TangemButtonShape import com.tangem.core.ui.ds.button.TangemButtonSize import com.tangem.core.ui.ds.image.TangemIconUM import com.tangem.core.ui.extensions.TextReference -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.features.feed.ui.earn.state.EarnFilterNetworkUM import com.tangem.features.feed.ui.earn.state.EarnFilterUM @@ -27,57 +23,12 @@ internal fun FilterButtons( onTypeFilterClick: () -> Unit, modifier: Modifier = Modifier, ) { - if (LocalRedesignEnabled.current) { - FilterButtonsV2( - earnFilterUM = earnFilterUM, - onNetworkFilterClick = onNetworkFilterClick, - onTypeFilterClick = onTypeFilterClick, - modifier = modifier, - ) - } else { - FilterButtonsV1( - earnFilterUM = earnFilterUM, - onNetworkFilterClick = onNetworkFilterClick, - onTypeFilterClick = onTypeFilterClick, - modifier = modifier, - ) - } -} - -@Composable -private fun FilterButtonsV1( - earnFilterUM: EarnFilterUM, - onNetworkFilterClick: () -> Unit, - onTypeFilterClick: () -> Unit, - modifier: Modifier = Modifier, -) { - Row( - modifier = modifier.padding(horizontal = 16.dp), - ) { - SecondarySmallButton( - config = SmallButtonConfig( - text = when (earnFilterUM.selectedNetworkFilter) { - is EarnFilterNetworkUM.AllNetworks -> TextReference.Res(R.string.earn_filter_all_networks) - is EarnFilterNetworkUM.MyNetworks -> TextReference.Res(R.string.earn_filter_my_networks) - is EarnFilterNetworkUM.Network -> TextReference.Str(earnFilterUM.selectedNetworkFilter.text) - }, - onClick = onNetworkFilterClick, - icon = TangemButtonIconPosition.End(iconResId = R.drawable.ic_chevron_24), - isEnabled = earnFilterUM.isNetworkFilterEnabled, - ), - ) - - SpacerWMax() - - SecondarySmallButton( - config = SmallButtonConfig( - text = earnFilterUM.selectedTypeFilter.text, - onClick = onTypeFilterClick, - icon = TangemButtonIconPosition.End(iconResId = R.drawable.ic_chevron_24), - isEnabled = earnFilterUM.isTypeFilterEnabled, - ), - ) - } + FilterButtonsV2( + earnFilterUM = earnFilterUM, + onNetworkFilterClick = onNetworkFilterClick, + onTypeFilterClick = onTypeFilterClick, + modifier = modifier, + ) } @Composable diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/MostlyUsedCard.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/MostlyUsedCard.kt index 33fe2fd816..089927bdaf 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/MostlyUsedCard.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/MostlyUsedCard.kt @@ -25,19 +25,11 @@ import com.tangem.features.feed.ui.earn.state.EarnListItemUM @Composable internal fun MostlyUsedCard(item: EarnListItemUM, onClick: () -> Unit, modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - MostlyUsedCardV2( - modifier = modifier, - item = item, - onClick = onClick, - ) - } else { - MostlyUsedCardV1( - modifier = modifier, - item = item, - onClick = onClick, - ) - } + MostlyUsedCardV2( + modifier = modifier, + item = item, + onClick = onClick, + ) } @Composable @@ -91,84 +83,6 @@ private fun MostlyUsedCardV2(item: EarnListItemUM, onClick: () -> Unit, modifier } } -@Composable -private fun MostlyUsedCardV1(item: EarnListItemUM, onClick: () -> Unit, modifier: Modifier = Modifier) { - Column( - modifier = modifier - .width(148.dp) - .clip(TangemTheme.shapes.roundedCornersXMedium) - .background(TangemTheme.colors.background.action) - .clickable(onClick = onClick) - .padding(12.dp), - ) { - CurrencyIcon( - modifier = Modifier.size(32.dp), - state = item.currencyIconState, - shouldDisplayNetwork = true, - networkBadgeSize = 12.dp, - networkBadgeBackground = TangemTheme.colors.background.action, - ) - - SpacerH(8.dp) - - Row( - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - modifier = Modifier.weight(weight = 1f, fill = false), - text = item.tokenName.resolveReference(), - color = TangemTheme.colors.text.primary1, - style = TangemTheme.typography.subtitle2, - overflow = TextOverflow.Ellipsis, - maxLines = 1, - ) - SpacerW(4.dp) - Text( - text = item.symbol.resolveReference(), - color = TangemTheme.colors.text.tertiary, - style = TangemTheme.typography.subtitle2, - maxLines = 1, - ) - } - - SpacerH(2.dp) - - Text( - text = item.earnValue.resolveReference(), - color = TangemTheme.colors.text.accent, - style = TangemTheme.typography.caption1, - maxLines = 1, - ) - } -} - -@Preview(showBackground = true, widthDp = 360) -@Composable -private fun EarnListItemPreviewV1() { - TangemThemePreview { - MostlyUsedCardV1( - EarnListItemUM( - network = stringReference("Ethereum"), - symbol = stringReference("USDT"), - tokenName = stringReference("Tether"), - currencyIconState = CurrencyIconState.TokenIcon( - url = null, - topBadgeIconResId = R.drawable.img_eth_22, - fallbackTint = TangemColorPalette.Black, - fallbackBackground = TangemColorPalette.Meadow, - isGrayscale = false, - shouldShowCustomBadge = false, - ), - earnValue = stringReference("APY 6.54%"), - earnTypeTitle = stringReference("Yield"), - earnType = EarnType.YIELD, - onItemClick = {}, - ), - onClick = {}, - ) - } -} - @Preview(showBackground = true, widthDp = 360) @Composable private fun EarnListItemPreviewV2() { diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/MostlyUsedPlaceholder.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/MostlyUsedPlaceholder.kt index e27c045736..b848dcdbf9 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/MostlyUsedPlaceholder.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/earn/components/MostlyUsedPlaceholder.kt @@ -12,7 +12,6 @@ import androidx.compose.ui.unit.dp import com.tangem.core.ui.components.CircleShimmer import com.tangem.core.ui.components.RectangleShimmer import com.tangem.core.ui.components.SpacerH -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.res.TangemThemePreviewRedesign @@ -31,48 +30,11 @@ internal fun MostlyUsedPlaceholder( horizontalArrangement = Arrangement.spacedBy(8.dp), ) { items(PLACEHOLDER_ITEMS_COUNT) { - if (LocalRedesignEnabled.current) { - MostlyUsedItemPlaceholderV2() - } else { - MostlyUsedItemPlaceholderV1() - } + MostlyUsedItemPlaceholderV2() } } } -@Composable -private fun MostlyUsedItemPlaceholderV1(modifier: Modifier = Modifier) { - Column( - modifier = modifier - .width(148.dp) - .height(102.dp) - .background( - color = TangemTheme.colors.background.action, - shape = TangemTheme.shapes.roundedCornersXMedium, - ) - .padding(12.dp), - ) { - CircleShimmer( - modifier = Modifier - .size(32.dp), - ) - SpacerH(8.dp) - RectangleShimmer( - modifier = Modifier - .width(74.dp) - .height(20.dp), - radius = 4.dp, - ) - SpacerH(2.dp) - RectangleShimmer( - modifier = Modifier - .width(84.dp) - .height(16.dp), - radius = 4.dp, - ) - } -} - @Composable private fun MostlyUsedItemPlaceholderV2(modifier: Modifier = Modifier) { Column( 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 d3882f8bf9..ae6cbac798 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 @@ -10,7 +10,6 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Icon import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.platform.testTag @@ -106,12 +105,10 @@ private fun FeedListContent( .padding(bottom = WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding()) .drawBehind { drawRect(background) }, ) { - if (LocalRedesignEnabled.current) { - SpacerH(contentPadding.calculateTopPadding()) - } + SpacerH(contentPadding.calculateTopPadding()) DateBlock(state.currentDate) - if (state.forYouBannerUM is ForYouBannerUM.Content && LocalRedesignEnabled.current) { + if (state.forYouBannerUM is ForYouBannerUM.Content) { SpacerH(16.dp) TangemMessageBanner( title = resourceReference(R.string.for_you_title), @@ -164,17 +161,7 @@ private fun FeedListContent( @Preview(showBackground = true, heightDp = 1500) @Composable private fun FeedListPreview() { - TangemThemePreview { + TangemThemePreviewRedesign { FeedList(state = createFeedPreviewState(), contentPadding = PaddingValues()) } -} - -@Preview(showBackground = true, heightDp = 1500) -@Composable -private fun FeedListPreviewV2() { - TangemThemePreviewRedesign { - CompositionLocalProvider(LocalRedesignEnabled provides true) { - FeedList(state = createFeedPreviewState(), contentPadding = PaddingValues()) - } - } } \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/BlockHeader.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/BlockHeader.kt index d85eb11789..9b6dc33ae8 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/BlockHeader.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/BlockHeader.kt @@ -16,11 +16,7 @@ import com.tangem.core.ui.R import com.tangem.core.ui.components.RectangleShimmer import com.tangem.core.ui.components.SpacerH import com.tangem.core.ui.components.SpacerW -import com.tangem.core.ui.components.buttons.SecondarySmallButton -import com.tangem.core.ui.components.buttons.SmallButtonConfig -import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme @Composable @@ -31,10 +27,7 @@ internal fun ColumnScope.Header( modifier: Modifier = Modifier, title: @Composable () -> Unit, ) { - val isRedesignEnabled = LocalRedesignEnabled.current - if (isRedesignEnabled) { - SpacerH(12.dp) - } + SpacerH(12.dp) AnimatedContent( targetState = isLoading, modifier = modifier, @@ -45,45 +38,32 @@ internal fun ColumnScope.Header( verticalAlignment = Alignment.CenterVertically, ) { if (animatedState) { - if (isRedesignEnabled) { - RectangleShimmer( - modifier = Modifier.size(width = 130.dp, height = 24.dp), - radius = TangemTheme.dimens2.x25, - ) - } else { - RectangleShimmer(modifier = Modifier.size(width = 104.dp, height = 18.dp)) - } + RectangleShimmer( + modifier = Modifier.size(width = 130.dp, height = 24.dp), + radius = TangemTheme.dimens2.x25, + ) } else { Box(modifier = Modifier.weight(1f)) { title() } SpacerW(8.dp) AnimatedVisibility(shouldShowSeeAll) { - if (isRedesignEnabled) { - Row( - modifier = Modifier - .padding(start = 8.dp) - .clickable(onClick = onSeeAllClick), - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - text = stringResourceSafe(R.string.common_see_all), - color = TangemTheme.colors2.text.neutral.primary, - style = TangemTheme.typography2.bodySemibold16, - ) - Icon( - modifier = Modifier.size(24.dp), - imageVector = ImageVector.vectorResource(R.drawable.ic_chevron_small_right_24), - tint = TangemTheme.colors2.markers.iconGray, - contentDescription = null, - ) - } - } else { - SecondarySmallButton( - config = SmallButtonConfig( - text = TextReference.Res(R.string.common_see_all), - onClick = onSeeAllClick, - ), + Row( + modifier = Modifier + .padding(start = 8.dp) + .clickable(onClick = onSeeAllClick), + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = stringResourceSafe(R.string.common_see_all), + color = TangemTheme.colors2.text.neutral.primary, + style = TangemTheme.typography2.bodySemibold16, + ) + Icon( + modifier = Modifier.size(24.dp), + imageVector = ImageVector.vectorResource(R.drawable.ic_chevron_small_right_24), + tint = TangemTheme.colors2.markers.iconGray, + contentDescription = null, ) } } diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/ChartsFilterChip.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/ChartsFilterChip.kt deleted file mode 100644 index 4f36a6b094..0000000000 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/ChartsFilterChip.kt +++ /dev/null @@ -1,51 +0,0 @@ -package com.tangem.features.feed.ui.feed.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Text -import androidx.compose.material3.ripple -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.unit.dp -import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.res.TangemTheme -import com.tangem.features.feed.model.market.list.state.SortByTypeUM - -@Composable -internal fun ChartsFilterChip(sortByTypeUM: SortByTypeUM, isSelected: Boolean, onClick: () -> Unit) { - Box( - modifier = Modifier - .clip(shape = RoundedCornerShape(12.dp)) - .background( - color = if (isSelected) { - TangemTheme.colors.button.primary - } else { - TangemTheme.colors.button.secondary - }, - ) - .clickable( - onClick = onClick, - indication = ripple(), - interactionSource = remember { MutableInteractionSource() }, - ) - .padding(vertical = 8.dp, horizontal = 24.dp), - contentAlignment = Alignment.Center, - ) { - Text( - text = sortByTypeUM.text.resolveReference(), - style = TangemTheme.typography.button, - color = if (isSelected) { - TangemTheme.colors.text.primary2 - } else { - TangemTheme.colors.text.primary1 - }, - ) - } -} \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/DateBlock.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/DateBlock.kt index 2c3ffe2bd8..89fa5c2bef 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/DateBlock.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/DateBlock.kt @@ -5,45 +5,13 @@ import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp import com.tangem.core.ui.R import com.tangem.core.ui.components.SpacerH import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme @Composable internal fun DateBlock(currentDate: String) { - if (LocalRedesignEnabled.current) { - DateBlockV2(currentDate) - } else { - DateBlockV1(currentDate) - } -} - -@Composable -private fun DateBlockV1(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, - ) -} - -@Composable -private fun DateBlockV2(currentDate: String) { SpacerH(TangemTheme.dimens2.x1) Text( modifier = Modifier diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/EarnBlock.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/EarnBlock.kt index ddb450e65d..d098b959ee 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/EarnBlock.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/EarnBlock.kt @@ -9,17 +9,13 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp -import androidx.compose.ui.util.fastForEach import com.tangem.core.ui.R import com.tangem.core.ui.components.SpacerH import com.tangem.core.ui.components.UnableToLoadData import com.tangem.core.ui.components.block.BlockCard import com.tangem.core.ui.components.block.TangemBlockCardColors import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme -import com.tangem.features.feed.ui.earn.components.EarnItemPlaceholderV1 -import com.tangem.features.feed.ui.earn.components.EarnListItem import com.tangem.features.feed.ui.earn.components.MostlyUsedCard import com.tangem.features.feed.ui.earn.components.MostlyUsedPlaceholder import com.tangem.features.feed.ui.earn.state.EarnListItemUM @@ -29,56 +25,7 @@ import kotlinx.collections.immutable.ImmutableList @Composable internal fun EarnBlock(onSeeAllClick: () -> Unit, earnListUM: EarnListUM, modifier: Modifier = Modifier) { if (earnListUM is EarnListUM.Empty) return - if (LocalRedesignEnabled.current) { - EarnBlockV2(onSeeAllClick = onSeeAllClick, earnListUM = earnListUM, modifier = modifier) - } else { - EarnBlockV1(onSeeAllClick = onSeeAllClick, earnListUM = earnListUM, modifier = modifier) - } -} - -@Composable -private fun EarnBlockV1(onSeeAllClick: () -> Unit, earnListUM: EarnListUM, modifier: Modifier = Modifier) { - Column(modifier = modifier) { - Header( - title = { - Text( - text = stringResourceSafe(R.string.markets_earn_common_title), - style = TangemTheme.typography.h3, - color = TangemTheme.colors.text.primary1, - overflow = TextOverflow.Ellipsis, - maxLines = 1, - ) - }, - onSeeAllClick = onSeeAllClick, - isLoading = earnListUM is EarnListUM.Loading, - shouldShowSeeAll = earnListUM is EarnListUM.Content, - modifier = Modifier.padding(horizontal = 20.dp), - ) - - SpacerH(12.dp) - - BlockCard( - modifier = Modifier.padding(horizontal = 16.dp), - colors = TangemBlockCardColors.copy(containerColor = TangemTheme.colors.background.action), - ) { - AnimatedContent( - targetState = earnListUM, - contentKey = { it::class.java }, - ) { earnListUM -> - when (earnListUM) { - is EarnListUM.Content -> EarnContentBlock(items = earnListUM.items) - is EarnListUM.Error -> EarnErrorBlock(onRetryClick = earnListUM.onRetryClicked) - EarnListUM.Loading -> { - repeat(PLACEHOLDER_ITEM_COUNT) { - EarnItemPlaceholderV1() - } - } - EarnListUM.Empty -> Unit - } - } - } - SpacerH(32.dp) - } + EarnBlockV2(onSeeAllClick = onSeeAllClick, earnListUM = earnListUM, modifier = modifier) } @Composable @@ -143,32 +90,22 @@ private fun EarnErrorBlock(onRetryClick: () -> Unit) { @Composable private fun EarnContentBlock(items: ImmutableList) { - if (LocalRedesignEnabled.current) { - LazyRow( - contentPadding = PaddingValues( - start = 16.dp, - end = 16.dp, - bottom = 8.dp, - ), - horizontalArrangement = Arrangement.spacedBy(8.dp), - ) { - items( - items = items, - key = { item -> item.id }, - ) { item -> - MostlyUsedCard( - item = item, - onClick = item.onItemClick, - ) - } - } - } else { - Column(modifier = Modifier.fillMaxWidth()) { - items.fastForEach { item -> - EarnListItem(item = item) - } + LazyRow( + contentPadding = PaddingValues( + start = 16.dp, + end = 16.dp, + bottom = 8.dp, + ), + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + items( + items = items, + key = { item -> item.id }, + ) { item -> + MostlyUsedCard( + item = item, + onClick = item.onItemClick, + ) } } -} - -private const val PLACEHOLDER_ITEM_COUNT = 5 \ No newline at end of file +} \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/FeedListLoading.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/FeedListLoading.kt index 14ef1324cc..5846617dc5 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/FeedListLoading.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/FeedListLoading.kt @@ -13,9 +13,8 @@ import com.tangem.core.ui.components.RectangleShimmer import com.tangem.core.ui.components.SpacerH import com.tangem.core.ui.components.block.BlockCard import com.tangem.core.ui.components.block.TangemBlockCardColors -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview +import com.tangem.core.ui.res.TangemThemePreviewRedesign import com.tangem.features.feed.ui.feed.components.articles.DefaultLoadingArticle import com.tangem.features.feed.ui.feed.components.articles.TrendingLoadingArticle @@ -36,7 +35,48 @@ internal fun FeedListLoading(modifier: Modifier = Modifier) { @Composable internal fun MarketLoadingBlock() { - if (LocalRedesignEnabled.current) { + RectangleShimmer( + modifier = Modifier + .padding(start = 16.dp, top = 16.dp) + .size(width = 132.dp, height = 24.dp), + radius = TangemTheme.dimens2.x25, + ) + SpacerH(20.dp) + ChartsLoading(modifier = Modifier.padding(horizontal = 16.dp)) + SpacerH(40.dp) +} + +@Composable +internal fun MarketPulseLoadingBlock() { + RectangleShimmer( + modifier = Modifier + .padding(start = 16.dp, top = 16.dp) + .size(width = 132.dp, height = 24.dp), + radius = TangemTheme.dimens2.x25, + ) + SpacerH(15.dp) + LazyRow( + modifier = Modifier.padding(vertical = 4.dp), + verticalAlignment = Alignment.CenterVertically, + contentPadding = PaddingValues(16.dp), + horizontalArrangement = Arrangement.spacedBy(6.dp), + state = rememberLazyListState(), + ) { + items(DEFAULT_CHART_SIZE_IN_MARKET) { + RectangleShimmer( + modifier = Modifier.size(width = 112.dp, height = 36.dp), + radius = TangemTheme.dimens2.x25, + ) + } + } + SpacerH(16.dp) + ChartsLoading(modifier = Modifier.padding(horizontal = 16.dp)) + SpacerH(32.dp) +} + +@Composable +internal fun NewsLoadingBlock() { + Column { RectangleShimmer( modifier = Modifier .padding(start = 16.dp, top = 16.dp) @@ -44,133 +84,28 @@ internal fun MarketLoadingBlock() { radius = TangemTheme.dimens2.x25, ) SpacerH(20.dp) - ChartsLoading(modifier = Modifier.padding(horizontal = 16.dp)) + TrendingLoadingArticle(modifier = Modifier.padding(horizontal = 16.dp)) + SpacerH(12.dp) + LazyRow( + verticalAlignment = Alignment.CenterVertically, + contentPadding = PaddingValues(horizontal = 16.dp), + horizontalArrangement = Arrangement.spacedBy(12.dp), + state = rememberLazyListState(), + ) { + items(DEFAULT_CHART_SIZE_IN_MARKET) { + DefaultLoadingArticle() + } + } SpacerH(40.dp) - } else { - RectangleShimmer( - modifier = Modifier - .padding(start = 16.dp) - .size(width = 104.dp, height = 18.dp), - ) - SpacerH(15.dp) - ChartsLoading(modifier = Modifier.padding(horizontal = 16.dp)) - SpacerH(35.dp) - } -} - -@Composable -internal fun MarketPulseLoadingBlock() { - if (LocalRedesignEnabled.current) { - RectangleShimmer( - modifier = Modifier - .padding(start = 16.dp, top = 16.dp) - .size(width = 132.dp, height = 24.dp), - radius = TangemTheme.dimens2.x25, - ) - SpacerH(15.dp) - LazyRow( - modifier = Modifier.padding(vertical = 4.dp), - verticalAlignment = Alignment.CenterVertically, - contentPadding = PaddingValues(16.dp), - horizontalArrangement = Arrangement.spacedBy(6.dp), - state = rememberLazyListState(), - ) { - items(DEFAULT_CHART_SIZE_IN_MARKET) { - RectangleShimmer( - modifier = Modifier.size(width = 112.dp, height = 36.dp), - radius = TangemTheme.dimens2.x25, - ) - } - } - SpacerH(16.dp) - ChartsLoading(modifier = Modifier.padding(horizontal = 16.dp)) - SpacerH(32.dp) - } else { - RectangleShimmer( - modifier = Modifier - .padding(start = 16.dp) - .size(width = 104.dp, height = 18.dp), - ) - SpacerH(15.dp) - LazyRow( - modifier = Modifier.padding(vertical = 4.dp), - verticalAlignment = Alignment.CenterVertically, - contentPadding = PaddingValues(16.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp), - state = rememberLazyListState(), - ) { - items(DEFAULT_CHART_SIZE_IN_MARKET) { - RectangleShimmer(modifier = Modifier.size(width = 124.dp, height = 36.dp)) - } - } - SpacerH(16.dp) - ChartsLoading(modifier = Modifier.padding(horizontal = 16.dp)) - SpacerH(32.dp) - } -} - -@Composable -internal fun NewsLoadingBlock() { - if (LocalRedesignEnabled.current) { - Column { - RectangleShimmer( - modifier = Modifier - .padding(start = 16.dp, top = 16.dp) - .size(width = 132.dp, height = 24.dp), - radius = TangemTheme.dimens2.x25, - ) - SpacerH(20.dp) - TrendingLoadingArticle(modifier = Modifier.padding(horizontal = 16.dp)) - SpacerH(12.dp) - LazyRow( - verticalAlignment = Alignment.CenterVertically, - contentPadding = PaddingValues(horizontal = 16.dp), - horizontalArrangement = Arrangement.spacedBy(12.dp), - state = rememberLazyListState(), - ) { - items(DEFAULT_CHART_SIZE_IN_MARKET) { - DefaultLoadingArticle() - } - } - SpacerH(40.dp) - } - } else { - Column { - RectangleShimmer( - modifier = Modifier - .padding(start = 16.dp) - .size(width = 104.dp, height = 18.dp), - ) - SpacerH(15.dp) - TrendingLoadingArticle(modifier = Modifier.padding(horizontal = 16.dp)) - SpacerH(12.dp) - LazyRow( - verticalAlignment = Alignment.CenterVertically, - contentPadding = PaddingValues(16.dp), - horizontalArrangement = Arrangement.spacedBy(12.dp), - state = rememberLazyListState(), - ) { - items(DEFAULT_CHART_SIZE_IN_MARKET) { - DefaultLoadingArticle() - } - } - SpacerH(35.dp) - } } } @Composable private fun ChartsLoading(modifier: Modifier = Modifier) { - val isRedesignEnabled = LocalRedesignEnabled.current BlockCard( modifier = modifier, colors = TangemBlockCardColors.copy( - containerColor = if (isRedesignEnabled) { - TangemTheme.colors2.surface.level3 - } else { - TangemTheme.colors.background.action - }, - + containerColor = TangemTheme.colors2.surface.level3, ), ) { Column( @@ -190,7 +125,7 @@ private const val DEFAULT_CHART_SIZE_IN_MARKET = 5 @Preview(showBackground = true) @Composable private fun FeedListLoadingPreview() { - TangemThemePreview { + TangemThemePreviewRedesign { Column { MarketLoadingBlock() NewsLoadingBlock() diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/MarketsBlock.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/MarketsBlock.kt index e4cfd4a92b..409a43816a 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/MarketsBlock.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/MarketsBlock.kt @@ -28,7 +28,6 @@ import com.tangem.core.ui.components.block.BlockCard import com.tangem.core.ui.components.block.TangemBlockCardColors import com.tangem.core.ui.ds.tabs.TangemTab import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.features.feed.model.market.list.state.SortByTypeUM import com.tangem.features.feed.ui.feed.state.FeedListCallbacks @@ -42,7 +41,6 @@ internal fun MarketBlock( onItemClick: (MarketsListItemUM) -> Unit, modifier: Modifier = Modifier, ) { - val isRedesignEnabled = LocalRedesignEnabled.current AnimatedContent( targetState = marketChart, label = "MarketBlockChartAnimation", @@ -58,16 +56,8 @@ internal fun MarketBlock( title = { Text( text = stringResourceSafe(R.string.markets_common_title), - style = if (isRedesignEnabled) { - TangemTheme.typography2.headingSemibold20 - } else { - TangemTheme.typography.h3 - }, - color = if (isRedesignEnabled) { - TangemTheme.colors2.text.neutral.primary - } else { - TangemTheme.colors.text.primary1 - }, + style = TangemTheme.typography2.headingSemibold20, + color = TangemTheme.colors2.text.neutral.primary, overflow = TextOverflow.Ellipsis, maxLines = 1, ) @@ -80,7 +70,7 @@ internal fun MarketBlock( modifier = Modifier.padding(horizontal = MARKET_BLOCK_HEADER_PADDING), ) - SpacerH(if (isRedesignEnabled) 20.dp else 12.dp) + SpacerH(20.dp) Charts( onItemClick = onItemClick, @@ -96,7 +86,6 @@ internal fun MarketBlock( @Suppress("LongMethod") @Composable internal fun ColumnScope.MarketPulseBlock(marketChartConfig: MarketChartConfig, feedListCallbacks: FeedListCallbacks) { - val isRedesignEnabled = LocalRedesignEnabled.current val onSeeAllClick by rememberUpdatedState { feedListCallbacks.onMarketOpenClick(marketChartConfig.currentSortByType) } @@ -105,16 +94,8 @@ internal fun ColumnScope.MarketPulseBlock(marketChartConfig: MarketChartConfig, title = { Text( text = stringResourceSafe(R.string.markets_pulse_common_title), - style = if (isRedesignEnabled) { - TangemTheme.typography2.headingSemibold20 - } else { - TangemTheme.typography.h3 - }, - color = if (isRedesignEnabled) { - TangemTheme.colors2.text.neutral.primary - } else { - TangemTheme.colors.text.primary1 - }, + style = TangemTheme.typography2.headingSemibold20, + color = TangemTheme.colors2.text.neutral.primary, overflow = TextOverflow.Ellipsis, maxLines = 1, ) @@ -128,11 +109,7 @@ internal fun ColumnScope.MarketPulseBlock(marketChartConfig: MarketChartConfig, LazyRow( modifier = Modifier.padding(vertical = 4.dp), verticalAlignment = Alignment.CenterVertically, - contentPadding = if (isRedesignEnabled) { - PaddingValues(horizontal = 16.dp, vertical = 6.dp) - } else { - PaddingValues(16.dp) - }, + contentPadding = PaddingValues(horizontal = 16.dp, vertical = 6.dp), horizontalArrangement = Arrangement.spacedBy(8.dp), state = rememberLazyListState(), ) { @@ -140,19 +117,11 @@ internal fun ColumnScope.MarketPulseBlock(marketChartConfig: MarketChartConfig, items = marketChartConfig.getFilterPreset(), key = SortByTypeUM::name, ) { sortByTypeUM -> - if (isRedesignEnabled) { - TangemTab( - text = sortByTypeUM.text, - isChecked = sortByTypeUM == marketChartConfig.currentSortByType, - onCheckedChange = { feedListCallbacks.onSortTypeClick(sortByTypeUM) }, - ) - } else { - ChartsFilterChip( - sortByTypeUM = sortByTypeUM, - isSelected = sortByTypeUM == marketChartConfig.currentSortByType, - onClick = { feedListCallbacks.onSortTypeClick(sortByTypeUM) }, - ) - } + TangemTab( + text = sortByTypeUM.text, + isChecked = sortByTypeUM == marketChartConfig.currentSortByType, + onCheckedChange = { feedListCallbacks.onSortTypeClick(sortByTypeUM) }, + ) } } @@ -179,21 +148,12 @@ private fun Charts( onItemClick: (MarketsListItemUM) -> Unit, modifier: Modifier = Modifier, ) { - val isRedesignEnabled = LocalRedesignEnabled.current BlockCard( modifier = modifier, colors = TangemBlockCardColors.copy( - containerColor = if (isRedesignEnabled) { - TangemTheme.colors2.surface.level3 - } else { - TangemTheme.colors.background.action - }, + containerColor = TangemTheme.colors2.surface.level3, ), - shape = if (isRedesignEnabled) { - RoundedCornerShape(TangemTheme.dimens2.x6) - } else { - TangemTheme.shapes.roundedCornersXMedium - }, + shape = RoundedCornerShape(TangemTheme.dimens2.x6), ) { Column(modifier = Modifier.fillMaxWidth()) { when (marketChart) { diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/NewsBlock.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/NewsBlock.kt index 8fc948caa6..3072f8a698 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/NewsBlock.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/NewsBlock.kt @@ -1,12 +1,10 @@ package com.tangem.features.feed.ui.feed.components import androidx.compose.animation.AnimatedContent -import androidx.compose.foundation.Image import androidx.compose.foundation.layout.* import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Brush @@ -26,7 +24,6 @@ import com.tangem.core.ui.components.UnableToLoadData import com.tangem.core.ui.components.block.BlockCard import com.tangem.core.ui.components.block.TangemBlockCardColors import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.features.feed.ui.feed.components.articles.ArticleCard import com.tangem.features.feed.ui.feed.components.articles.ArticleConfigUM @@ -38,9 +35,6 @@ private const val GRADIENT_END = 0.5f private const val LINEAR_GRADIENT_FIRST_PART_V2 = 0xFF7B78FF private const val LINEAR_GRADIENT_SECOND_PART_V2 = 0xFFC56BCD -private const val LINEAR_GRADIENT_FIRST_PART_V1 = 0xFF635EEC -private const val LINEAR_GRADIENT_SECOND_PART_V1 = 0xFFE05AED - private const val MAGIC_ICON_COLOR = 0xFF7D78FF @Composable @@ -65,22 +59,8 @@ internal fun NewsBlock(feedListCallbacks: FeedListCallbacks, news: NewsUM, trend @Suppress("LongMethod") @Composable private fun NewsContentBlock(feedListCallbacks: FeedListCallbacks, news: NewsUM, trendingArticle: ArticleConfigUM?) { - val isRedesignEnabled = LocalRedesignEnabled.current - val gradientStart = remember(isRedesignEnabled) { - if (isRedesignEnabled) { - Color(LINEAR_GRADIENT_FIRST_PART_V2) - } else { - Color(LINEAR_GRADIENT_FIRST_PART_V1) - } - } - - val gradientEnd = remember(isRedesignEnabled) { - if (isRedesignEnabled) { - Color(LINEAR_GRADIENT_SECOND_PART_V2) - } else { - Color(LINEAR_GRADIENT_SECOND_PART_V1) - } - } + val gradientStart = Color(LINEAR_GRADIENT_FIRST_PART_V2) + val gradientEnd = Color(LINEAR_GRADIENT_SECOND_PART_V2) Column { Header( @@ -88,33 +68,18 @@ private fun NewsContentBlock(feedListCallbacks: FeedListCallbacks, news: NewsUM, Row(verticalAlignment = Alignment.CenterVertically) { Text( text = stringResourceSafe(R.string.common_news), - style = if (isRedesignEnabled) { - TangemTheme.typography2.headingSemibold20 - } else { - TangemTheme.typography.h3 - }, - color = if (isRedesignEnabled) { - TangemTheme.colors2.text.neutral.primary - } else { - TangemTheme.colors.text.primary1 - }, + style = TangemTheme.typography2.headingSemibold20, + color = TangemTheme.colors2.text.neutral.primary, ) SpacerW(4.dp) - if (isRedesignEnabled) { - Icon( - modifier = Modifier.size(TangemTheme.dimens2.x6), - tint = Color(MAGIC_ICON_COLOR), - imageVector = ImageVector.vectorResource(R.drawable.ic_magic_28), - contentDescription = null, - ) - } else { - Image( - imageVector = ImageVector.vectorResource(R.drawable.ic_stars_20), - contentDescription = null, - ) - } + Icon( + modifier = Modifier.size(TangemTheme.dimens2.x6), + tint = Color(MAGIC_ICON_COLOR), + imageVector = ImageVector.vectorResource(R.drawable.ic_magic_28), + contentDescription = null, + ) SpacerW(2.dp) @@ -131,11 +96,7 @@ private fun NewsContentBlock(feedListCallbacks: FeedListCallbacks, news: NewsUM, append(stringResourceSafe(R.string.feed_tangem_ai)) } }, - style = if (isRedesignEnabled) { - TangemTheme.typography2.bodyRegular16.copy(fontWeight = FontWeight.Medium) - } else { - TangemTheme.typography.subtitle1 - }, + style = TangemTheme.typography2.bodyRegular16.copy(fontWeight = FontWeight.Medium), overflow = TextOverflow.Ellipsis, maxLines = 1, ) @@ -156,7 +117,6 @@ private fun NewsContentBlock(feedListCallbacks: FeedListCallbacks, news: NewsUM, .padding(horizontal = 16.dp), articleConfigUM = trendingArticle, onArticleClick = { feedListCallbacks.onArticleClick(trendingArticle.id) }, - colors = TangemBlockCardColors.copy(containerColor = TangemTheme.colors.background.action), ) SpacerH(12.dp) } diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/NewsSlider.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/NewsSlider.kt index 866a07785d..19e152a194 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/NewsSlider.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/NewsSlider.kt @@ -10,9 +10,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.layout.onFirstVisible import androidx.compose.ui.unit.dp -import com.tangem.core.ui.components.block.TangemBlockCardColors import com.tangem.core.ui.res.LocalMainBottomSheetColor -import com.tangem.core.ui.res.TangemTheme import com.tangem.features.feed.ui.feed.components.articles.ArticleCard import com.tangem.features.feed.ui.feed.components.articles.ShowMoreArticlesCard import com.tangem.features.feed.ui.feed.state.NewsSliderConfig @@ -48,7 +46,6 @@ internal fun NewsSlider(newsSliderConfig: NewsSliderConfig) { .width(280.dp) .heightIn(min = 172.dp) .fillMaxHeight(), - colors = TangemBlockCardColors.copy(containerColor = TangemTheme.colors.background.action), ) } diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleCard.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleCard.kt index 48d21b699b..c8517bb853 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleCard.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleCard.kt @@ -1,30 +1,13 @@ package com.tangem.features.feed.ui.feed.components.articles -import androidx.compose.material3.CardColors import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import com.tangem.core.ui.components.block.TangemBlockCardColors -import com.tangem.core.ui.res.LocalRedesignEnabled @Composable -fun ArticleCard( - articleConfigUM: ArticleConfigUM, - onArticleClick: () -> Unit, - modifier: Modifier = Modifier, - colors: CardColors = TangemBlockCardColors, -) { - if (LocalRedesignEnabled.current) { - ArticleCardV2( - articleConfigUM = articleConfigUM, - onArticleClick = onArticleClick, - modifier = modifier, - ) - } else { - ArticleCardV1( - articleConfigUM = articleConfigUM, - onArticleClick = onArticleClick, - modifier = modifier, - colors = colors, - ) - } +fun ArticleCard(articleConfigUM: ArticleConfigUM, onArticleClick: () -> Unit, modifier: Modifier = Modifier) { + ArticleCardV2( + articleConfigUM = articleConfigUM, + onArticleClick = onArticleClick, + modifier = modifier, + ) } \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleCardV1.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleCardV1.kt deleted file mode 100644 index 97ede1fbdf..0000000000 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleCardV1.kt +++ /dev/null @@ -1,273 +0,0 @@ -package com.tangem.features.feed.ui.feed.components.articles - -import android.content.res.Configuration -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.CardColors -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.vectorResource -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview -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.SpacerHMax -import com.tangem.core.ui.components.block.BlockCard -import com.tangem.core.ui.components.block.TangemBlockCardColors -import com.tangem.core.ui.components.label.entity.LabelUM -import com.tangem.core.ui.extensions.TextReference -import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import kotlinx.collections.immutable.persistentListOf -import kotlinx.collections.immutable.toImmutableList -import kotlinx.collections.immutable.toImmutableSet - -@Composable -internal fun ArticleCardV1( - articleConfigUM: ArticleConfigUM, - onArticleClick: () -> Unit, - modifier: Modifier = Modifier, - colors: CardColors = TangemBlockCardColors, -) { - if (articleConfigUM.isTrending) { - TrendingArticle( - articleConfigUM = articleConfigUM, - modifier = modifier, - onArticleClick = onArticleClick, - colors = colors, - ) - } else { - DefaultArticle( - articleConfigUM = articleConfigUM, - modifier = modifier, - onArticleClick = onArticleClick, - colors = colors, - ) - } -} - -@Composable -private fun TrendingArticle( - articleConfigUM: ArticleConfigUM, - onArticleClick: () -> Unit, - colors: CardColors, - modifier: Modifier = Modifier, -) { - Box( - modifier = modifier - .clip(TangemTheme.shapes.roundedCornersXMedium) - .background(colors.containerColor) - .clickable { onArticleClick() }, - ) { - Image( - modifier = Modifier.matchParentSize(), - painter = painterResource(R.drawable.bg_trending_article), - contentDescription = null, - contentScale = ContentScale.FillWidth, - ) - Column( - modifier = Modifier.padding(vertical = 24.dp, horizontal = 16.dp), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Text( - modifier = Modifier - .background( - color = TangemTheme.colors.icon.accent.copy(alpha = 0.1f), - shape = RoundedCornerShape(8.dp), - ) - .padding(horizontal = 8.dp, vertical = 4.dp), - text = stringResourceSafe(R.string.feed_trending_now), - style = TangemTheme.typography.caption1, - color = TangemTheme.colors.icon.accent, - ) - - SpacerH(12.dp) - - Text( - text = articleConfigUM.title, - color = if (articleConfigUM.isViewed) { - TangemTheme.colors.text.tertiary - } else { - TangemTheme.colors.text.primary1 - }, - style = TangemTheme.typography.h3, - textAlign = TextAlign.Center, - ) - - SpacerH(8.dp) - - ArticleInfo( - score = articleConfigUM.score, - createdAt = articleConfigUM.createdAt.resolveReference(), - ) - - SpacerH(32.dp) - - Tags( - modifier = Modifier.padding(horizontal = 46.dp), - tags = articleConfigUM.tags.toImmutableList(), - ) - } - } -} - -@Composable -internal fun ShowMoreArticlesCardV1(modifier: Modifier = Modifier, onClick: () -> Unit) { - BlockCard( - modifier = modifier, - onClick = onClick, - colors = TangemBlockCardColors.copy(containerColor = TangemTheme.colors.background.action), - ) { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier - .fillMaxSize() - .padding(vertical = 31.dp, horizontal = 12.dp), - ) { - Image( - imageVector = ImageVector.vectorResource(R.drawable.ic_show_more_news_48), - contentDescription = stringResourceSafe(R.string.common_show_more), - ) - - SpacerH(16.dp) - - Text( - text = stringResourceSafe(R.string.news_all_news), - style = TangemTheme.typography.subtitle1, - color = TangemTheme.colors.text.primary1, - ) - - Text( - text = stringResourceSafe(R.string.news_stay_in_the_loop), - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.tertiary, - ) - } - } -} - -@Composable -private fun DefaultArticle( - articleConfigUM: ArticleConfigUM, - onArticleClick: () -> Unit, - colors: CardColors, - modifier: Modifier = Modifier, -) { - Column( - modifier = modifier - .clip(TangemTheme.shapes.roundedCornersXMedium) - .background(colors.containerColor) - .clickable { onArticleClick() } - .padding(12.dp), - ) { - ArticleInfo( - score = articleConfigUM.score, - createdAt = articleConfigUM.createdAt.resolveReference(), - ) - - SpacerH(8.dp) - - Text( - text = articleConfigUM.title, - color = if (articleConfigUM.isViewed) { - TangemTheme.colors.text.tertiary - } else { - TangemTheme.colors.text.primary1 - }, - style = TangemTheme.typography.subtitle1, - maxLines = 3, - overflow = TextOverflow.Ellipsis, - ) - - SpacerH(16.dp) - - SpacerHMax() - - Tags(tags = articleConfigUM.tags.toImmutableList()) - } -} - -@Preview(showBackground = true, widthDp = 360) -@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun TagsPreview() { - TangemThemePreview { - Tags( - tags = persistentListOf( - LabelUM(TextReference.Str("Hype")), - LabelUM(TextReference.Str("BTC")), - LabelUM(TextReference.Str("Supply")), - LabelUM(TextReference.Str("Demand")), - LabelUM(TextReference.Str("Best rate")), - LabelUM(TextReference.Str("Breaking news")), - ), - ) - } -} - -@Preview(showBackground = true, widthDp = 360, backgroundColor = 0xFF000000) -@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun ArticleCardsPreview() { - val tags = listOf( - LabelUM(TextReference.Str("Hype")), - LabelUM(TextReference.Str("BTC")), - LabelUM(TextReference.Str("Supply")), - LabelUM(TextReference.Str("Demand")), - LabelUM(TextReference.Str("Breaking news")), - ).toImmutableSet() - - val config = ArticleConfigUM( - id = 1, - title = "Bitcoin ETFs log 4th straight day of inflows (+\$550M)", - score = 9.5f, - createdAt = TextReference.Str("1h ago"), - isTrending = true, - tags = tags, - isViewed = false, - ) - - TangemThemePreview { - Column(modifier = Modifier.verticalScroll(rememberScrollState())) { - ArticleCard( - articleConfigUM = config, - onArticleClick = {}, - ) - - SpacerH(20.dp) - - ArticleCard( - articleConfigUM = config.copy(isViewed = true), - onArticleClick = {}, - ) - - SpacerH(20.dp) - - ArticleCard( - articleConfigUM = config.copy(isTrending = false), - onArticleClick = {}, - ) - - SpacerH(20.dp) - - ArticleCard( - articleConfigUM = config.copy(isTrending = false, isViewed = true), - onArticleClick = {}, - ) - } - } -} \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleHeader.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleHeader.kt index 530d0a1dc5..f5baaf743a 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleHeader.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleHeader.kt @@ -11,14 +11,11 @@ import androidx.compose.ui.res.vectorResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.tangem.core.ui.R -import com.tangem.core.ui.components.label.Label import com.tangem.core.ui.components.label.entity.LabelLeadingContentUM import com.tangem.core.ui.components.label.entity.LabelUM import com.tangem.core.ui.ds.badge.* import com.tangem.core.ui.ds.image.TangemIconUM -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.res.TangemThemePreviewRedesign import com.tangem.utils.StringsSigns import kotlinx.collections.immutable.ImmutableList @@ -34,63 +31,14 @@ fun ArticleHeader( tags: ImmutableList, modifier: Modifier = Modifier, ) { - if (LocalRedesignEnabled.current) { - ArticleHeaderV2( - isTrending = isTrending, - title = title, - createdAt = createdAt, - score = score, - tags = tags, - modifier = modifier, - ) - } else { - ArticleHeaderV1( - title = title, - createdAt = createdAt, - score = score, - tags = tags, - modifier = modifier, - ) - } -} - -@OptIn(ExperimentalLayoutApi::class) -@Composable -private fun ArticleHeaderV1( - title: String, - createdAt: String, - score: Float, - tags: ImmutableList, - modifier: Modifier = Modifier, -) { - Column(modifier = modifier) { - ArticleInfo( - score = score, - createdAt = createdAt, - ) - - Spacer(modifier = Modifier.height(12.dp)) - - Text( - text = title, - style = TangemTheme.typography.h2, - color = TangemTheme.colors.text.primary1, - ) - - if (tags.isNotEmpty()) { - Spacer(modifier = Modifier.height(20.dp)) - FlowRow( - horizontalArrangement = Arrangement.spacedBy(4.dp), - verticalArrangement = Arrangement.spacedBy(4.dp), - ) { - tags.forEach { tag -> - Label( - state = tag, - ) - } - } - } - } + ArticleHeaderV2( + isTrending = isTrending, + title = title, + createdAt = createdAt, + score = score, + tags = tags, + modifier = modifier, + ) } @Composable @@ -220,21 +168,7 @@ private fun labelLeadingBadgeIconPosition(content: LabelLeadingContentUM): Tange @Preview(showBackground = true, widthDp = 360) @Composable -private fun ArticleHeaderPreviewV1() { - TangemThemePreview { - ArticleHeader( - title = "Something going good!", - createdAt = "1 hour ago", - score = 5.5f, - tags = persistentListOf(), - isTrending = true, - ) - } -} - -@Preview(showBackground = true, widthDp = 360) -@Composable -private fun ArticleHeaderPreviewV2() { +private fun ArticleHeaderPreview() { TangemThemePreviewRedesign { ArticleHeader( title = "Something going good!", diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleInfo.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleInfo.kt deleted file mode 100644 index 656b128605..0000000000 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleInfo.kt +++ /dev/null @@ -1,61 +0,0 @@ -package com.tangem.features.feed.ui.feed.components.articles - -import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.size -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.drawWithCache -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.vectorResource -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import com.tangem.core.ui.R -import com.tangem.core.ui.res.TangemTheme - -@Composable -internal fun ArticleInfo(score: Float, createdAt: String, modifier: Modifier = Modifier) { - val dotColor = TangemTheme.colors.text.secondary - Row( - modifier = modifier, - horizontalArrangement = Arrangement.spacedBy(4.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - Image( - imageVector = ImageVector.vectorResource(R.drawable.ic_start_circle_12), - contentDescription = null, - ) - - Text( - text = score.toString(), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.secondary, - ) - - Spacer( - modifier = Modifier - .size(4.dp) - .drawWithCache { - val radius = size.minDimension / 2f - onDrawBehind { - drawCircle( - color = dotColor, - radius = radius, - ) - } - }, - ) - - Text( - text = createdAt, - style = TangemTheme.typography.subtitle2, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - color = TangemTheme.colors.text.secondary, - ) - } -} \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleLoadingCard.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleLoadingCard.kt index 74fbda7a34..c80849be73 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleLoadingCard.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ArticleLoadingCard.kt @@ -11,47 +11,12 @@ import com.tangem.core.ui.components.RectangleShimmer import com.tangem.core.ui.components.SpacerH import com.tangem.core.ui.components.block.BlockCard import com.tangem.core.ui.components.block.TangemBlockCardColors -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.res.TangemThemePreviewRedesign @Composable fun TrendingLoadingArticle(modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - TrendingLoadingArticleV2(modifier) - } else { - TrendingLoadingArticleV1(modifier) - } -} - -@Composable -private fun TrendingLoadingArticleV1(modifier: Modifier = Modifier) { - BlockCard( - modifier = modifier, - colors = TangemBlockCardColors.copy(containerColor = TangemTheme.colors.background.action), - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 24.dp, horizontal = 16.dp), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - RectangleShimmer(modifier = Modifier.size(width = 96.dp, height = 24.dp), radius = 8.dp) - SpacerH(12.dp) - RectangleShimmer(modifier = Modifier.size(width = 285.dp, height = 18.dp), radius = 4.dp) - SpacerH(6.dp) - RectangleShimmer(modifier = Modifier.size(width = 190.dp, height = 18.dp), radius = 4.dp) - SpacerH(14.dp) - RectangleShimmer(modifier = Modifier.size(width = 110.dp, height = 18.dp), radius = 4.dp) - SpacerH(32.dp) - Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(4.dp)) { - RectangleShimmer(modifier = Modifier.size(width = 64.dp, height = 24.dp), radius = 8.dp) - RectangleShimmer(modifier = Modifier.size(width = 64.dp, height = 24.dp), radius = 8.dp) - RectangleShimmer(modifier = Modifier.size(width = 64.dp, height = 24.dp), radius = 8.dp) - } - } - } + TrendingLoadingArticleV2(modifier) } @Composable @@ -96,51 +61,7 @@ private fun TrendingLoadingArticleV2(modifier: Modifier = Modifier) { @Composable fun DefaultLoadingArticle(modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - DefaultLoadingArticleV2(modifier) - } else { - DefaultLoadingArticleV1(modifier) - } -} - -@Composable -private fun DefaultLoadingArticleV1(modifier: Modifier = Modifier) { - BlockCard( - modifier = modifier, - colors = TangemBlockCardColors.copy(containerColor = TangemTheme.colors.background.action), - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(16.dp), - ) { - RectangleShimmer(modifier = Modifier.size(width = 46.dp, height = 16.dp), radius = TangemTheme.dimens2.x25) - SpacerH(8.dp) - RectangleShimmer( - modifier = Modifier - .fillMaxWidth() - .height(20.dp), - radius = TangemTheme.dimens2.x25, - ) - SpacerH(28.dp) - RectangleShimmer(modifier = Modifier.size(width = 46.dp, height = 16.dp), radius = TangemTheme.dimens2.x25) - SpacerH(8.dp) - Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(4.dp)) { - RectangleShimmer( - modifier = Modifier.size(width = 72.dp, height = 24.dp), - radius = TangemTheme.dimens2.x25, - ) - RectangleShimmer( - modifier = Modifier.size(width = 62.dp, height = 24.dp), - radius = TangemTheme.dimens2.x25, - ) - RectangleShimmer( - modifier = Modifier.size(width = 32.dp, height = 24.dp), - radius = TangemTheme.dimens2.x25, - ) - } - } - } + DefaultLoadingArticleV2(modifier) } @Composable @@ -186,16 +107,7 @@ private fun DefaultLoadingArticleV2(modifier: Modifier = Modifier) { @Preview(showBackground = true, widthDp = 360) @Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable -private fun TrendingLoadingArticlePreviewV1() { - TangemThemePreview { - TrendingLoadingArticle() - } -} - -@Preview(showBackground = true, widthDp = 360) -@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun TrendingLoadingArticlePreviewV2() { +private fun TrendingLoadingArticlePreview() { TangemThemePreviewRedesign { TrendingLoadingArticle() } @@ -204,16 +116,7 @@ private fun TrendingLoadingArticlePreviewV2() { @Preview(showBackground = true, widthDp = 360) @Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable -private fun DefaultLoadingArticlePreviewV1() { - TangemThemePreview { - DefaultLoadingArticle() - } -} - -@Preview(showBackground = true, widthDp = 360) -@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun DefaultLoadingArticlePreviewV2() { +private fun DefaultLoadingArticlePreview() { TangemThemePreviewRedesign { DefaultLoadingArticle() } diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ShowMoreArticlesCard.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ShowMoreArticlesCard.kt index fba589144d..520ef6efbf 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ShowMoreArticlesCard.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/ShowMoreArticlesCard.kt @@ -2,14 +2,8 @@ package com.tangem.features.feed.ui.feed.components.articles import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import com.tangem.core.ui.res.LocalRedesignEnabled @Composable fun ShowMoreArticlesCard(modifier: Modifier = Modifier, onClick: () -> Unit) { - val isRedesignEnabled: Boolean = LocalRedesignEnabled.current - if (isRedesignEnabled) { - ShowMoreArticlesCardV2(modifier = modifier, onClick = onClick) - } else { - ShowMoreArticlesCardV1(modifier = modifier, onClick = onClick) - } + ShowMoreArticlesCardV2(modifier = modifier, onClick = onClick) } \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/Tags.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/Tags.kt index 2554569a61..a9b4f19ee8 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/Tags.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/feed/components/articles/Tags.kt @@ -8,13 +8,11 @@ import androidx.compose.ui.layout.SubcomposeMeasureScope import androidx.compose.ui.unit.Constraints import androidx.compose.ui.unit.dp import com.tangem.core.ui.R -import com.tangem.core.ui.components.label.Label import com.tangem.core.ui.components.label.entity.LabelLeadingContentUM import com.tangem.core.ui.components.label.entity.LabelUM import com.tangem.core.ui.ds.badge.* import com.tangem.core.ui.ds.image.TangemIconUM import com.tangem.core.ui.extensions.TextReference -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.utils.StringsSigns import kotlinx.collections.immutable.ImmutableList @@ -36,28 +34,24 @@ internal fun Tags(tags: ImmutableList, modifier: Modifier = Modifier) { val tagPlaceables = subcompose(ContentSlot.Tags) { tags.forEach { tag -> - if (LocalRedesignEnabled.current) { - TangemBadge( - text = tag.text, - tangemIconUM = when (val content = tag.leadingContent) { - LabelLeadingContentUM.None -> null - is LabelLeadingContentUM.Token -> TangemIconUM.Url( - url = content.iconUrl, - fallbackRes = R.drawable.ic_alert_24, - ) - }, - shape = TangemBadgeShape.Rounded, - size = TangemBadgeSize.X6, - type = TangemBadgeType.Tinted, - color = TangemBadgeColor.Gray, - iconPosition = when (tag.leadingContent) { - LabelLeadingContentUM.None -> TangemBadgeIconPosition.None - is LabelLeadingContentUM.Token -> TangemBadgeIconPosition.Start - }, - ) - } else { - Label(state = tag) - } + TangemBadge( + text = tag.text, + tangemIconUM = when (val content = tag.leadingContent) { + LabelLeadingContentUM.None -> null + is LabelLeadingContentUM.Token -> TangemIconUM.Url( + url = content.iconUrl, + fallbackRes = R.drawable.ic_alert_24, + ) + }, + shape = TangemBadgeShape.Rounded, + size = TangemBadgeSize.X6, + type = TangemBadgeType.Tinted, + color = TangemBadgeColor.Gray, + iconPosition = when (tag.leadingContent) { + LabelLeadingContentUM.None -> TangemBadgeIconPosition.None + is LabelLeadingContentUM.Token -> TangemBadgeIconPosition.Start + }, + ) } }.map { it.measure(constraints) } @@ -134,22 +128,13 @@ private fun SubcomposeMeasureScope.calculateLayoutInfo( @Composable private fun OverflowLabel(count: Int) { - if (LocalRedesignEnabled.current) { - TangemBadge( - text = TextReference.Str("${StringsSigns.PLUS}$count"), - shape = TangemBadgeShape.Rounded, - size = TangemBadgeSize.X6, - type = TangemBadgeType.Tinted, - color = TangemBadgeColor.Gray, - ) - } else { - Label( - state = LabelUM( - text = TextReference.Str("${StringsSigns.PLUS}$count"), - maxLines = 1, - ), - ) - } + TangemBadge( + text = TextReference.Str("${StringsSigns.PLUS}$count"), + shape = TangemBadgeShape.Rounded, + size = TangemBadgeSize.X6, + type = TangemBadgeType.Tinted, + color = TangemBadgeColor.Gray, + ) } private fun calculateRowWidth(placeables: List, spacingPx: Int): Int { diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/MarketsTokenDetailsContent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/MarketsTokenDetailsContent.kt index a041bf92a2..e99c67671c 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/MarketsTokenDetailsContent.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/MarketsTokenDetailsContent.kt @@ -24,9 +24,6 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.unit.dp import com.tangem.core.ui.components.* -import com.tangem.core.ui.components.appbar.TangemTopAppBar -import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM -import com.tangem.core.ui.components.buttons.segmentedbutton.SegmentedButtons import com.tangem.core.ui.components.currency.icon.CoinIcon import com.tangem.core.ui.components.marketprice.PriceChangeInPercent import com.tangem.core.ui.components.marketprice.PriceChangeType @@ -38,7 +35,6 @@ 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.resourceReference -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.test.MarketsTestTags @@ -50,10 +46,8 @@ import com.tangem.features.feed.ui.market.detailed.state.ExchangesBottomSheetCon import com.tangem.features.feed.ui.market.detailed.state.InfoBottomSheetContent import com.tangem.features.feed.ui.market.detailed.state.MarketsTokenDetailsUM import com.tangem.features.feed.ui.market.detailed.state.SecurityScoreBottomSheetContent -import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.flow.distinctUntilChanged -import com.tangem.core.ui.R as CoreR @Suppress("LongParameterList") @Composable @@ -62,7 +56,6 @@ internal fun MarketsTokenDetailsContent( state: MarketsTokenDetailsUM, backgroundColor: Color, modifier: Modifier = Modifier, - portfolioBlock: @Composable ((Modifier) -> Unit)?, portfolioFloatingBlock: @Composable ((Modifier) -> Unit)?, marketingBanner: @Composable (Modifier) -> Unit, ) { @@ -71,7 +64,6 @@ internal fun MarketsTokenDetailsContent( modifier = modifier, backgroundColor = backgroundColor, state = state, - portfolioBlock = portfolioBlock, portfolioFloatingBlock = portfolioFloatingBlock, marketingBanner = marketingBanner, ) @@ -90,11 +82,9 @@ private fun Content( state: MarketsTokenDetailsUM, backgroundColor: Color, modifier: Modifier = Modifier, - portfolioBlock: @Composable ((Modifier) -> Unit)?, portfolioFloatingBlock: @Composable ((Modifier) -> Unit)?, marketingBanner: @Composable (Modifier) -> Unit, ) { - val isRedesignEnabled = LocalRedesignEnabled.current val density = LocalDensity.current val bottomBarHeight = with(density) { WindowInsets.systemBars.getBottom(this).toDp() } val lazyListState = rememberLazyListState() @@ -128,20 +118,19 @@ private fun Content( Header(state = state) } item { - if (isRedesignEnabled) SpacerH(TangemTheme.dimens2.x3) else SpacerH16() + SpacerH(TangemTheme.dimens2.x3) } item("intervalSelector") { IntervalSelector( trendInterval = state.selectedInterval, onIntervalClick = state.onSelectedIntervalChange, - isEnabled = state.body !is MarketsTokenDetailsUM.Body.Nothing, modifier = Modifier .padding(horizontal = TangemTheme.dimens.spacing16) .fillMaxWidth(), ) } item { - if (isRedesignEnabled) SpacerH(TangemTheme.dimens2.x3) else SpacerH32() + SpacerH(TangemTheme.dimens2.x3) } item("chart") { MarketTokenDetailsChart( @@ -153,9 +142,7 @@ private fun Content( item { SpacerH16() } tokenMarketDetailsBody( state = state.body, - portfolioBlock = portfolioBlock, relatedNews = state.relatedNews, - isRedesignEnabled = isRedesignEnabled, marketingBanner = marketingBanner, ) item { SpacerH(bottomSpacing) } @@ -176,86 +163,14 @@ private fun Content( } } -@Suppress("LongParameterList") -@Composable -internal fun MarketsTokenDetailsTopBar( - backgroundColor: Color, - shouldShowPriceSubtitle: Boolean, - tokenName: String, - tokenPrice: String, - isBackButtonEnabled: Boolean, - onBackClick: () -> Unit, - onShareClick: () -> Unit, -) { - TangemTopAppBar( - modifier = Modifier.drawBehind { drawRect(backgroundColor) }, - title = tokenName, - subtitle = if (shouldShowPriceSubtitle) tokenPrice else null, - startButton = TopAppBarButtonUM.Back( - onBackClicked = onBackClick, - enabled = isBackButtonEnabled, - ), - endButton = TopAppBarButtonUM.Icon( - iconRes = CoreR.drawable.ic_share_24, - onClicked = onShareClick, - ), - ) -} - @Composable private fun Header(state: MarketsTokenDetailsUM) { - if (LocalRedesignEnabled.current) { - HeaderV2( - modifier = Modifier - .padding(TangemTheme.dimens2.x4) - .fillMaxWidth(), - state = state, - ) - } else { - HeaderV1( - modifier = Modifier - .padding(horizontal = TangemTheme.dimens.spacing16) - .fillMaxWidth(), - state = state, - ) - } -} - -@Composable -private fun HeaderV1(state: MarketsTokenDetailsUM, modifier: Modifier = Modifier) { - Row( - modifier = modifier, - horizontalArrangement = Arrangement.SpaceBetween, - ) { - Column(modifier = Modifier.weight(1f)) { - TokenPriceTextV1( - price = state.priceText, - triggerPriceChange = state.triggerPriceChange, - ) - Row(horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing4)) { - Text( - text = state.dateTimeText.resolveReference(), - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.tertiary, - ) - if (state.priceChangePercentText != null) { - PriceChangeInPercent( - valueInPercent = state.priceChangePercentText, - type = state.priceChangeType, - textStyle = TangemTheme.typography.caption2, - ) - } - } - } - SpacerW4() - CoinIcon( - modifier = Modifier.requiredSize(TangemTheme.dimens.size48), - url = state.iconUrl, - alpha = 1f, - colorFilter = null, - fallbackResId = R.drawable.ic_custom_token_44, - ) - } + HeaderV2( + modifier = Modifier + .padding(TangemTheme.dimens2.x4) + .fillMaxWidth(), + state = state, + ) } @Composable @@ -324,40 +239,6 @@ private fun HeaderV2(state: MarketsTokenDetailsUM, modifier: Modifier = Modifier } } -@Composable -private fun TokenPriceTextV1( - price: String, - triggerPriceChange: StateEvent, - modifier: Modifier = Modifier, -) { - val growColor = TangemTheme.colors.text.accent - val fallColor = TangemTheme.colors.text.warning - val generalColor = TangemTheme.colors.text.primary1 - - val color = remember(generalColor) { Animatable(generalColor) } - - EventEffect(triggerPriceChange) { priceChangeType -> - val nextColor = when (priceChangeType) { - PriceChangeType.UP, - -> growColor - PriceChangeType.DOWN -> fallColor - PriceChangeType.NEUTRAL -> return@EventEffect - } - - color.animateTo(nextColor, snap()) - color.animateTo(generalColor, tween(durationMillis = 500)) - } - - Text( - text = price, - modifier = modifier, - color = color.value, - autoSize = TextAutoSize.StepBased(maxFontSize = TangemTheme.typography.head.fontSize), - maxLines = 1, - style = TangemTheme.typography.head, - ) -} - @Composable private fun TokenPriceTextV2( priceAnnotated: TextReference, @@ -395,66 +276,24 @@ private fun TokenPriceTextV2( @Composable private fun IntervalSelector( trendInterval: PriceChangeInterval, - isEnabled: Boolean, onIntervalClick: (PriceChangeInterval) -> Unit, modifier: Modifier = Modifier, ) { - if (LocalRedesignEnabled.current) { - val items = remember { - PriceChangeInterval.entries - .map { TangemSegmentUM(it.toString(), it.getText()) }.toImmutableList() - } - val selectedItem = remember(trendInterval) { - items.firstOrNull { it.id == trendInterval.toString() } - } - - TangemSegmentedPicker( - items = items, - initialSelectedItem = selectedItem, - isFixed = true, - modifier = modifier, - onClick = { onIntervalClick(PriceChangeInterval.valueOf(it.id)) }, - ) - - return + val items = remember { + PriceChangeInterval.entries + .map { TangemSegmentUM(it.toString(), it.getText()) }.toImmutableList() + } + val selectedItem = remember(trendInterval) { + items.firstOrNull { it.id == trendInterval.toString() } } - SegmentedButtons( - config = persistentListOf( - PriceChangeInterval.H24, - PriceChangeInterval.WEEK, - PriceChangeInterval.MONTH, - PriceChangeInterval.MONTH3, - PriceChangeInterval.MONTH6, - PriceChangeInterval.YEAR, - PriceChangeInterval.ALL_TIME, - ), - color = TangemTheme.colors.button.secondary, - initialSelectedItem = trendInterval, - onClick = onIntervalClick, - isEnabled = isEnabled, + TangemSegmentedPicker( + items = items, + initialSelectedItem = selectedItem, + isFixed = true, modifier = modifier, - ) { - Box( - Modifier - .fillMaxSize() - .align(Alignment.Center) - .padding( - vertical = TangemTheme.dimens.spacing4, - ), - ) { - Text( - modifier = Modifier.align(Alignment.Center), - text = it.getText().resolveReference(), - style = TangemTheme.typography.caption1, - color = if (isEnabled) { - TangemTheme.colors.text.primary1 - } else { - TangemTheme.colors.text.disabled - }, - ) - } - } + onClick = { onIntervalClick(PriceChangeInterval.valueOf(it.id)) }, + ) } @Composable @@ -493,7 +332,6 @@ private fun MarketsTokenDetailsContent_Preview( MarketsTokenDetailsContent( state = params, backgroundColor = TangemTheme.colors.background.tertiary, - portfolioBlock = {}, portfolioFloatingBlock = null, marketingBanner = {}, contentPadding = PaddingValues(), diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/MarketsTokenDetailsTitle.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/MarketsTokenDetailsTitle.kt index 95f163f3dc..ee86620523 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/MarketsTokenDetailsTitle.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/MarketsTokenDetailsTitle.kt @@ -11,7 +11,6 @@ import androidx.compose.runtime.Composable 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.graphics.vector.ImageVector import androidx.compose.ui.res.vectorResource import androidx.compose.ui.unit.Dp @@ -21,7 +20,6 @@ import com.tangem.core.ui.components.haze.hazeEffectTangem 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.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.generated.icons.Icons import com.tangem.core.ui.res.generated.icons.ic_sign_plus_24 @@ -31,29 +29,16 @@ import com.tangem.features.feed.ui.market.detailed.state.MarketsTokenDetailsUM @Composable internal fun MarketsTokenDetailsTitle( state: MarketsTokenDetailsUM, - backgroundColor: Color, isBackButtonEnabled: Boolean, onBackClick: () -> Unit, ) { - if (LocalRedesignEnabled.current) { - MarketsTokenDetailsRedesignTopBar( - isAddToPortfolioButtonVisible = state.isAddToPortfolioButtonVisible, - onAddToPortfolioClick = state.onAddToPortfolioClick, - onShareClick = state.onShareClick, - isBackButtonEnabled = isBackButtonEnabled, - onBackClick = onBackClick, - ) - } else { - MarketsTokenDetailsTopBar( - onBackClick = onBackClick, - isBackButtonEnabled = isBackButtonEnabled, - shouldShowPriceSubtitle = state.shouldShowPriceSubtitle, - tokenName = state.tokenName, - tokenPrice = state.priceText, - backgroundColor = backgroundColor, - onShareClick = state.onShareClick, - ) - } + MarketsTokenDetailsRedesignTopBar( + isAddToPortfolioButtonVisible = state.isAddToPortfolioButtonVisible, + onAddToPortfolioClick = state.onAddToPortfolioClick, + onShareClick = state.onShareClick, + isBackButtonEnabled = isBackButtonEnabled, + onBackClick = onBackClick, + ) } @Composable diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/ExchangesBottomSheet.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/ExchangesBottomSheet.kt index e41fb40418..0c89a7b0c5 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/ExchangesBottomSheet.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/ExchangesBottomSheet.kt @@ -5,13 +5,11 @@ import androidx.annotation.StringRes import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -29,16 +27,9 @@ import androidx.compose.ui.unit.dp import com.tangem.core.ui.components.CircleShimmer import com.tangem.core.ui.components.RectangleShimmer import com.tangem.core.ui.components.SpacerH -import com.tangem.core.ui.components.SpacerH12 -import com.tangem.core.ui.components.appbar.TangemTopAppBar -import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM import com.tangem.core.ui.components.audits.AuditLabelUM import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig -import com.tangem.core.ui.components.bottomsheets.sheet.TangemBottomSheet -import com.tangem.core.ui.components.buttons.SecondarySmallButton -import com.tangem.core.ui.components.buttons.SmallButtonConfig import com.tangem.core.ui.components.currency.icon.CurrencyIconState -import com.tangem.core.ui.components.token.TokenItem import com.tangem.core.ui.components.token.state.TokenItemState import com.tangem.core.ui.decorations.roundedShapeItemDecoration import com.tangem.core.ui.ds.button.* @@ -48,10 +39,8 @@ import com.tangem.core.ui.ds.row.TangemRowLayoutId import com.tangem.core.ui.ds.topbar.TangemTopBar import com.tangem.core.ui.ds.topbar.TangemTopBarType import com.tangem.core.ui.extensions.* -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.test.TokenElementsTestTags import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.res.TangemThemePreviewRedesign import com.tangem.features.feed.impl.R import com.tangem.features.feed.ui.market.detailed.state.ExchangeItemUM @@ -68,56 +57,7 @@ import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet as TangemBot */ @Composable internal fun ExchangesBottomSheet(config: TangemBottomSheetConfig) { - if (LocalRedesignEnabled.current) { - ExchangesBottomSheetV2(config) - } else { - ExchangesBottomSheetV1(config) - } -} - -@Composable -private fun ExchangesBottomSheetV1(config: TangemBottomSheetConfig) { - val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() } - - TangemBottomSheet( - config = config, - addBottomInsets = false, - title = { Title(textResId = it.titleResId, onBackClick = config.onDismissRequest) }, - content = { content -> - Box { - LazyColumn( - modifier = Modifier.fillMaxSize(), - contentPadding = PaddingValues(bottom = bottomBarHeight), - ) { - item(key = "subtitle") { - Subtitle( - subtitleRes = content.subtitleResId, - volumeReference = content.volumeReference, - modifier = Modifier.padding( - start = TangemTheme.dimens.spacing16, - top = TangemTheme.dimens.spacing12, - end = TangemTheme.dimens.spacing16, - bottom = TangemTheme.dimens.spacing8, - ), - ) - } - - items( - items = content.exchangeItems, - key = TokenItemState::id, - itemContent = { TokenItem(state = it, isBalanceHidden = false) }, - ) - } - - if (content is ExchangesBottomSheetContent.Error) { - Error( - content = content, - modifier = Modifier.align(Alignment.Center), - ) - } - } - }, - ) + ExchangesBottomSheetV2(config) } @Composable @@ -191,14 +131,6 @@ private fun ExchangesBottomSheetV2(config: TangemBottomSheetConfig) { ) } -@Composable -private fun Title(@StringRes textResId: Int, onBackClick: () -> Unit) { - TangemTopAppBar( - title = stringResourceSafe(id = textResId), - startButton = TopAppBarButtonUM.Back(onBackClicked = onBackClick), - ) -} - @Composable private fun Subtitle(@StringRes subtitleRes: Int, volumeReference: TextReference, modifier: Modifier = Modifier) { Row( @@ -213,57 +145,18 @@ private fun Subtitle(@StringRes subtitleRes: Int, volumeReference: TextReference @Composable private fun SubtitleText(textReference: TextReference) { - if (LocalRedesignEnabled.current) { - Text( - text = textReference.resolveReference(), - color = TangemTheme.colors2.text.neutral.secondary, - overflow = TextOverflow.Ellipsis, - maxLines = 1, - style = TangemTheme.typography2.captionSemibold12, - ) - } else { - Text( - text = textReference.resolveReference(), - color = TangemTheme.colors.text.tertiary, - overflow = TextOverflow.Ellipsis, - maxLines = 1, - style = TangemTheme.typography.body2, - ) - } + Text( + text = textReference.resolveReference(), + color = TangemTheme.colors2.text.neutral.secondary, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + style = TangemTheme.typography2.captionSemibold12, + ) } @Composable private fun Error(content: ExchangesBottomSheetContent.Error, modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - ErrorV2(content, modifier) - } else { - ErrorV1(content, modifier) - } -} - -@Composable -private fun ErrorV1(content: ExchangesBottomSheetContent.Error, modifier: Modifier = Modifier) { - Column( - modifier = modifier, - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Text( - text = stringResourceSafe(id = content.message), - color = TangemTheme.colors.text.tertiary, - textAlign = TextAlign.Center, - style = TangemTheme.typography.caption1, - ) - - SpacerH12() - - SecondarySmallButton( - config = SmallButtonConfig( - text = resourceReference(id = R.string.alert_button_try_again), - onClick = content.onRetryClick, - ), - ) - } + ErrorV2(content, modifier) } @Composable @@ -427,10 +320,10 @@ private fun getColorByTrustValue(type: AuditLabelUM.Type): Color { @Preview @Preview(name = "Dark Theme", uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable -private fun Preview_ExchangesBottomSheet( +private fun Preview_ExchangesBottomSheetV2( @PreviewParameter(ExchangesBottomSheetContentProvider::class) content: ExchangesBottomSheetContent, ) { - TangemThemePreview { + TangemThemePreviewRedesign { ExchangesBottomSheet( config = TangemBottomSheetConfig( onDismissRequest = {}, @@ -441,25 +334,6 @@ private fun Preview_ExchangesBottomSheet( } } -@Preview -@Preview(name = "Dark Theme", uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun Preview_ExchangesBottomSheetV2( - @PreviewParameter(ExchangesBottomSheetContentProvider::class) content: ExchangesBottomSheetContent, -) { - TangemThemePreviewRedesign { - CompositionLocalProvider(LocalRedesignEnabled provides true) { - ExchangesBottomSheet( - config = TangemBottomSheetConfig( - onDismissRequest = {}, - content = content, - isShown = true, - ), - ) - } - } -} - private class ExchangesBottomSheetContentProvider : CollectionPreviewParameterProvider( listOf( ExchangesBottomSheetContent.Loading(exchangesCount = 13), diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/InfoBottomSheet.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/InfoBottomSheet.kt index 394cf45ce7..3e992459ec 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/InfoBottomSheet.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/InfoBottomSheet.kt @@ -17,19 +17,13 @@ import androidx.compose.ui.res.vectorResource import com.tangem.core.ui.components.SpacerH import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetType -import com.tangem.core.ui.components.bottomsheets.sheet.TangemBottomSheet -import com.tangem.core.ui.components.bottomsheets.sheet.TangemBottomSheetTitle -import com.tangem.core.ui.components.notifications.Notification -import com.tangem.core.ui.components.notifications.NotificationConfig import com.tangem.core.ui.ds.row.TangemRowContainer import com.tangem.core.ui.ds.row.TangemRowLayoutId import com.tangem.core.ui.ds.topbar.TangemTopBar import com.tangem.core.ui.ds.topbar.TangemTopBarType -import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.clickableSingle import com.tangem.core.ui.extensions.resolveReference import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.features.feed.impl.R import com.tangem.features.feed.ui.market.detailed.state.InfoBottomSheetContent @@ -38,50 +32,7 @@ import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet as TangemBot @Composable internal fun InfoBottomSheet(config: TangemBottomSheetConfig) { - if (LocalRedesignEnabled.current) { - InfoBottomSheetV2(config) - } else { - InfoBottomSheetV1(config) - } -} - -@Composable -private fun InfoBottomSheetV1(config: TangemBottomSheetConfig) { - val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() } - - TangemBottomSheet( - config = config, - addBottomInsets = false, - title = { TangemBottomSheetTitle(title = it.title) }, - content = { content -> - Column( - modifier = Modifier - .verticalScroll(rememberScrollState()) - .padding(horizontal = TangemTheme.dimens.spacing16), - ) { - MarkdownText( - markdown = content.body.resolveReference(), - disableLinkMovementMethod = true, - linkifyMask = 0, - syntaxHighlightColor = TangemTheme.colors.text.secondary, - style = TangemTheme.typography.body2.copy( - color = TangemTheme.colors.text.secondary, - ), - ) - - if (content.generatedAINotificationUM != null) { - AdditionalInfoNotification( - onClick = content.generatedAINotificationUM.onClick, - modifier = Modifier - .padding(top = TangemTheme.dimens.spacing12, bottom = TangemTheme.dimens.spacing16) - .fillMaxWidth(), - ) - } - - SpacerH(bottomBarHeight) - } - }, - ) + InfoBottomSheetV2(config) } @Suppress("LongMethod") @@ -165,20 +116,4 @@ private fun InfoBottomSheetV2(config: TangemBottomSheetConfig) { } }, ) -} - -@Composable -private fun AdditionalInfoNotification(onClick: () -> Unit, modifier: Modifier = Modifier) { - Notification( - config = NotificationConfig( - subtitle = TextReference.Res(id = R.string.information_generated_with_ai), - iconResId = R.drawable.ic_magic_28, - onClick = onClick, - shouldShowArrowIcon = false, - ), - modifier = modifier, - subtitleColor = TangemTheme.colors.text.primary1, - containerColor = TangemTheme.colors.button.disabled, - iconTint = TangemTheme.colors.icon.accent, - ) } \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/InfoPoint.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/InfoPoint.kt index d9ef6ae298..e21e676406 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/InfoPoint.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/InfoPoint.kt @@ -8,7 +8,6 @@ import androidx.compose.foundation.layout.* import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -20,75 +19,16 @@ import androidx.compose.ui.unit.dp import com.tangem.core.ui.R import com.tangem.core.ui.components.RectangleShimmer import com.tangem.core.ui.components.SpacerW4 -import com.tangem.core.ui.components.TextShimmer -import com.tangem.core.ui.components.text.TooltipText import com.tangem.core.ui.extensions.conditional import com.tangem.core.ui.extensions.resolveReference import com.tangem.core.ui.extensions.stringReference -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.res.TangemThemePreviewRedesign -import com.tangem.core.ui.utils.PreviewShimmerContainer import com.tangem.features.feed.ui.market.detailed.state.InfoPointUM @Composable internal fun InfoPoint(infoPointUM: InfoPointUM, modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - InfoPointV2(infoPointUM, modifier) - } else { - InfoPointV1(infoPointUM, modifier) - } -} - -@Composable -private fun InfoPointV1(infoPointUM: InfoPointUM, modifier: Modifier = Modifier) { - Column( - modifier = modifier.padding(vertical = TangemTheme.dimens.spacing8), - horizontalAlignment = Alignment.Start, - ) { - if (infoPointUM.onInfoClick != null) { - TooltipText( - text = infoPointUM.title, - onInfoClick = infoPointUM.onInfoClick, - textStyle = TangemTheme.typography.caption2, - ) - } else { - Text( - text = infoPointUM.title.resolveReference(), - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.tertiary, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - } - Row { - Text( - text = infoPointUM.value, - style = TangemTheme.typography.body1, - color = TangemTheme.colors.text.primary1, - ) - if (infoPointUM.change != null) { - SpacerW4() - Icon( - modifier = Modifier - .size(TangemTheme.dimens.size8) - .align(Alignment.CenterVertically), - imageVector = ImageVector.vectorResource( - id = when (infoPointUM.change) { - InfoPointUM.ChangeType.UP -> R.drawable.ic_arrow_up_8 - InfoPointUM.ChangeType.DOWN -> R.drawable.ic_arrow_down_8 - }, - ), - tint = when (infoPointUM.change) { - InfoPointUM.ChangeType.UP -> TangemTheme.colors.icon.accent - InfoPointUM.ChangeType.DOWN -> TangemTheme.colors.icon.warning - }, - contentDescription = null, - ) - } - } - } + InfoPointV2(infoPointUM, modifier) } @Composable @@ -154,46 +94,8 @@ private fun InfoPointV2(infoPointUM: InfoPointUM, modifier: Modifier = Modifier) } @Composable -internal fun InfoPointShimmer(modifier: Modifier = Modifier, withTooltip: Boolean = false) { - if (LocalRedesignEnabled.current) { - InfoPointShimmerV2(modifier) - } else { - InfoPointShimmerV1(modifier, withTooltip) - } -} - -@Composable -private fun InfoPointShimmerV1(modifier: Modifier = Modifier, withTooltip: Boolean = false) { - Column( - modifier = modifier.padding(vertical = TangemTheme.dimens.spacing8), - horizontalAlignment = Alignment.Start, - ) { - if (withTooltip) { - Box( - modifier = Modifier - .requiredHeight(TangemTheme.dimens.size16) - .fillMaxWidth(), - contentAlignment = Alignment.CenterStart, - ) { - TextShimmer( - modifier = Modifier.fillMaxWidth(), - style = TangemTheme.typography.caption2, - textSizeHeight = false, - ) - } - } else { - TextShimmer( - modifier = Modifier.fillMaxWidth(), - style = TangemTheme.typography.caption2, - textSizeHeight = true, - ) - } - TextShimmer( - modifier = Modifier.fillMaxWidth(fraction = 0.5f), - style = TangemTheme.typography.body1, - textSizeHeight = true, - ) - } +internal fun InfoPointShimmer(modifier: Modifier = Modifier) { + InfoPointShimmerV2(modifier) } @Composable @@ -223,8 +125,8 @@ private fun InfoPointShimmerV2(modifier: Modifier = Modifier) { @Preview @Preview("Dark Theme", uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable -private fun ContentPreviewV1() { - TangemThemePreview { +private fun ContentPreviewV2() { + TangemThemePreviewRedesign { Column( modifier = Modifier .width(150.dp) @@ -261,85 +163,4 @@ private fun ContentPreviewV1() { ) } } -} - -@Preview -@Preview("Dark Theme", uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun ContentPreviewV2() { - CompositionLocalProvider( - LocalRedesignEnabled provides true, - ) { - TangemThemePreviewRedesign { - Column( - modifier = Modifier - .width(150.dp) - .background(TangemTheme.colors.background.tertiary), - ) { - InfoPoint( - infoPointUM = InfoPointUM( - title = stringReference("Market Cap"), - value = "$1,000,000,000", - ), - ) - InfoPoint( - infoPointUM = InfoPointUM( - title = stringReference("Market Cap"), - value = "$1,000,000,000", - onInfoClick = { }, - ), - ) - InfoPoint( - infoPointUM = InfoPointUM( - title = stringReference("Market Cap"), - value = "$1,000,000", - change = InfoPointUM.ChangeType.UP, - onInfoClick = { }, - ), - ) - InfoPoint( - infoPointUM = InfoPointUM( - title = stringReference("Market Cap"), - value = "$1,000,000", - change = InfoPointUM.ChangeType.DOWN, - onInfoClick = { }, - ), - ) - } - } - } -} - -@Preview -@Preview("Dark Theme", uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun PreviewShimmer() { - TangemThemePreview { - PreviewShimmerContainer( - shimmerContent = { - Column( - modifier = Modifier - .width(150.dp) - .background(TangemTheme.colors.background.tertiary), - ) { - InfoPointShimmer(modifier = Modifier.fillMaxWidth()) - InfoPointShimmer( - modifier = Modifier.fillMaxWidth(), - withTooltip = true, - ) - InfoPointShimmer( - modifier = Modifier.fillMaxWidth(), - withTooltip = true, - ) - InfoPointShimmer( - modifier = Modifier.fillMaxWidth(), - withTooltip = true, - ) - } - }, - actualContent = { - ContentPreviewV1() - }, - ) - } } \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/InsightsBlock.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/InsightsBlock.kt index 0d0dc27c6a..e8c29c5c45 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/InsightsBlock.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/InsightsBlock.kt @@ -6,29 +6,21 @@ import androidx.compose.material3.Text import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.tangem.core.ui.components.RectangleShimmer import com.tangem.core.ui.components.SpacerW import com.tangem.core.ui.components.block.information.GridItems -import com.tangem.core.ui.components.block.information.InformationBlock -import com.tangem.core.ui.components.buttons.segmentedbutton.SegmentedButtons -import com.tangem.core.ui.components.text.TooltipText import com.tangem.core.ui.ds.tabs.TangemSegmentUM import com.tangem.core.ui.ds.tabs.TangemSegmentedPicker -import com.tangem.core.ui.extensions.resolveReference import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.res.TangemThemePreviewRedesign import com.tangem.core.ui.utils.PreviewShimmerContainer import com.tangem.domain.markets.PriceChangeInterval import com.tangem.features.feed.impl.R import com.tangem.features.feed.ui.components.TokenMarketInformationBlock -import com.tangem.features.feed.ui.market.detailed.getText import com.tangem.features.feed.ui.market.detailed.state.InfoPointUM import com.tangem.features.feed.ui.market.detailed.state.InsightsUM import kotlinx.collections.immutable.persistentListOf @@ -36,77 +28,7 @@ import kotlinx.collections.immutable.toImmutableList @Composable internal fun InsightsBlock(state: InsightsUM, modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - InsightsBlockV2(state, modifier) - } else { - InsightsBlockV1(state, modifier) - } -} - -@Composable -private fun InsightsBlockV1(state: InsightsUM, modifier: Modifier = Modifier) { - var currentInterval by remember { mutableStateOf(PriceChangeInterval.H24) } - - InformationBlock( - modifier = modifier, - title = { - TooltipText( - text = resourceReference(R.string.markets_token_details_insights), - textStyle = TangemTheme.typography.subtitle2, - onInfoClick = state.onInfoClick, - ) - }, - action = { - SegmentedButtons( - config = persistentListOf( - PriceChangeInterval.H24, - PriceChangeInterval.WEEK, - PriceChangeInterval.MONTH, - ), - initialSelectedItem = PriceChangeInterval.H24, - onClick = { interval -> - currentInterval = interval - state.onIntervalChanged(interval) - }, - modifier = Modifier.width(IntrinsicSize.Min), - ) { - Box( - Modifier - .fillMaxSize() - .align(Alignment.Center) - .padding( - horizontal = 14.dp, - vertical = 4.dp, - ), - ) { - Text( - modifier = Modifier.align(Alignment.Center), - text = it.getText().resolveReference(), - style = TangemTheme.typography.caption1, - color = TangemTheme.colors.text.primary1, - ) - } - } - }, - content = { - val infoPoints = when (currentInterval) { - PriceChangeInterval.H24 -> state.h24Info - PriceChangeInterval.WEEK -> state.weekInfo - PriceChangeInterval.MONTH -> state.monthInfo - else -> state.h24Info - } - - GridItems( - items = infoPoints, - itemContent = { infoPointUM -> - InfoPoint( - modifier = Modifier.align(Alignment.CenterStart), - infoPointUM = infoPointUM, - ) - }, - ) - }, - ) + InsightsBlockV2(state, modifier) } @Composable @@ -180,41 +102,7 @@ private fun InsightsBlockV2(state: InsightsUM, modifier: Modifier = Modifier) { @Composable internal fun InsightsBlockPlaceholder(modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - InsightsBlockPlaceholderV2(modifier) - } else { - InsightsBlockPlaceholderV1(modifier) - } -} - -@Composable -internal fun InsightsBlockPlaceholderV1(modifier: Modifier = Modifier) { - val subtitle2dp = with(LocalDensity.current) { TangemTheme.typography.subtitle2.lineHeight.toDp() } - val caption1dp = with(LocalDensity.current) { TangemTheme.typography.caption1.lineHeight.toDp() } - val headerHeight = maxOf(subtitle2dp, caption1dp) + TangemTheme.dimens.spacing4 - - InformationBlock( - modifier = modifier, - title = { - RectangleShimmer( - modifier = Modifier - .height(headerHeight) - .fillMaxWidth(), - radius = TangemTheme.dimens.radius3, - ) - }, - content = { - GridItems( - items = List(size = 4) { it }.toImmutableList(), - horizontalArragement = Arrangement.spacedBy(TangemTheme.dimens.spacing12), - itemContent = { - InfoPointShimmer( - modifier = Modifier.fillMaxWidth(), - ) - }, - ) - }, - ) + InsightsBlockPlaceholderV2(modifier) } @Composable @@ -257,8 +145,8 @@ internal fun InsightsBlockPlaceholderV2(modifier: Modifier = Modifier) { @Preview @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable -private fun ContentPreviewV1() { - TangemThemePreview { +private fun ContentPreviewV2() { + TangemThemePreviewRedesign { InsightsBlock( state = InsightsUM( h24Info = persistentListOf( @@ -325,95 +213,11 @@ private fun ContentPreviewV1() { @Preview @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable -private fun ContentPreviewV2() { - CompositionLocalProvider(LocalRedesignEnabled provides true) { - TangemThemePreviewRedesign { - InsightsBlock( - state = InsightsUM( - h24Info = persistentListOf( - InfoPointUM( - title = resourceReference(R.string.markets_token_details_experienced_buyers), - value = "1 000 000 000", - ), - InfoPointUM( - title = resourceReference(R.string.markets_token_details_buy_pressure), - value = "1 000 000 000", - ), - InfoPointUM( - title = resourceReference(R.string.markets_token_details_holders), - value = "1 000 000 000", - ), - InfoPointUM( - title = resourceReference(R.string.markets_token_details_liquidity), - value = "1 000 000 000", - ), - ), - weekInfo = persistentListOf( - InfoPointUM( - title = resourceReference(R.string.markets_token_details_experienced_buyers), - value = "1 000 000", - ), - InfoPointUM( - title = resourceReference(R.string.markets_token_details_buy_pressure), - value = "1 000 000", - ), - InfoPointUM( - title = resourceReference(R.string.markets_token_details_holders), - value = "1 000 000", - ), - InfoPointUM( - title = resourceReference(R.string.markets_token_details_liquidity), - value = "1 000 000", - ), - ), - monthInfo = persistentListOf( - InfoPointUM( - title = resourceReference(R.string.markets_token_details_experienced_buyers), - value = "1 000", - ), - InfoPointUM( - title = resourceReference(R.string.markets_token_details_buy_pressure), - value = "1 000", - ), - InfoPointUM( - title = resourceReference(R.string.markets_token_details_holders), - value = "1 000", - ), - InfoPointUM( - title = resourceReference(R.string.markets_token_details_liquidity), - value = "1 000", - ), - ), - onInfoClick = {}, - onIntervalChanged = {}, - ), - ) - } - } -} - -@Preview -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun PreviewPlaceholderV1() { - TangemThemePreview { +private fun PreviewPlaceholderV2() { + TangemThemePreviewRedesign { PreviewShimmerContainer( - actualContent = { ContentPreviewV1() }, + actualContent = { ContentPreviewV2() }, shimmerContent = { InsightsBlockPlaceholder() }, ) } -} - -@Preview -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun PreviewPlaceholderV2() { - TangemThemePreviewRedesign { - CompositionLocalProvider(LocalRedesignEnabled provides true) { - PreviewShimmerContainer( - actualContent = { ContentPreviewV2() }, - shimmerContent = { InsightsBlockPlaceholder() }, - ) - } - } } \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/LinksBlock.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/LinksBlock.kt index 78b45dd66f..7019b69819 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/LinksBlock.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/LinksBlock.kt @@ -11,9 +11,6 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.util.fastForEach import com.tangem.core.ui.components.ChipShimmer import com.tangem.core.ui.components.TextShimmer -import com.tangem.core.ui.components.block.information.InformationBlock -import com.tangem.core.ui.components.buttons.chip.Chip -import com.tangem.core.ui.components.inputrow.inner.DividerContainer import com.tangem.core.ui.ds.button.SecondaryTangemButton import com.tangem.core.ui.ds.button.TangemButtonIconPosition import com.tangem.core.ui.ds.button.TangemButtonShape @@ -21,11 +18,8 @@ import com.tangem.core.ui.ds.button.TangemButtonSize import com.tangem.core.ui.ds.image.TangemIconUM import com.tangem.core.ui.extensions.stringReference import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.res.TangemThemePreviewRedesign -import com.tangem.core.ui.utils.PreviewShimmerContainer import com.tangem.features.feed.impl.R import com.tangem.features.feed.ui.market.detailed.state.LinksUM import kotlinx.collections.immutable.ImmutableList @@ -33,53 +27,7 @@ import kotlinx.collections.immutable.persistentListOf @Composable internal fun LinksBlock(state: LinksUM, modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - LinksBlockV2(state, modifier) - } else { - LinksBlockV1(state, modifier) - } -} - -@Composable -private fun LinksBlockV1(state: LinksUM, modifier: Modifier = Modifier) { - InformationBlock( - modifier = modifier, - contentHorizontalPadding = 0.dp, - title = { - Text( - text = stringResourceSafe(id = R.string.markets_token_details_links), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.tertiary, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - }, - content = { - Column { - SubBlockV1( - title = stringResourceSafe(id = R.string.markets_token_details_official_links), - links = state.officialLinks, - onLinkClick = state.onLinkClick, - ) - SubBlockV1( - title = stringResourceSafe(id = R.string.markets_token_details_social), - links = state.social, - onLinkClick = state.onLinkClick, - ) - SubBlockV1( - title = stringResourceSafe(id = R.string.markets_token_details_repository), - links = state.repository, - onLinkClick = state.onLinkClick, - ) - SubBlockV1( - title = stringResourceSafe(id = R.string.markets_token_details_blockchain_site), - links = state.blockchainSite, - onLinkClick = state.onLinkClick, - lastBlock = true, - ) - } - }, - ) + LinksBlockV2(state, modifier) } @Composable @@ -108,48 +56,6 @@ private fun LinksBlockV2(state: LinksUM, modifier: Modifier = Modifier) { } } -@OptIn(ExperimentalLayoutApi::class) -@Composable -private fun SubBlockV1( - links: ImmutableList, - onLinkClick: (LinksUM.Link) -> Unit, - modifier: Modifier = Modifier, - lastBlock: Boolean = false, - title: String = "Official links", -) { - if (links.isEmpty()) return - - DividerContainer( - modifier = modifier, - showDivider = !lastBlock, - ) { - Column( - modifier = Modifier.padding(TangemTheme.dimens.spacing12), - verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12), - ) { - Text( - text = title, - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.tertiary, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - FlowRow( - horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12), - verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12), - ) { - links.fastForEach { link -> - Chip( - text = stringReference(link.title), - iconResId = link.iconRes, - onClick = { onLinkClick(link) }, - ) - } - } - } - } -} - @OptIn(ExperimentalLayoutApi::class) @Composable private fun SubBlockV2( @@ -196,32 +102,7 @@ private fun SubBlockV2( @Composable fun LinksBlockPlaceholder(modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - LinksBlockPlaceholderV2(modifier) - } else { - LinksBlockPlaceholderV1(modifier) - } -} - -@Composable -private fun LinksBlockPlaceholderV1(modifier: Modifier = Modifier) { - InformationBlock( - modifier = modifier, - contentHorizontalPadding = 0.dp, - title = { - TextShimmer( - modifier = Modifier.fillMaxWidth(), - style = TangemTheme.typography.subtitle2, - ) - }, - content = { - Column { - SubBlockPlaceholderV1() - SubBlockPlaceholderV1() - SubBlockPlaceholderV1(lastBlock = true) - } - }, - ) + LinksBlockPlaceholderV2(modifier) } @Composable @@ -233,33 +114,6 @@ private fun LinksBlockPlaceholderV2(modifier: Modifier = Modifier) { } } -@Composable -private fun SubBlockPlaceholderV1(modifier: Modifier = Modifier, lastBlock: Boolean = false) { - DividerContainer( - modifier = modifier, - showDivider = !lastBlock, - ) { - Column( - modifier = Modifier.padding(vertical = TangemTheme.dimens.spacing12), - verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12), - ) { - TextShimmer( - modifier = Modifier.width(78.dp), - style = TangemTheme.typography.caption2, - ) - Row( - horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12), - ) { - repeat(times = 3) { - ChipShimmer( - modifier = Modifier.weight(1f), - ) - } - } - } - } -} - @Composable private fun SubBlockPlaceholderV2(modifier: Modifier = Modifier) { Column( @@ -285,56 +139,6 @@ private fun SubBlockPlaceholderV2(modifier: Modifier = Modifier) { } } -@Preview -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun ContentPreviewV1() { - TangemThemePreview { - LinksBlockV1( - state = LinksUM( - officialLinks = persistentListOf( - LinksUM.Link( - title = "Website", - iconRes = R.drawable.ic_plus_24, - url = "https://tangem.com", - ), - LinksUM.Link( - title = "Website", - iconRes = R.drawable.ic_plus_24, - url = "https://tangem.com", - ), - LinksUM.Link( - title = "Website", - iconRes = R.drawable.ic_plus_24, - url = "https://tangem.com", - ), - ), - social = persistentListOf( - LinksUM.Link( - title = "Twitter", - iconRes = R.drawable.ic_plus_24, - url = "https://tangem.com", - ), - LinksUM.Link( - title = "Facebook", - iconRes = R.drawable.ic_plus_24, - url = "https://tangem.com", - ), - ), - repository = persistentListOf( - LinksUM.Link( - title = "Github", - iconRes = R.drawable.ic_plus_24, - url = "https://tangem.com", - ), - ), - blockchainSite = persistentListOf(), - onLinkClick = {}, - ), - ) - } -} - @Preview @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable @@ -385,18 +189,6 @@ private fun ContentPreviewV2() { } } -@Preview -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun PlaceholderPreviewV1() { - TangemThemePreview { - PreviewShimmerContainer( - shimmerContent = { LinksBlockPlaceholderV1() }, - actualContent = { ContentPreviewV1() }, - ) - } -} - @Preview @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/ListedOnBlock.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/ListedOnBlock.kt index 5691e27dcb..d460b2ac13 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/ListedOnBlock.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/ListedOnBlock.kt @@ -1,6 +1,5 @@ package com.tangem.features.feed.ui.market.detailed.components -import android.content.res.Configuration import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.material3.Icon @@ -8,28 +7,19 @@ 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.vector.ImageVector import androidx.compose.ui.platform.testTag -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider import androidx.compose.ui.unit.dp import com.tangem.common.ui.R import com.tangem.core.ui.components.SpacerWMax import com.tangem.core.ui.components.TextShimmer -import com.tangem.core.ui.components.block.information.InformationBlock import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.test.MarketsTestTags import com.tangem.features.feed.ui.components.TokenMarketInformationBlock import com.tangem.features.feed.ui.market.detailed.state.ListedOnUM -import kotlinx.coroutines.delay /** * "Listed on" block @@ -40,50 +30,7 @@ import kotlinx.coroutines.delay */ @Composable internal fun ListedOnBlock(state: ListedOnUM, modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - ListedOnBlockV2(state, modifier) - } else { - ListedOnBlockV1(state, modifier) - } -} - -@Composable -private fun ListedOnBlockV1(state: ListedOnUM, modifier: Modifier = Modifier) { - Box(modifier = modifier) { - InformationBlock( - title = { - Text( - text = state.title.resolveReference(), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.tertiary, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - }, - modifier = Modifier - .clip(shape = TangemTheme.shapes.roundedCornersXMedium) - .clickable(enabled = state is ListedOnUM.Content) { - (state as? ListedOnUM.Content)?.onClick?.invoke() - } - .testTag(MarketsTestTags.LISTED_ON_BLOCK), - ) { - Description( - state = state, - modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing12), - ) - } - - if (state is ListedOnUM.Content) { - Icon( - painter = painterResource(id = R.drawable.ic_chevron_right_24), - contentDescription = null, - tint = TangemTheme.colors.icon.informative, - modifier = Modifier - .align(Alignment.CenterEnd) - .padding(end = TangemTheme.dimens.spacing12), - ) - } - } + ListedOnBlockV2(state, modifier) } @Composable @@ -129,31 +76,7 @@ private fun ListedOnBlockV2(state: ListedOnUM, modifier: Modifier = Modifier) { @Composable internal fun ListedOnBlockPlaceholder(modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - ListedOnBlockPlaceholderV2(modifier) - } else { - ListedOnBlockPlaceholderV1(modifier) - } -} - -@Composable -internal fun ListedOnBlockPlaceholderV1(modifier: Modifier = Modifier) { - InformationBlock( - title = { - TextShimmer( - style = TangemTheme.typography.subtitle2, - modifier = Modifier.fillMaxWidth(fraction = 0.5f), - ) - }, - modifier = modifier, - ) { - TextShimmer( - style = TangemTheme.typography.body2, - modifier = Modifier - .fillMaxWidth(fraction = 0.3f) - .padding(bottom = TangemTheme.dimens.spacing12), - ) - } + ListedOnBlockPlaceholderV2(modifier) } @Composable @@ -175,51 +98,4 @@ internal fun ListedOnBlockPlaceholderV2(modifier: Modifier = Modifier) { } }, ) -} - -@Composable -private fun Description(state: ListedOnUM, modifier: Modifier = Modifier) { - Text( - text = state.description.resolveReference(), - modifier = modifier.testTag(MarketsTestTags.LISTED_ON_EXCHANGES_COUNT), - color = TangemTheme.colors.text.tertiary, - overflow = TextOverflow.Ellipsis, - maxLines = 1, - style = TangemTheme.typography.body2, - ) -} - -@Preview(widthDp = 328, heightDp = 68) -@Preview(name = "Dark Theme", widthDp = 328, heightDp = 68, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun Preview_ListedOnBlock(@PreviewParameter(ListenOnUMProvider::class) state: ListedOnUM?) { - TangemThemePreview { - if (state == null) { - ListedOnBlockPlaceholder() - } else { - ListedOnBlock(state = state) - } - } -} - -@Preview -@Composable -private fun Preview_ListedOnBlock_StateChanging() { - var state by remember { mutableStateOf(value = null) } - - Preview_ListedOnBlock(state = state) - - LaunchedEffect(key1 = null) { - delay(timeMillis = 3000) - - state = ListedOnUM.Empty - } -} - -private class ListenOnUMProvider : CollectionPreviewParameterProvider( - collection = listOf( - ListedOnUM.Empty, - ListedOnUM.Content(onClick = {}, amount = 5), - null, - ), -) \ No newline at end of file +} \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/MetricsBlock.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/MetricsBlock.kt index 396ef07835..f6c231b333 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/MetricsBlock.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/MetricsBlock.kt @@ -1,84 +1,23 @@ package com.tangem.features.feed.ui.market.detailed.components -import android.content.res.Configuration import androidx.compose.foundation.layout.* -import androidx.compose.material3.Text import androidx.compose.runtime.* import androidx.compose.ui.Modifier -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.tangem.core.ui.components.RectangleShimmer -import com.tangem.core.ui.components.TextButton -import com.tangem.core.ui.components.TextShimmer -import com.tangem.core.ui.components.block.information.GridItems -import com.tangem.core.ui.components.block.information.InformationBlock -import com.tangem.core.ui.components.buttons.common.TangemButtonsDefaults -import com.tangem.core.ui.extensions.resourceReference -import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.core.ui.utils.PreviewShimmerContainer -import com.tangem.features.feed.impl.R import com.tangem.features.feed.ui.components.MetricsCard -import com.tangem.features.feed.ui.market.detailed.state.InfoPointUM import com.tangem.features.feed.ui.market.detailed.state.InfoPointUMV2 import com.tangem.features.feed.ui.market.detailed.state.MetricsUM import com.tangem.features.feed.ui.market.detailed.state.MetricsV2UM -import kotlinx.collections.immutable.persistentListOf -import kotlinx.collections.immutable.toImmutableList - -const val MAX_METRICS_COUNT = 6 @Composable internal fun MetricsBlock(state: MetricsUM, modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - state.metricsV2?.let { - MetricsBlockV2(it, modifier) - } - } else { - MetricsBlockV1(state, modifier) + state.metricsV2?.let { + MetricsBlockV2(it, modifier) } } -@Composable -private fun MetricsBlockV1(state: MetricsUM, modifier: Modifier = Modifier) { - var isExpanded by remember { mutableStateOf(false) } - - InformationBlock( - modifier = modifier, - title = { - Text( - text = stringResourceSafe(id = R.string.markets_token_details_metrics), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.tertiary, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - }, - action = { - if (state.metrics.size > MAX_METRICS_COUNT) { - ShowLessMoreButton(expanded = isExpanded, onClick = { isExpanded = !isExpanded }) - } - }, - content = { - val metrics = if (isExpanded) { - state.metrics - } else { - state.metrics.take(MAX_METRICS_COUNT).toImmutableList() - } - - GridItems( - items = metrics, - itemContent = { - InfoPoint(infoPointUM = it) - }, - ) - }, - ) -} - @Composable private fun MetricsBlockV2(state: MetricsV2UM, modifier: Modifier = Modifier) { Column( @@ -123,60 +62,9 @@ private fun MetricCard(item: InfoPointUMV2) { } } -// TODO make TextButton clickable area smaller and remove paddings for an action in InformationBlock -@Composable -private fun ShowLessMoreButton(expanded: Boolean, onClick: () -> Unit) { - // FIXME add string resources - val text = if (expanded) { - "See less" - } else { - "See more" - } - - TextButton( - text = text, - onClick = onClick, - colors = TangemButtonsDefaults.positiveButtonColors, - textStyle = TangemTheme.typography.body2, - ) -} - @Composable internal fun MetricsBlockPlaceholder(modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - MetricsBlockPlaceholderV2(modifier) - } else { - MetricsBlockPlaceholderV1(modifier) - } -} - -@Composable -private fun MetricsBlockPlaceholderV1(modifier: Modifier = Modifier) { - InformationBlock( - modifier = modifier, - title = { - TextShimmer( - modifier = Modifier.fillMaxWidth(), - radius = TangemTheme.dimens.radius3, - style = TangemTheme.typography.subtitle2, - ) - }, - action = { - Box(Modifier) - }, - content = { - GridItems( - items = List(size = 6) { it }.toImmutableList(), - horizontalArragement = Arrangement.spacedBy(TangemTheme.dimens.spacing12), - itemContent = { - InfoPointShimmer( - modifier = Modifier.fillMaxWidth(), - withTooltip = true, - ) - }, - ) - }, - ) + MetricsBlockPlaceholderV2(modifier) } @Composable @@ -279,61 +167,4 @@ private fun CirculatingSupplyCardPlaceholder() { ) }, ) -} - -@Preview -@Preview("Dark Theme", uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun BlockPreview() { - TangemThemePreview { - MetricsBlock( - state = MetricsUM( - metrics = persistentListOf( - InfoPointUM( - title = resourceReference(R.string.markets_token_details_market_capitalization), - value = "1.2T", - onInfoClick = {}, - ), - InfoPointUM( - title = resourceReference(R.string.markets_token_details_market_rating), - value = "A", - onInfoClick = {}, - ), - InfoPointUM( - title = resourceReference(R.string.markets_token_details_trading_volume), - value = "1.2T", - onInfoClick = {}, - ), - InfoPointUM( - title = resourceReference(R.string.markets_token_details_fully_diluted_valuation), - value = "1.2T", - onInfoClick = {}, - ), - InfoPointUM( - title = resourceReference(R.string.markets_token_details_circulating_supply), - value = "1.2T", - onInfoClick = {}, - ), - InfoPointUM( - title = resourceReference(R.string.markets_token_details_total_supply), - value = "1.2T", - onInfoClick = {}, - ), - ), - metricsV2 = null, - ), - ) - } -} - -@Preview -@Preview("Dark Theme", uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun PreviewPlaceholder() { - TangemThemePreview { - PreviewShimmerContainer( - actualContent = { BlockPreview() }, - shimmerContent = { MetricsBlockPlaceholder() }, - ) - } } \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/MetricsCards.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/MetricsCards.kt index 9f0a64aa21..bed95a1b8b 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/MetricsCards.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/MetricsCards.kt @@ -7,7 +7,6 @@ import androidx.compose.material3.Icon import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -28,7 +27,6 @@ import com.tangem.core.ui.ds.row.TangemRowContainer import com.tangem.core.ui.ds.row.TangemRowLayoutId import com.tangem.core.ui.extensions.* import com.tangem.core.ui.res.LocalIsInDarkTheme -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreviewRedesign import com.tangem.features.feed.impl.R @@ -380,115 +378,113 @@ private const val BRONZE_PLACE_COLOR_LIGHT = 0xFFCC7F66 @Preview(widthDp = 360, heightDp = 1500, showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable private fun MetricsCardsPreview() { - CompositionLocalProvider(LocalRedesignEnabled provides true) { - TangemThemePreviewRedesign { - Column( - modifier = Modifier - .fillMaxWidth() - .background(TangemTheme.colors2.surface.level2) - .padding(16.dp), - verticalArrangement = Arrangement.spacedBy(12.dp), - ) { - MarketCapCard( - item = InfoPointUMV2.MarketCap( - capitalizationValue = stringReference("$ 1.2 T"), - onInfoClick = {}, - ), - ) + TangemThemePreviewRedesign { + Column( + modifier = Modifier + .fillMaxWidth() + .background(TangemTheme.colors2.surface.level2) + .padding(16.dp), + verticalArrangement = Arrangement.spacedBy(12.dp), + ) { + MarketCapCard( + item = InfoPointUMV2.MarketCap( + capitalizationValue = stringReference("$ 1.2 T"), + onInfoClick = {}, + ), + ) - TradingVolumeCard( - item = InfoPointUMV2.TradingVolume( - tradingValue = stringReference("$ 45.2 M"), - liquidity = 0.75f, - trendingVolumeLiquidityType = TrendingVolumeLiquidityType.HIGH, - onInfoClick = {}, - ), - ) + TradingVolumeCard( + item = InfoPointUMV2.TradingVolume( + tradingValue = stringReference("$ 45.2 M"), + liquidity = 0.75f, + trendingVolumeLiquidityType = TrendingVolumeLiquidityType.HIGH, + onInfoClick = {}, + ), + ) - TradingVolumeCard( - item = InfoPointUMV2.TradingVolume( - tradingValue = stringReference("$ 12.1 M"), - liquidity = 0.45f, - trendingVolumeLiquidityType = TrendingVolumeLiquidityType.MEDIUM, - onInfoClick = {}, - ), - ) + TradingVolumeCard( + item = InfoPointUMV2.TradingVolume( + tradingValue = stringReference("$ 12.1 M"), + liquidity = 0.45f, + trendingVolumeLiquidityType = TrendingVolumeLiquidityType.MEDIUM, + onInfoClick = {}, + ), + ) - TradingVolumeCard( - item = InfoPointUMV2.TradingVolume( - tradingValue = stringReference("$ 2.3 M"), - liquidity = 0.15f, - trendingVolumeLiquidityType = TrendingVolumeLiquidityType.LOW, - onInfoClick = {}, - ), - ) + TradingVolumeCard( + item = InfoPointUMV2.TradingVolume( + tradingValue = stringReference("$ 2.3 M"), + liquidity = 0.15f, + trendingVolumeLiquidityType = TrendingVolumeLiquidityType.LOW, + onInfoClick = {}, + ), + ) - MarketPositionCard( - item = InfoPointUMV2.MarketPosition( - position = stringReference("1"), - rangeValue = 0.02f, - marketRatingType = MarketRatingType.GOLD, - onInfoClick = {}, - marketRatingChange24H = MarketRatingChange24H.NoChanges, - ), - ) + MarketPositionCard( + item = InfoPointUMV2.MarketPosition( + position = stringReference("1"), + rangeValue = 0.02f, + marketRatingType = MarketRatingType.GOLD, + onInfoClick = {}, + marketRatingChange24H = MarketRatingChange24H.NoChanges, + ), + ) - MarketPositionCard( - item = InfoPointUMV2.MarketPosition( - position = stringReference("2"), - rangeValue = 0.05f, - marketRatingChange24H = MarketRatingChange24H.Up(1), - marketRatingType = MarketRatingType.SILVER, - onInfoClick = {}, - ), - ) + MarketPositionCard( + item = InfoPointUMV2.MarketPosition( + position = stringReference("2"), + rangeValue = 0.05f, + marketRatingChange24H = MarketRatingChange24H.Up(1), + marketRatingType = MarketRatingType.SILVER, + onInfoClick = {}, + ), + ) - MarketPositionCard( - item = InfoPointUMV2.MarketPosition( - position = null, - rangeValue = null, - marketRatingType = MarketRatingType.OTHER, - onInfoClick = {}, - marketRatingChange24H = MarketRatingChange24H.NoChanges, - ), - ) + MarketPositionCard( + item = InfoPointUMV2.MarketPosition( + position = null, + rangeValue = null, + marketRatingType = MarketRatingType.OTHER, + onInfoClick = {}, + marketRatingChange24H = MarketRatingChange24H.NoChanges, + ), + ) - MarketPositionCard( - item = InfoPointUMV2.MarketPosition( - position = stringReference("42"), - rangeValue = 0.42f, - marketRatingType = MarketRatingType.OTHER, - onInfoClick = {}, - marketRatingChange24H = MarketRatingChange24H.Down(15), - ), - ) + MarketPositionCard( + item = InfoPointUMV2.MarketPosition( + position = stringReference("42"), + rangeValue = 0.42f, + marketRatingType = MarketRatingType.OTHER, + onInfoClick = {}, + marketRatingChange24H = MarketRatingChange24H.Down(15), + ), + ) - FDVCard( - item = InfoPointUMV2.FullyDilutedValuation( - value = stringReference("$ 1.5 T"), - fullyDilutedValuationChange24 = stringReference("$ 2.44 M in total"), - onInfoClick = {}, - ), - ) + FDVCard( + item = InfoPointUMV2.FullyDilutedValuation( + value = stringReference("$ 1.5 T"), + fullyDilutedValuationChange24 = stringReference("$ 2.44 M in total"), + onInfoClick = {}, + ), + ) - CirculatingSupplyCard( - item = InfoPointUMV2.CirculatingSupply( - currentValue = stringReference("12.5 B POL"), - maxValue = stringReference("21 B POL"), - fillValue = 0.6f, - onInfoClick = {}, - ), - ) + CirculatingSupplyCard( + item = InfoPointUMV2.CirculatingSupply( + currentValue = stringReference("12.5 B POL"), + maxValue = stringReference("21 B POL"), + fillValue = 0.6f, + onInfoClick = {}, + ), + ) - CirculatingSupplyCard( - item = InfoPointUMV2.CirculatingSupply( - currentValue = stringReference("18.9 M ETH"), - maxValue = null, - fillValue = null, - onInfoClick = {}, - ), - ) - } + CirculatingSupplyCard( + item = InfoPointUMV2.CirculatingSupply( + currentValue = stringReference("18.9 M ETH"), + maxValue = null, + fillValue = null, + onInfoClick = {}, + ), + ) } } } \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/PricePerformanceBlock.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/PricePerformanceBlock.kt deleted file mode 100644 index 6e43c327ee..0000000000 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/PricePerformanceBlock.kt +++ /dev/null @@ -1,269 +0,0 @@ -package com.tangem.features.feed.ui.market.detailed.components - -import android.content.res.Configuration -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.IntrinsicSize -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.StrokeCap -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import com.tangem.core.ui.components.RectangleShimmer -import com.tangem.core.ui.components.SpacerW8 -import com.tangem.core.ui.components.TextShimmer -import com.tangem.core.ui.components.block.information.InformationBlock -import com.tangem.core.ui.components.buttons.segmentedbutton.SegmentedButtons -import com.tangem.core.ui.components.progressbar.TangemLinearProgressIndicator -import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.TangemAnimations -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.core.ui.utils.PreviewShimmerContainer -import com.tangem.domain.markets.PriceChangeInterval -import com.tangem.features.feed.impl.R -import com.tangem.features.feed.ui.market.detailed.getText -import com.tangem.features.feed.ui.market.detailed.state.PricePerformanceUM -import kotlinx.collections.immutable.persistentListOf - -@Composable -internal fun PricePerformanceBlock(state: PricePerformanceUM, modifier: Modifier = Modifier) { - var currentInterval by remember { mutableStateOf(PriceChangeInterval.H24) } - - InformationBlock( - modifier = modifier, - title = { - Text( - text = stringResourceSafe(id = R.string.markets_token_details_price_performance), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.tertiary, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - }, - action = { - SegmentedButtons( - config = persistentListOf( - PriceChangeInterval.H24, - PriceChangeInterval.MONTH, - PriceChangeInterval.ALL_TIME, - ), - initialSelectedItem = PriceChangeInterval.H24, - onClick = { interval -> - currentInterval = interval - state.onIntervalChanged(interval) - }, - modifier = Modifier.width(IntrinsicSize.Min), - ) { - Box( - Modifier - .fillMaxSize() - .align(Alignment.Center) - .padding( - horizontal = 14.dp, - vertical = TangemTheme.dimens.spacing4, - ), - ) { - Text( - modifier = Modifier.align(Alignment.Center), - text = it.getText().resolveReference(), - style = TangemTheme.typography.caption1, - color = TangemTheme.colors.text.primary1, - ) - } - } - }, - content = { - val value = when (currentInterval) { - PriceChangeInterval.H24 -> state.h24 - PriceChangeInterval.MONTH -> state.month - PriceChangeInterval.ALL_TIME -> state.all - else -> error("") - } - - Content( - modifier = Modifier.fillMaxWidth(), - state = value, - ) - }, - ) -} - -@Composable -private fun Content(state: PricePerformanceUM.Value, modifier: Modifier = Modifier) { - val animatedIndicatorFraction by TangemAnimations.horizontalIndicatorAsState( - targetFraction = state.indicatorFraction, - ) - - Column( - modifier = modifier - .padding(vertical = TangemTheme.dimens.spacing8), - verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12), - ) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - ) { - Text( - text = stringResourceSafe(R.string.markets_token_details_low), - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.tertiary, - ) - SpacerW8() - Text( - text = stringResourceSafe(R.string.markets_token_details_high), - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.tertiary, - ) - } - TangemLinearProgressIndicator( - modifier = Modifier - .height(TangemTheme.dimens.size6) - .fillMaxWidth(), - progress = { animatedIndicatorFraction }, - color = TangemTheme.colors.text.accent, - backgroundColor = TangemTheme.colors.background.tertiary, - strokeCap = StrokeCap.Round, - ) - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8), - ) { - Text( - modifier = Modifier.weight(1f), - text = state.low, - style = TangemTheme.typography.body1, - color = TangemTheme.colors.text.primary1, - ) - Text( - modifier = Modifier.weight(1f), - text = state.high, - style = TangemTheme.typography.body1, - color = TangemTheme.colors.text.primary1, - textAlign = TextAlign.End, - ) - } - } -} - -@Composable -internal fun PricePerformanceBlockPlaceholder(modifier: Modifier = Modifier) { - val subtitle2dp = with(LocalDensity.current) { TangemTheme.typography.subtitle2.lineHeight.toDp() } - val caption1dp = with(LocalDensity.current) { TangemTheme.typography.caption1.lineHeight.toDp() } - val headerHeight = maxOf(subtitle2dp, caption1dp) + TangemTheme.dimens.spacing4 - - InformationBlock( - modifier = modifier, - title = { - RectangleShimmer( - modifier = Modifier - .height(headerHeight) - .fillMaxWidth(), - radius = TangemTheme.dimens.radius3, - ) - }, - content = { - Column( - modifier = Modifier.padding(vertical = TangemTheme.dimens.spacing8), - verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12), - ) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - ) { - TextShimmer( - modifier = Modifier.width(35.dp), - style = TangemTheme.typography.caption2, - ) - SpacerW8() - TextShimmer( - modifier = Modifier.width(35.dp), - style = TangemTheme.typography.caption2, - ) - } - RectangleShimmer( - modifier = Modifier - .height(TangemTheme.dimens.size6) - .fillMaxWidth(), - radius = 27.dp, - ) - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - ) { - TextShimmer( - modifier = Modifier.width(TangemTheme.dimens.size56), - style = TangemTheme.typography.body1, - ) - SpacerW8() - TextShimmer( - modifier = Modifier.width(TangemTheme.dimens.size56), - style = TangemTheme.typography.body1, - ) - } - } - }, - ) -} - -@Preview -@Preview("Dark Theme", uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun ContentPreview() { - TangemThemePreview { - PricePerformanceBlock( - modifier = Modifier, - state = PricePerformanceUM( - h24 = PricePerformanceUM.Value( - low = "\$38,5K", - high = "\$58,5K", - indicatorFraction = 0.5f, - ), - month = PricePerformanceUM.Value( - low = "\$500,5K", - high = "\$5800,5K", - indicatorFraction = 0.8f, - ), - all = PricePerformanceUM.Value( - low = "\$58,52", - high = "\$580,5M", - indicatorFraction = 0.2f, - ), - onIntervalChanged = {}, - ), - ) - } -} - -@Preview -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun PlaceholderPreview() { - TangemThemePreview { - PreviewShimmerContainer( - shimmerContent = { - PricePerformanceBlockPlaceholder() - }, - actualContent = { - ContentPreview() - }, - ) - } -} \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/ScoreStarsBlock.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/ScoreStarsBlock.kt index 9243c0a91a..1b5bca2f65 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/ScoreStarsBlock.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/ScoreStarsBlock.kt @@ -3,7 +3,6 @@ package com.tangem.features.feed.ui.market.detailed.components import androidx.annotation.FloatRange import androidx.compose.foundation.layout.* import androidx.compose.material3.Icon -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -15,10 +14,7 @@ import androidx.compose.ui.graphics.CompositingStrategy import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.vectorResource -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.features.feed.impl.R import kotlin.math.round @@ -26,52 +22,7 @@ import kotlin.math.round private const val STARS_COUNT = 5 @Composable -internal fun ScoreStarsBlock( - score: Float, - horizontalSpacing: Dp, - scoreTextStyle: TextStyle, - modifier: Modifier = Modifier, -) { - if (LocalRedesignEnabled.current) { - ScoreStarsBlockV2( - score = score, - modifier = modifier, - ) - } else { - ScoreStarsBlockV1( - score = score, - horizontalSpacing = horizontalSpacing, - scoreTextStyle = scoreTextStyle, - modifier = modifier, - ) - } -} - -@Composable -private fun ScoreStarsBlockV1( - score: Float, - horizontalSpacing: Dp, - scoreTextStyle: TextStyle, - modifier: Modifier = Modifier, -) { - val rounded = score.roundTo1decimal() - val percentage = rounded / STARS_COUNT - Row( - modifier = modifier, - horizontalArrangement = Arrangement.spacedBy(horizontalSpacing), - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - text = rounded.toString(), - style = scoreTextStyle, - color = TangemTheme.colors.text.primary1, - ) - Stars(fraction = percentage) - } -} - -@Composable -private fun ScoreStarsBlockV2(score: Float, modifier: Modifier = Modifier) { +internal fun ScoreStarsBlock(score: Float, modifier: Modifier = Modifier) { val rounded = score.roundTo1decimal() val percentage = rounded / STARS_COUNT Box( @@ -85,59 +36,6 @@ private fun ScoreStarsBlockV2(score: Float, modifier: Modifier = Modifier) { @Suppress("MagicNumber") @Composable private fun Stars(@FloatRange(0.0, 1.0) fraction: Float = 0f) { - if (LocalRedesignEnabled.current) { - StarsV2(fraction) - } else { - StarsV1(fraction) - } -} - -@Suppress("MagicNumber") -@Composable -private fun StarsV1(@FloatRange(0.0, 1.0) fraction: Float = 0f) { - val grayColor = TangemTheme.colors.icon.inactive - - Row( - horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing4), - verticalAlignment = Alignment.CenterVertically, - ) { - repeat(times = STARS_COUNT) { i -> - Box( - modifier = Modifier.size(TangemTheme.dimens.size16), - contentAlignment = Alignment.Center, - ) { - Icon( - modifier = Modifier - .requiredSize(16.dp) - .graphicsLayer(compositingStrategy = CompositingStrategy.Offscreen) - .drawWithCache { - onDrawWithContent { - val starFraction = ((fraction - i * 0.2) / 0.2).coerceIn(0.0, 1.0) - val starFractionFloat = starFraction - .toFloat() - .roundTo1decimal() - - drawContent() - drawRect( - color = grayColor, - topLeft = Offset(x = size.width * starFractionFloat, y = 0f), - size = Size(size.width * (1 - starFractionFloat), size.height), - blendMode = BlendMode.SrcIn, - ) - } - }, - imageVector = ImageVector.vectorResource(R.drawable.ic_star_24), - contentDescription = null, - tint = TangemTheme.colors.icon.accent, - ) - } - } - } -} - -@Suppress("MagicNumber") -@Composable -private fun StarsV2(@FloatRange(0.0, 1.0) fraction: Float = 0f) { val grayColor = TangemTheme.colors2.markers.iconGray Row( diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/SecurityScoreBlock.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/SecurityScoreBlock.kt index 9ef7769693..ba23885144 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/SecurityScoreBlock.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/SecurityScoreBlock.kt @@ -6,77 +6,27 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.layoutId import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.tangem.core.ui.components.SpacerH import com.tangem.core.ui.components.TextShimmer -import com.tangem.core.ui.components.text.TooltipText import com.tangem.core.ui.ds.row.TangemRowContainer import com.tangem.core.ui.ds.row.TangemRowLayoutId import com.tangem.core.ui.extensions.resolveReference import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringReference -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.res.TangemThemePreviewRedesign -import com.tangem.core.ui.utils.PreviewShimmerContainer import com.tangem.features.feed.impl.R import com.tangem.features.feed.ui.components.TokenMarketInformationBlock import com.tangem.features.feed.ui.market.detailed.state.SecurityScoreUM @Composable internal fun SecurityScoreBlock(state: SecurityScoreUM, modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - SecurityScoreBlockV2(state, modifier) - } else { - SecurityScoreBlockV1(state, modifier) - } -} - -@Composable -private fun SecurityScoreBlockV1(state: SecurityScoreUM, modifier: Modifier = Modifier) { - Row( - modifier = modifier - .clip(TangemTheme.shapes.roundedCornersXMedium) - .background(TangemTheme.colors.background.action) - .fillMaxWidth() - .heightIn(max = TangemTheme.dimens.size72) - .padding(all = TangemTheme.dimens.spacing12), - verticalAlignment = Alignment.CenterVertically, - ) { - Column( - modifier = Modifier - .weight(1F) - .fillMaxHeight(), - verticalArrangement = Arrangement.SpaceBetween, - ) { - TooltipText( - text = resourceReference(R.string.markets_token_details_security_score), - onInfoClick = state.onInfoClick, - textStyle = TangemTheme.typography.subtitle2, - ) - - Text( - text = state.description.resolveReference(), - style = TangemTheme.typography.body2, - color = TangemTheme.colors.text.tertiary, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - } - ScoreStarsBlock( - score = state.score, - scoreTextStyle = TangemTheme.typography.body1, - horizontalSpacing = TangemTheme.dimens.spacing8, - ) - } + SecurityScoreBlockV2(state, modifier) } @Composable @@ -111,8 +61,6 @@ private fun SecurityScoreBlockV2(state: SecurityScoreUM, modifier: Modifier = Mo ScoreStarsBlock( modifier = Modifier.layoutId(layoutId = TangemRowLayoutId.END_TOP), score = state.score, - scoreTextStyle = TangemTheme.typography.body1, - horizontalSpacing = TangemTheme.dimens.spacing8, ) } }, @@ -121,11 +69,7 @@ private fun SecurityScoreBlockV2(state: SecurityScoreUM, modifier: Modifier = Mo @Composable internal fun SecurityScoreBlockPlaceholder(modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - SecurityScoreBlockPlaceholderV2(modifier) - } else { - SecurityScoreBlockPlaceholderV1(modifier) - } + SecurityScoreBlockPlaceholderV2(modifier) } @Composable @@ -167,103 +111,26 @@ private fun SecurityScoreBlockPlaceholderV2(modifier: Modifier = Modifier) { } } -@Composable -private fun SecurityScoreBlockPlaceholderV1(modifier: Modifier = Modifier) { - Row( - modifier = modifier - .clip(TangemTheme.shapes.roundedCornersXMedium) - .background(TangemTheme.colors.background.primary) - .fillMaxWidth() - .heightIn(max = TangemTheme.dimens.size72) - .padding(all = TangemTheme.dimens.spacing12), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, - ) { - Column( - modifier = Modifier - .fillMaxWidth(fraction = 0.4f) - .padding(vertical = TangemTheme.dimens.spacing2) - .fillMaxHeight(), - verticalArrangement = Arrangement.SpaceBetween, - ) { - TextShimmer( - modifier = Modifier.fillMaxWidth(), - style = TangemTheme.typography.subtitle2, - textSizeHeight = true, - ) - TextShimmer( - modifier = Modifier.fillMaxWidth(), - style = TangemTheme.typography.body2, - textSizeHeight = true, - ) - } - - TextShimmer( - modifier = Modifier.fillMaxWidth(fraction = 0.5f), - style = TangemTheme.typography.body2, - textSizeHeight = true, - ) - } -} - -@Preview(widthDp = 328, showBackground = true) -@Preview(widthDp = 328, showBackground = true, locale = "ru") -@Preview(widthDp = 328, showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun ContentPreviewV1() { - TangemThemePreview { - SecurityScoreBlock( - state = SecurityScoreUM( - score = 3.5f, - description = stringReference("Based on 3 ratings"), - onInfoClick = {}, - ), - ) - } -} - -@Preview(widthDp = 328, showBackground = true) -@Preview(widthDp = 328, showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun PreviewPlaceholderV1() { - TangemThemePreview { - PreviewShimmerContainer( - shimmerContent = { - SecurityScoreBlockPlaceholder( - modifier = Modifier.fillMaxWidth(), - ) - }, - actualContent = { - ContentPreviewV1() - }, - ) - } -} - @Preview(widthDp = 328, showBackground = true) @Preview(widthDp = 328, showBackground = true, locale = "ru") @Preview(widthDp = 328, showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable private fun ContentPreviewV2() { - CompositionLocalProvider( - LocalRedesignEnabled provides true, - ) { - TangemThemePreviewRedesign { - Column(modifier = Modifier.background(TangemTheme.colors2.surface.level2)) { - SecurityScoreBlock( - state = SecurityScoreUM( - score = 3.5f, - description = stringReference("Based on 3 ratings"), - onInfoClick = {}, - ), - ) + TangemThemePreviewRedesign { + Column(modifier = Modifier.background(TangemTheme.colors2.surface.level2)) { + SecurityScoreBlock( + state = SecurityScoreUM( + score = 3.5f, + description = stringReference("Based on 3 ratings"), + onInfoClick = {}, + ), + ) - SpacerH(10.dp) + SpacerH(10.dp) - SecurityScoreBlockPlaceholder( - modifier = Modifier.fillMaxWidth(), - ) - } + SecurityScoreBlockPlaceholder( + modifier = Modifier.fillMaxWidth(), + ) } } } \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/SecurityScoreBottomSheet.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/SecurityScoreBottomSheet.kt index 884352769f..e6284776bc 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/SecurityScoreBottomSheet.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/SecurityScoreBottomSheet.kt @@ -2,16 +2,12 @@ package com.tangem.features.feed.ui.market.detailed.components import android.content.res.Configuration import androidx.compose.foundation.* -import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Icon import androidx.compose.material3.Text -import androidx.compose.material3.ripple import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -25,30 +21,22 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.layoutId import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.util.fastForEach -import androidx.compose.ui.util.fastForEachIndexed import coil.compose.SubcomposeAsyncImage import coil.request.ImageRequest import com.tangem.core.ui.components.* import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetType -import com.tangem.core.ui.components.bottomsheets.sheet.TangemBottomSheet -import com.tangem.core.ui.components.bottomsheets.sheet.TangemBottomSheetTitle -import com.tangem.core.ui.components.inputrow.inner.DividerContainer -import com.tangem.core.ui.decorations.roundedShapeItemDecoration import com.tangem.core.ui.ds.row.TangemRowContainer import com.tangem.core.ui.ds.row.TangemRowLayoutId 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.resolveReference -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.res.TangemThemePreviewRedesign import com.tangem.features.feed.impl.R import com.tangem.features.feed.ui.market.detailed.preview.SecurityScorePreviewData @@ -57,58 +45,7 @@ import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet as TangemBot @Composable internal fun SecurityScoreBottomSheet(config: TangemBottomSheetConfig) { - if (LocalRedesignEnabled.current) { - SecurityScoreBottomSheetV2(config) - } else { - SecurityScoreBottomSheetV1(config) - } -} - -@Composable -private fun SecurityScoreBottomSheetV1(config: TangemBottomSheetConfig) { - val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() } - - TangemBottomSheet( - config = config, - addBottomInsets = false, - title = { TangemBottomSheetTitle(title = it.title) }, - content = { content -> - Column( - modifier = Modifier - .verticalScroll(rememberScrollState()) - .padding(horizontal = TangemTheme.dimens.spacing16), - ) { - Text( - text = content.description.resolveReference(), - style = TangemTheme.typography.body2.copy( - color = TangemTheme.colors.text.secondary, - ), - ) - - SpacerH12() - content.providers.fastForEachIndexed { index, provider -> - DividerContainer( - modifier = Modifier - .roundedShapeItemDecoration( - currentIndex = index, - lastIndex = content.providers.lastIndex, - addDefaultPadding = false, - ) - .background(TangemTheme.colors.background.action), - showDivider = index != content.providers.lastIndex, - ) { - SecurityScoreProviderRow( - providerUM = provider, - onLinkClick = { content.onProviderLinkClick(provider) }, - ) - } - } - - SpacerH16() - SpacerH(bottomBarHeight) - } - }, - ) + SecurityScoreBottomSheetV2(config) } @Composable @@ -167,74 +104,6 @@ private fun SecurityScoreBottomSheetV2(config: TangemBottomSheetConfig) { ) } -@Composable -private fun SecurityScoreProviderRow( - providerUM: SecurityScoreBottomSheetContent.SecurityScoreProviderUM, - onLinkClick: () -> Unit, -) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = TangemTheme.dimens.spacing12) - .heightIn(min = TangemTheme.dimens.size68), - verticalAlignment = Alignment.CenterVertically, - ) { - SubcomposeAsyncImage( - modifier = Modifier - .size(size = TangemTheme.dimens.size40) - .clip(TangemTheme.shapes.roundedCorners8), - model = ImageRequest.Builder(context = LocalContext.current) - .data(providerUM.iconUrl) - .crossfade(enable = true) - .allowHardware(false) - .build(), - loading = { RectangleShimmer(radius = TangemTheme.dimens.radius8) }, - error = { RectangleShimmer(radius = TangemTheme.dimens.radius8) }, - contentDescription = null, - ) - - Column( - modifier = Modifier.padding(start = TangemTheme.dimens.spacing12), - horizontalAlignment = Alignment.Start, - verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing4), - ) { - Text( - text = providerUM.name, - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.primary1, - ) - providerUM.lastAuditDate?.let { auditDate -> - Text( - text = auditDate, - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.tertiary, - ) - } - } - - SpacerWMax() - - Column( - horizontalAlignment = Alignment.End, - verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing4), - modifier = Modifier.clickable( - enabled = providerUM.urlData != null, - indication = ripple(bounded = false), - interactionSource = remember { MutableInteractionSource() }, - onClick = onLinkClick, - ), - ) { - ScoreStarsBlock( - score = providerUM.score, - scoreTextStyle = TangemTheme.typography.body2, - horizontalSpacing = TangemTheme.dimens.spacing3, - ) - - UrlBlockV1(providerUM) - } - } -} - @Composable private fun SecurityScoreProviderRowV2( providerUM: SecurityScoreBottomSheetContent.SecurityScoreProviderUM, @@ -305,34 +174,6 @@ private fun SecurityScoreProviderRowV2( } } -@Composable -private fun UrlBlockV1( - providerUM: SecurityScoreBottomSheetContent.SecurityScoreProviderUM, - modifier: Modifier = Modifier, -) { - val urlData = providerUM.urlData - val rootHost = urlData?.rootHost - if (urlData != null && rootHost != null) { - Row( - modifier = modifier, - horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing4), - ) { - Text( - text = urlData.rootHost, - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.tertiary, - ) - Icon( - modifier = Modifier - .size(TangemTheme.dimens.size16), - painter = painterResource(id = R.drawable.ic_arrow_top_right_24), - contentDescription = null, - tint = TangemTheme.colors.icon.informative, - ) - } - } -} - @Composable private fun UrlBlockV2( providerUM: SecurityScoreBottomSheetContent.SecurityScoreProviderUM, @@ -401,8 +242,8 @@ fun StarBlock(score: Float, modifier: Modifier = Modifier) { @Preview(showBackground = true, widthDp = 360) @Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable -private fun SecurityScoreBottomSheetPreviewV1() { - TangemThemePreview { +private fun SecurityScoreBottomSheetPreviewV2() { + TangemThemePreviewRedesign { SecurityScoreBottomSheet( config = TangemBottomSheetConfig( isShown = true, @@ -411,21 +252,4 @@ private fun SecurityScoreBottomSheetPreviewV1() { ), ) } -} - -@Preview(showBackground = true, widthDp = 360) -@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun SecurityScoreBottomSheetPreviewV2() { - TangemThemePreviewRedesign { - CompositionLocalProvider(LocalRedesignEnabled provides true) { - SecurityScoreBottomSheet( - config = TangemBottomSheetConfig( - isShown = true, - onDismissRequest = {}, - content = SecurityScorePreviewData.bottomSheetContent, - ), - ) - } - } } \ No newline at end of file diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/TokenMarketDetailsBody.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/TokenMarketDetailsBody.kt index 121f46303b..8f4dd1874e 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/TokenMarketDetailsBody.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/components/TokenMarketDetailsBody.kt @@ -11,9 +11,7 @@ import androidx.compose.ui.unit.dp import com.tangem.core.ui.components.UnableToLoadData import com.tangem.core.ui.components.items.DescriptionItem import com.tangem.core.ui.components.items.DescriptionPlaceholder -import com.tangem.core.ui.extensions.conditionalCompose import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.features.feed.impl.R import com.tangem.features.feed.ui.feed.components.NewsSlider @@ -22,79 +20,16 @@ import com.tangem.features.feed.ui.feed.state.NewsSliderConfig import com.tangem.features.feed.ui.market.detailed.state.MarketsTokenDetailsUM import com.tangem.features.feed.ui.market.detailed.state.MarketsTokenDetailsUM.RelatedNews -@Suppress("CanBeNonNullable") internal fun LazyListScope.tokenMarketDetailsBody( - isRedesignEnabled: Boolean, state: MarketsTokenDetailsUM.Body, - portfolioBlock: @Composable ((Modifier) -> Unit)?, relatedNews: RelatedNews, marketingBanner: @Composable (Modifier) -> Unit, ) { - if (isRedesignEnabled) { - tokenMarketDetailsBodyV2( - state = state, - relatedNews = relatedNews, - marketingBanner = marketingBanner, - ) - } else { - tokenMarketDetailsBodyV1( - state = state, - portfolioBlock = portfolioBlock, - relatedNews = relatedNews, - ) - } -} - -@Suppress("CanBeNonNullable") -private fun LazyListScope.tokenMarketDetailsBodyV1( - state: MarketsTokenDetailsUM.Body, - portfolioBlock: @Composable ((Modifier) -> Unit)?, - relatedNews: RelatedNews, -) { - when (state) { - MarketsTokenDetailsUM.Body.Loading -> { - item("description-loading") { - DescriptionPlaceholder(modifier = Modifier.blockPaddings()) - } - - if (portfolioBlock != null) { - item(key = "portfolio") { - portfolioBlock(Modifier.blockPaddings()) - } - } - - aboutCoinHeader() - - loadingInfoBlocks(false) - } - is MarketsTokenDetailsUM.Body.Content -> { - if (state.description != null) { - description(state.description) - } - - if (portfolioBlock != null) { - item(key = "portfolio") { - portfolioBlock(Modifier.blockPaddings()) - } - } - - if (relatedNews.articles.isNotEmpty()) { - relatedNews(relatedNews) - } else { - sectionStub(RelatedNews.SECTION_KEY) - } - - aboutCoinHeader() - - infoBlocksListV1(state = state.infoBlocks) - } - is MarketsTokenDetailsUM.Body.Error -> { - error(state) - } - MarketsTokenDetailsUM.Body.Nothing -> { - // Do nothing - } - } + tokenMarketDetailsBodyV2( + state = state, + relatedNews = relatedNews, + marketingBanner = marketingBanner, + ) } private fun LazyListScope.marketingBannerItem(marketingBanner: @Composable (Modifier) -> Unit) { @@ -125,7 +60,7 @@ private fun LazyListScope.tokenMarketDetailsBodyV2( DescriptionPlaceholder(modifier = Modifier.blockPaddings()) } - loadingInfoBlocks(true) + loadingInfoBlocks() } is MarketsTokenDetailsUM.Body.Content -> { if (state.description != null) { @@ -164,36 +99,12 @@ private fun LazyListScope.error(state: MarketsTokenDetailsUM.Body.Error) { } } -private fun LazyListScope.aboutCoinHeader() { - item("aboutCoinHeader") { - Text( - modifier = Modifier.padding( - start = TangemTheme.dimens.spacing16, - end = TangemTheme.dimens.spacing16, - bottom = TangemTheme.dimens.spacing20, - ), - text = stringResourceSafe(R.string.markets_about_coin_header), - color = TangemTheme.colors.text.primary1, - style = TangemTheme.typography.h3, - ) - } -} - private fun LazyListScope.description(description: MarketsTokenDetailsUM.Description) { item("description") { DescriptionItem( modifier = Modifier - .conditionalCompose( - condition = LocalRedesignEnabled.current, - modifier = { - this - .padding(horizontal = TangemTheme.dimens2.x4) - .padding(bottom = 24.dp) - }, - otherModifier = { - blockPaddings() - }, - ), + .padding(horizontal = TangemTheme.dimens2.x4) + .padding(bottom = 24.dp), description = description.shortDescription, hasFullDescription = description.fullDescription != null, onReadMoreClick = description.onReadMoreClick, @@ -201,60 +112,6 @@ private fun LazyListScope.description(description: MarketsTokenDetailsUM.Descrip } } -internal fun LazyListScope.infoBlocksListV1(state: MarketsTokenDetailsUM.InformationBlocks) { - if (state.insights != null) { - item("insights") { - InsightsBlock( - modifier = Modifier.blockPaddings(), - state = state.insights, - ) - } - } - - if (state.securityScore != null) { - item("securityScore") { - SecurityScoreBlock( - modifier = Modifier.blockPaddings(), - state = state.securityScore, - ) - } - } - - if (state.metrics != null) { - item("metrics") { - MetricsBlock( - modifier = Modifier.blockPaddings(), - state = state.metrics, - ) - } - } - - if (state.pricePerformance != null) { - item("pricePerformance") { - PricePerformanceBlock( - modifier = Modifier.blockPaddings(), - state = state.pricePerformance, - ) - } - } - - item(key = "listedOn") { - ListedOnBlock( - state = state.listedOn, - modifier = Modifier.blockPaddings(), - ) - } - - if (state.links != null) { - item("links") { - LinksBlock( - modifier = Modifier.blockPaddings(), - state = state.links, - ) - } - } -} - internal fun LazyListScope.infoBlocksListV2(state: MarketsTokenDetailsUM.InformationBlocks, relatedNews: RelatedNews) { if (state.metrics != null) { item("metrics") { @@ -306,40 +163,8 @@ internal fun LazyListScope.infoBlocksListV2(state: MarketsTokenDetailsUM.Informa } } -private fun LazyListScope.loadingInfoBlocks(isRedesignEnabled: Boolean) { - if (isRedesignEnabled) { - loadingInfoBlocksV2() - } else { - loadingInfoBlocksV1() - } -} - -private fun LazyListScope.loadingInfoBlocksV1() { - item("insights-loading") { - InsightsBlockPlaceholder( - modifier = Modifier.blockPaddings(), - ) - } - - item("securityScore-loading") { - SecurityScoreBlockPlaceholder(modifier = Modifier.blockPaddings()) - } - - item("metrics-loading") { - MetricsBlockPlaceholder(modifier = Modifier.blockPaddings()) - } - - item("pricePerformance-loading") { - PricePerformanceBlockPlaceholder(modifier = Modifier.blockPaddings()) - } - - item(key = "listedOn-loading") { - ListedOnBlockPlaceholder(modifier = Modifier.blockPaddings()) - } - - item("links-loading") { - LinksBlockPlaceholder(modifier = Modifier.blockPaddings()) - } +private fun LazyListScope.loadingInfoBlocks() { + loadingInfoBlocksV2() } private fun LazyListScope.loadingInfoBlocksV2() { @@ -364,41 +189,6 @@ private fun LazyListScope.loadingInfoBlocksV2() { } } -private fun LazyListScope.relatedNews(relatedNews: RelatedNews) { - item(RelatedNews.SECTION_KEY) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 32.dp, top = 20.dp) - .onFirstVisible( - minFractionVisible = 0.5f, - callback = relatedNews.onFirstVisible, - ), - verticalArrangement = Arrangement.spacedBy(12.dp), - ) { - Text( - modifier = Modifier.padding(start = 16.dp), - text = stringResourceSafe(R.string.news_related_news), - style = TangemTheme.typography.h3, - color = TangemTheme.colors.text.primary1, - ) - - NewsSlider( - NewsSliderConfig( - callbacks = NewsSliderCallbacks( - onOpenAllNews = {}, // not applicable here - onSliderScroll = relatedNews.onScroll, - onSliderEndReached = {}, // not applicable here - onArticleClick = relatedNews.onArticledClicked, - ), - content = relatedNews.articles, - shouldShowSeeAllNewsItem = false, - ), - ) - } - } -} - private fun LazyListScope.relatedNewsV2(relatedNews: RelatedNews) { item(RelatedNews.SECTION_KEY) { Column( @@ -436,15 +226,7 @@ private fun LazyListScope.relatedNewsV2(relatedNews: RelatedNews) { @Composable private fun Modifier.blockPaddings(): Modifier { - return if (LocalRedesignEnabled.current) { - this - .padding(horizontal = TangemTheme.dimens2.x4) - .padding(bottom = TangemTheme.dimens2.x2) - } else { - this.padding( - start = TangemTheme.dimens.spacing16, - end = TangemTheme.dimens.spacing16, - bottom = TangemTheme.dimens.spacing12, - ) - } + return this + .padding(horizontal = TangemTheme.dimens2.x4) + .padding(bottom = TangemTheme.dimens2.x2) } \ No newline at end of file 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 daf3816f77..72cdb7fa00 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 @@ -2,17 +2,12 @@ package com.tangem.features.feed.ui.market.list import android.content.res.Configuration import androidx.activity.compose.BackHandler -import androidx.compose.animation.AnimatedContent -import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.material3.Text import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawBehind -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.geometry.Offset import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalFocusManager @@ -22,17 +17,11 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.tangem.common.ui.markets.preview.MarketChartListItemPreviewDataProvider import com.tangem.core.ui.components.* -import com.tangem.core.ui.components.appbar.AppBarWithBackButtonAndIcon import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig -import com.tangem.core.ui.components.bottomsheets.state.BottomSheetState -import com.tangem.core.ui.components.fields.SearchBar -import com.tangem.core.ui.components.fields.TangemSearchBarDefaults import com.tangem.core.ui.components.fields.entity.SearchBarUM import com.tangem.core.ui.event.consumedEvent import com.tangem.core.ui.extensions.resourceReference -import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.res.LocalMainBottomSheetColor -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview import com.tangem.domain.models.currency.CryptoCurrency @@ -45,64 +34,6 @@ import com.tangem.features.feed.ui.market.list.components.MarketsListSortByBotto import com.tangem.features.feed.ui.market.list.components.Options import com.tangem.features.feed.ui.utils.FadeConstants.BASE_FADE_LEVEL import kotlinx.collections.immutable.toImmutableList -import kotlinx.coroutines.delay - -private const val DELAY_FOR_FOCUS_REQUEST = 500L - -@Composable -internal fun TopBarWithSearch( - onBackClick: () -> Unit, - onSearchClick: () -> Unit, - marketsSearchBar: MarketsSearchBar, - bottomSheetState: BottomSheetState = BottomSheetState.EXPANDED, -) { - val background = LocalMainBottomSheetColor.current.value - val focusRequester = remember { FocusRequester() } - - val shouldShowAppBar = !marketsSearchBar.shouldAlwaysShowSearchBar && - !marketsSearchBar.searchBarUM.isActive && - marketsSearchBar.searchBarUM.query.isEmpty() - - AnimatedContent( - targetState = shouldShowAppBar, - label = "TopBarTransition", - ) { showAppBar -> - if (showAppBar) { - AppBarWithBackButtonAndIcon( - onBackClick = onBackClick, - backButtonEnabled = bottomSheetState == BottomSheetState.EXPANDED, - endButtonEnabled = bottomSheetState == BottomSheetState.EXPANDED, - text = stringResourceSafe(R.string.markets_common_title), - iconRes = R.drawable.ic_search_24, - onIconClick = onSearchClick, - backgroundColor = background, - ) - } else { - SearchBar( - modifier = Modifier - .drawBehind { drawRect(background) } - .padding(horizontal = 16.dp) - .padding(bottom = 8.dp), - state = marketsSearchBar.searchBarUM, - colors = TangemSearchBarDefaults.defaultTextFieldColors.copy( - focusedContainerColor = TangemTheme.colors.field.focused, - unfocusedContainerColor = TangemTheme.colors.field.focused, - ), - focusRequester = focusRequester, - ) - - val shouldRequestFocus = - (marketsSearchBar.shouldAlwaysShowSearchBar || marketsSearchBar.searchBarUM.isActive) && - bottomSheetState == BottomSheetState.EXPANDED - if (shouldRequestFocus) { - LaunchedEffect(bottomSheetState) { - delay(DELAY_FOR_FOCUS_REQUEST) - focusRequester.requestFocus() - } - } - } - } -} @Composable internal fun MarketsList(contentPadding: PaddingValues, state: MarketsListUM, modifier: Modifier = Modifier) { @@ -121,77 +52,10 @@ internal fun MarketsList(contentPadding: PaddingValues, state: MarketsListUM, mo @Suppress("LongMethod") @Composable -private fun ColumnScope.Content(contentPadding: PaddingValues, state: MarketsListUM, modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - ContentV2( - contentPadding = contentPadding, - state = state, - ) - } else { - ContentV1( - contentPadding = contentPadding, - state = state, - modifier = modifier, - ) - } -} - -@Suppress("LongMethod") -@Composable -private fun ColumnScope.ContentV1(contentPadding: PaddingValues, state: MarketsListUM, modifier: Modifier = Modifier) { - val strokeColor = TangemTheme.colors.stroke.primary - val scrolledState = remember { mutableStateOf(false) } - Column(modifier.padding(horizontal = TangemTheme.dimens.size16)) { - SpacerH(contentPadding.calculateTopPadding()) - AnimatedVisibility( - visible = scrolledState.value.not() && - state.isInSearchMode && - state.marketsSearchBar.searchBarUM.query.isNotEmpty(), - ) { - Column { - SpacerH8() - Text( - text = stringResourceSafe(id = R.string.markets_search_result_title), - style = TangemTheme.typography.h3, - color = TangemTheme.colors.text.primary1, - ) - SpacerH12() - } - } - Column { - AnimatedVisibility(!state.isInSearchMode && !state.marketsSearchBar.shouldAlwaysShowSearchBar) { - Options( - modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing12), - sortByTypeUM = state.selectedSortBy, - trendInterval = state.selectedInterval, - onIntervalClick = state.onIntervalClick, - onSortByClick = state.onSortByButtonClick, - sortMenuUM = state.sortByMenuUM, - ) - } - } - } - val strokeWidth = TangemTheme.dimens.size0_5 - Box( - Modifier - .fillMaxWidth() - .height(strokeWidth) - .drawBehind { - // draw horizontal line - if (scrolledState.value) { - drawLine( - color = strokeColor, - start = Offset(0f, size.height), - end = Offset(size.width, size.height), - strokeWidth = strokeWidth.toPx(), - ) - } - }, - ) - ItemsList( - scrolledState = scrolledState, - isInSearchMode = state.isInSearchMode, - state = state.list, +private fun ColumnScope.Content(contentPadding: PaddingValues, state: MarketsListUM) { + ContentV2( + contentPadding = contentPadding, + state = state, ) } @@ -229,10 +93,8 @@ private fun ColumnScope.ContentV2(contentPadding: PaddingValues, state: MarketsL } } }, - sortByTypeUM = state.selectedSortBy, trendInterval = state.selectedInterval, onIntervalClick = state.onIntervalClick, - onSortByClick = state.onSortByButtonClick, sortMenuUM = state.sortByMenuUM, ) } diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/components/MarketsListLazyColumn.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/components/MarketsListLazyColumn.kt index 13eff7a17e..ac4bccd560 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/components/MarketsListLazyColumn.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/components/MarketsListLazyColumn.kt @@ -23,10 +23,8 @@ import com.tangem.core.ui.components.buttons.SmallButtonConfig import com.tangem.core.ui.components.list.InfiniteListHandler import com.tangem.core.ui.decorations.roundedShapeItemDecoration import com.tangem.core.ui.event.EventEffect -import com.tangem.core.ui.extensions.conditionalCompose import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.test.MarketsTestTags import com.tangem.domain.models.currency.CryptoCurrency @@ -46,7 +44,6 @@ internal fun MarketsListLazyColumn( modifier: Modifier = Modifier, topContentPadding: Dp = 0.dp, ) { - val isRedesignEnabled = LocalRedesignEnabled.current val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() } val coroutineScope = rememberCoroutineScope() @@ -105,16 +102,11 @@ internal fun MarketsListLazyColumn( key = { _, item -> item.getComposeKey() }, ) { index, item -> MarketsListItem( - modifier = Modifier.conditionalCompose( - condition = isRedesignEnabled, - modifier = { - roundedShapeItemDecoration( - currentIndex = index, - lastIndex = state.items.lastIndex, - backgroundColor = TangemTheme.colors2.surface.level3, - radius = TangemTheme.dimens2.x5, - ) - }, + modifier = Modifier.roundedShapeItemDecoration( + currentIndex = index, + lastIndex = state.items.lastIndex, + backgroundColor = TangemTheme.colors2.surface.level3, + radius = TangemTheme.dimens2.x5, ), model = item, onClick = { state.onItemClick(item) }, diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/components/Options.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/components/Options.kt index a69b65bd57..3851d5a1b1 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/components/Options.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/components/Options.kt @@ -1,16 +1,11 @@ package com.tangem.features.feed.ui.market.list.components import androidx.compose.foundation.layout.* -import androidx.compose.material3.Text import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.tangem.core.ui.components.buttons.SecondarySmallButton -import com.tangem.core.ui.components.buttons.SmallButtonConfig -import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition -import com.tangem.core.ui.components.buttons.segmentedbutton.SegmentedButtons import com.tangem.core.ui.components.haze.hazeEffectTangem import com.tangem.core.ui.ds.button.PrimaryInverseTangemButton import com.tangem.core.ui.ds.button.TangemButtonShape @@ -18,97 +13,28 @@ import com.tangem.core.ui.ds.button.TangemButtonSize import com.tangem.core.ui.ds.image.TangemIconUM import com.tangem.core.ui.ds.tabs.TangemSegmentUM import com.tangem.core.ui.ds.tabs.TangemSegmentedPicker -import com.tangem.core.ui.extensions.resolveReference import com.tangem.core.ui.haptic.TangemHapticEffect import com.tangem.core.ui.res.LocalHapticManager -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.features.feed.impl.R import com.tangem.features.feed.model.market.list.state.MarketsListUM import com.tangem.features.feed.model.market.list.state.SortByMenuUM -import com.tangem.features.feed.model.market.list.state.SortByTypeUM import kotlinx.collections.immutable.persistentListOf import com.tangem.core.ui.ds.button.TangemButtonIconPosition as RedesignTangemButtonIconPosition -@Suppress("LongParameterList") @Composable internal fun Options( sortMenuUM: SortByMenuUM, - sortByTypeUM: SortByTypeUM, trendInterval: MarketsListUM.TrendInterval, - onSortByClick: () -> Unit, onIntervalClick: (MarketsListUM.TrendInterval) -> Unit, modifier: Modifier = Modifier, ) { - if (LocalRedesignEnabled.current) { - OptionsV2( - sortMenuUM = sortMenuUM, - trendInterval = trendInterval, - onIntervalClick = onIntervalClick, - modifier = modifier, - ) - } else { - OptionsV1( - sortByTypeUM = sortByTypeUM, - trendInterval = trendInterval, - onSortByClick = onSortByClick, - onIntervalClick = onIntervalClick, - modifier = modifier, - ) - } -} - -@Composable -private fun OptionsV1( - sortByTypeUM: SortByTypeUM, - trendInterval: MarketsListUM.TrendInterval, - onSortByClick: () -> Unit, - onIntervalClick: (MarketsListUM.TrendInterval) -> Unit, - modifier: Modifier = Modifier, -) { - Row( - modifier = modifier - .height(IntrinsicSize.Max) - .fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - ) { - SecondarySmallButton( - config = SmallButtonConfig( - text = sortByTypeUM.text, - onClick = onSortByClick, - icon = TangemButtonIconPosition.End(iconResId = R.drawable.ic_chevron_24), - ), - ) - SegmentedButtons( - config = persistentListOf( - MarketsListUM.TrendInterval.H24, - MarketsListUM.TrendInterval.D7, - MarketsListUM.TrendInterval.M1, - ), - color = TangemTheme.colors.button.secondary, - initialSelectedItem = trendInterval, - onClick = onIntervalClick, - modifier = Modifier - .width(160.dp) - .fillMaxHeight(), - ) { - Box( - Modifier - .fillMaxSize() - .align(Alignment.Center) - .padding( - vertical = TangemTheme.dimens.spacing4, - ), - ) { - Text( - modifier = Modifier.align(Alignment.Center), - text = it.text.resolveReference(), - style = TangemTheme.typography.caption1, - color = TangemTheme.colors.text.primary1, - ) - } - } - } + OptionsV2( + sortMenuUM = sortMenuUM, + trendInterval = trendInterval, + onIntervalClick = onIntervalClick, + modifier = modifier, + ) } @Composable diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/NewsDetailsContent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/NewsDetailsContent.kt index 6e71c83a26..a2e75dc61d 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/NewsDetailsContent.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/NewsDetailsContent.kt @@ -13,7 +13,6 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.tangem.core.ui.components.UnableToLoadData -import com.tangem.core.ui.components.pager.PagerIndicator import com.tangem.core.ui.ds.TangemPagerIndicator import com.tangem.core.ui.ds.TangemPagerIndicatorColors import com.tangem.core.ui.res.* @@ -62,7 +61,6 @@ internal fun NewsDetailsContent(state: NewsDetailsUM, contentPadding: PaddingVal @Composable private fun Content(contentPadding: PaddingValues, state: NewsDetailsUM, background: Color) { - val isRedesignEnabled = LocalRedesignEnabled.current val pagerState = rememberPagerState( initialPage = state.selectedArticleIndex, pageCount = { state.articles.size }, @@ -106,56 +104,22 @@ private fun Content(contentPadding: PaddingValues, state: NewsDetailsUM, backgro ) } if (state.articles.size > 1) { - if (isRedesignEnabled) { - TangemPagerIndicator( - pagerState = pagerState, - modifier = Modifier - .align(Alignment.BottomCenter) - .windowInsetsPadding(WindowInsets.navigationBars), - colors = TangemPagerIndicatorColors.copy( - overlay = TangemTheme.colors2.tabs.backgroundSecondary.copy(PAGER_BG_ALPHA), - ), - hazeState = localHaze, - ) - } else { - PagerIndicator( - pagerState = pagerState, - modifier = Modifier - .align(Alignment.BottomCenter) - .windowInsetsPadding(WindowInsets.navigationBars), - ) - } + TangemPagerIndicator( + pagerState = pagerState, + modifier = Modifier + .align(Alignment.BottomCenter) + .windowInsetsPadding(WindowInsets.navigationBars), + colors = TangemPagerIndicatorColors.copy( + overlay = TangemTheme.colors2.tabs.backgroundSecondary.copy(PAGER_BG_ALPHA), + ), + hazeState = localHaze, + ) } } } } } -@Preview(showBackground = true, widthDp = 360) -@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun PreviewNewsDetailsContent() { - TangemThemePreview { - val background = TangemTheme.colors.background.tertiary - CompositionLocalProvider( - LocalMainBottomSheetColor provides remember { mutableStateOf(background) }, - ) { - NewsDetailsContent( - state = NewsDetailsUM( - articlesStateUM = ArticlesStateUM.Content, - articles = MockArticlesFactory.createMockArticles(), - selectedArticleIndex = 0, - onShareClick = {}, - onLikeClick = {}, - onBackClick = {}, - onArticleIndexChanged = {}, - ), - contentPadding = PaddingValues(), - ) - } - } -} - @Preview(showBackground = true, widthDp = 360) @Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/components/ArticleDetail.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/components/ArticleDetail.kt index d7fdd670cf..60f4e71223 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/components/ArticleDetail.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/components/ArticleDetail.kt @@ -11,16 +11,13 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.hapticfeedback.HapticFeedbackType import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.unit.dp import com.tangem.core.ui.R import com.tangem.core.ui.components.BottomFade -import com.tangem.core.ui.components.SecondaryButtonIconStart import com.tangem.core.ui.components.SpacerH -import com.tangem.core.ui.components.buttons.common.TangemButtonSize import com.tangem.core.ui.components.haze.hazeSourceTangem import com.tangem.core.ui.ds.button.SecondaryTangemButton import com.tangem.core.ui.ds.button.TangemButtonShape @@ -30,7 +27,6 @@ import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.res.LocalHazeState import com.tangem.core.ui.res.LocalMainBottomSheetColor -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.features.feed.ui.feed.components.articles.ArticleHeader import com.tangem.features.feed.ui.news.details.state.ArticleUM @@ -47,150 +43,14 @@ internal fun ArticleDetail( relatedTokensUM: RelatedTokensUM, modifier: Modifier = Modifier, ) { - if (LocalRedesignEnabled.current) { - ArticleDetailV2( - contentPadding = contentPadding, - article = article, - onLikeClick = onLikeClick, - relatedTokensUM = relatedTokensUM, - modifier = modifier, - hazeState = hazeState, - ) - } else { - ArticleDetailV1( - article = article, - onLikeClick = onLikeClick, - relatedTokensUM = relatedTokensUM, - modifier = modifier, - ) - } -} - -@Suppress("LongMethod") -@Composable -private fun ArticleDetailV1( - article: ArticleUM, - onLikeClick: () -> Unit, - relatedTokensUM: RelatedTokensUM, - modifier: Modifier = Modifier, -) { - val hapticFeedback = LocalHapticFeedback.current - val density = LocalDensity.current - val background = LocalMainBottomSheetColor.current.value - val pagerHeight = 32.dp - val contentPadding = pagerHeight + 56.dp + with(density) { - WindowInsets.navigationBars.getBottom(this).div(this.density) - }.dp - - Box(modifier = modifier) { - LazyColumn( - modifier = Modifier.fillMaxSize(), - contentPadding = PaddingValues(bottom = contentPadding), - ) { - item("content") { - ArticleHeader( - title = article.title, - createdAt = article.createdAt.resolveReference(), - score = article.score, - tags = article.tags, - isTrending = article.isTrending, - modifier = Modifier - .padding(top = 16.dp) - .padding(horizontal = 16.dp), - ) - - if (article.shortContent.isNotEmpty()) { - QuickRecap( - content = article.shortContent, - modifier = Modifier - .padding(top = 32.dp) - .padding(horizontal = 16.dp), - ) - } - - Text( - text = article.content, - style = TangemTheme.typography.body1, - color = TangemTheme.colors.text.primary1, - modifier = Modifier - .padding(top = 16.dp) - .padding(horizontal = 16.dp), - ) - - SpacerH(24.dp) - - SecondaryButtonIconStart( - modifier = Modifier.padding(horizontal = 16.dp), - iconResId = if (article.isLiked) { - R.drawable.ic_heart_filled_20 - } else { - R.drawable.ic_heart_20 - }, - iconTint = Color.Unspecified, - text = stringResourceSafe(R.string.news_like), - size = TangemButtonSize.RoundedAction, - onClick = { - hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress) - onLikeClick() - }, - ) - - RelatedTokensBlock( - relatedTokensUM = relatedTokensUM, - onItemClick = when (relatedTokensUM) { - is RelatedTokensUM.Content -> relatedTokensUM.onTokenClick - else -> null - }, - modifier = Modifier.padding(horizontal = 16.dp), - ) - - if (article.relatedArticles.isNotEmpty()) { - SpacerH(24.dp) - Row( - modifier = Modifier.padding(horizontal = 16.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp), - ) { - Text( - text = stringResourceSafe(R.string.news_sources), - style = TangemTheme.typography.h3, - color = TangemTheme.colors.text.primary1, - ) - Text( - text = "${article.relatedArticles.size}", - style = TangemTheme.typography.h3, - color = TangemTheme.colors.text.tertiary, - ) - } - } - } - - if (article.relatedArticles.isNotEmpty()) { - item("relatedArticles") { - LazyRow( - modifier = Modifier.padding(vertical = 12.dp), - state = rememberLazyListState(), - contentPadding = PaddingValues(horizontal = 16.dp), - horizontalArrangement = Arrangement.spacedBy(12.dp), - ) { - items( - items = article.relatedArticles, - key = RelatedArticleUM::id, - ) { article -> - RelatedNewsItem( - relatedArticle = article, - modifier = Modifier.fillParentMaxHeight(), - ) - } - } - } - } - } - BottomFade( - modifier = Modifier - .align(Alignment.BottomCenter), - backgroundColor = background, - ) - } + ArticleDetailV2( + contentPadding = contentPadding, + article = article, + onLikeClick = onLikeClick, + relatedTokensUM = relatedTokensUM, + modifier = modifier, + hazeState = hazeState, + ) } @Suppress("LongMethod") diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/components/NewsDetailsPlaceholder.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/components/NewsDetailsPlaceholder.kt index e102f1591a..3bfe466bf9 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/components/NewsDetailsPlaceholder.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/components/NewsDetailsPlaceholder.kt @@ -10,94 +10,12 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.tangem.core.ui.components.RectangleShimmer import com.tangem.core.ui.components.SpacerH -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.res.TangemThemePreviewRedesign @Composable fun NewsDetailsPlaceholder(contentPadding: PaddingValues, background: Color, modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - NewsDetailsPlaceholderV2(contentPadding, background, modifier) - } else { - NewsDetailsPlaceholderV1(background, modifier) - } -} - -@Suppress("LongMethod") -@Composable -private fun NewsDetailsPlaceholderV1(background: Color, modifier: Modifier = Modifier) { - Column( - modifier = modifier - .fillMaxSize() - .background(background) - .padding(16.dp), - ) { - RectangleShimmer(modifier = Modifier.size(width = 112.dp, height = 20.dp)) - SpacerH(8.dp) - RectangleShimmer( - modifier = Modifier - .fillMaxWidth() - .height(28.dp), - ) - SpacerH(4.dp) - RectangleShimmer(modifier = Modifier.size(height = 28.dp, width = 208.dp)) - SpacerH(20.dp) - RectangleShimmer(modifier = Modifier.size(height = 36.dp, width = 99.dp), radius = 12.dp) - SpacerH(32.dp) - Column( - modifier = Modifier.fillMaxWidth(), - verticalArrangement = Arrangement.spacedBy(8.dp), - ) { - RectangleShimmer( - modifier = Modifier - .fillMaxWidth() - .height(20.dp), - ) - RectangleShimmer( - modifier = Modifier - .fillMaxWidth() - .height(20.dp) - .padding(end = 30.dp), - ) - RectangleShimmer( - modifier = Modifier - .fillMaxWidth() - .height(20.dp) - .padding(end = 30.dp), - ) - RectangleShimmer( - modifier = Modifier - .fillMaxWidth() - .height(20.dp) - .padding(end = 24.dp), - ) - RectangleShimmer( - modifier = Modifier - .fillMaxWidth() - .height(20.dp) - .padding(end = 70.dp), - ) - RectangleShimmer( - modifier = Modifier - .fillMaxWidth() - .height(20.dp) - .padding(end = 30.dp), - ) - RectangleShimmer( - modifier = Modifier - .fillMaxWidth() - .height(20.dp) - .padding(end = 96.dp), - ) - RectangleShimmer( - modifier = Modifier - .fillMaxWidth() - .height(20.dp) - .padding(end = 100.dp), - ) - } - } + NewsDetailsPlaceholderV2(contentPadding, background, modifier) } @Suppress("LongMethod") @@ -183,18 +101,6 @@ private fun NewsDetailsPlaceholderV2(contentPadding: PaddingValues, background: } } -@Preview(showBackground = true, widthDp = 360) -@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun NewsDetailsPlaceholderPreviewV1() { - TangemThemePreview { - NewsDetailsPlaceholder( - background = TangemTheme.colors.background.tertiary, - contentPadding = PaddingValues(), - ) - } -} - @Preview(showBackground = true, widthDp = 360) @Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/components/QuickRecap.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/components/QuickRecap.kt index 5730440a49..087cc16dd3 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/components/QuickRecap.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/components/QuickRecap.kt @@ -2,7 +2,6 @@ package com.tangem.features.feed.ui.news.details.components import androidx.compose.foundation.Image import androidx.compose.foundation.layout.* -import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.material3.VerticalDivider import androidx.compose.runtime.Composable @@ -11,66 +10,22 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.withStyle import androidx.compose.ui.tooling.preview.Preview -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.SpacerW import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreviewRedesign @Composable internal fun QuickRecap(content: String, modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - QuickRecapV2(content, modifier) - } else { - QuickRecapV1(content, modifier) - } -} - -@Composable -private fun QuickRecapV1(content: String, modifier: Modifier = Modifier) { - Box( - modifier = modifier.height(IntrinsicSize.Min), - ) { - VerticalDivider( - modifier = Modifier - .fillMaxHeight() - .padding(start = 8.dp), - thickness = 2.dp, - color = TangemTheme.colors.stroke.primary, - ) - Column(modifier = Modifier.padding(start = 20.dp)) { - Row(verticalAlignment = Alignment.CenterVertically) { - Icon( - painter = painterResource(id = R.drawable.ic_quick_recap_16), - contentDescription = null, - tint = TangemTheme.colors.icon.accent, - modifier = Modifier.size(20.dp), - ) - Spacer(modifier = Modifier.width(8.dp)) - Text( - text = stringResourceSafe(R.string.news_quick_recap), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.accent, - ) - } - Spacer(modifier = Modifier.height(12.dp)) - Text( - text = content, - style = TangemTheme.typography.body1, - color = TangemTheme.colors.text.primary1, - ) - } - } + QuickRecapV2(content, modifier) } @Composable diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/components/RelatedNewsItem.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/components/RelatedNewsItem.kt index f99d0eff17..f9fd9d617f 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/components/RelatedNewsItem.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/components/RelatedNewsItem.kt @@ -24,87 +24,12 @@ import com.tangem.core.ui.components.SpacerH import com.tangem.core.ui.components.SpacerHMax import com.tangem.core.ui.components.SpacerW import com.tangem.core.ui.extensions.resolveReference -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.features.feed.ui.news.details.state.RelatedArticleUM @Composable internal fun RelatedNewsItem(relatedArticle: RelatedArticleUM, modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - RelatedNewsItemV2(relatedArticle, modifier) - } else { - RelatedNewsItemV1(relatedArticle, modifier) - } -} - -@Composable -private fun RelatedNewsItemV1(relatedArticle: RelatedArticleUM, modifier: Modifier = Modifier) { - Column( - modifier = modifier - .sizeIn(maxWidth = 256.dp, minHeight = 132.dp) - .background(color = TangemTheme.colors.background.action, shape = RoundedCornerShape(12.dp)) - .clickable(onClick = relatedArticle.onClick) - .padding(12.dp), - ) { - Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { - Column(modifier = Modifier.weight(1f)) { - Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(bottom = 4.dp)) { - Icon( - painter = painterResource(id = R.drawable.ic_explore_16), - contentDescription = null, - tint = TangemTheme.colors.icon.informative, - modifier = Modifier.size(16.dp), - ) - SpacerW(4.dp) - Text( - text = relatedArticle.media.name, - style = TangemTheme.typography.caption1, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - color = TangemTheme.colors.text.tertiary, - ) - } - if (relatedArticle.title.isNotEmpty()) { - SpacerH(4.dp) - Text( - text = relatedArticle.title, - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.primary1, - maxLines = 3, - overflow = TextOverflow.Ellipsis, - ) - } - } - if (relatedArticle.imageUrl != null) { - SubcomposeAsyncImage( - modifier = Modifier - .size(40.dp) - .clip(RoundedCornerShape(4.dp)), - contentScale = ContentScale.Crop, - model = ImageRequest.Builder(context = LocalContext.current) - .data(relatedArticle.imageUrl) - .crossfade(enable = false) - .allowHardware(true) - .memoryCachePolicy(CachePolicy.DISABLED) - .build(), - loading = { - RectangleShimmer( - modifier = Modifier.size(40.dp), - radius = 4.dp, - ) - }, - error = {}, - contentDescription = relatedArticle.media.name, - ) - } - } - SpacerHMax() - Text( - text = relatedArticle.publishedAt.resolveReference(), - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.tertiary, - ) - } + RelatedNewsItemV2(relatedArticle, modifier) } @Suppress("LongMethod") diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/components/RelatedTokensBlock.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/components/RelatedTokensBlock.kt index 8013858af1..270a202046 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/components/RelatedTokensBlock.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/details/components/RelatedTokensBlock.kt @@ -10,17 +10,13 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp import androidx.compose.ui.util.fastForEach import com.tangem.common.ui.markets.MarketsListItem import com.tangem.common.ui.markets.MarketsListItemPlaceholder import com.tangem.common.ui.markets.models.MarketsListItemUM import com.tangem.core.ui.R import com.tangem.core.ui.components.SpacerH -import com.tangem.core.ui.components.block.BlockCard -import com.tangem.core.ui.components.block.TangemBlockCardColors import com.tangem.core.ui.extensions.stringResourceSafe -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.features.feed.model.news.details.NewsDetailsModel.Companion.RELATED_TOKEN_MAX_COUNT import com.tangem.features.feed.ui.news.details.state.RelatedTokensUM @@ -31,69 +27,11 @@ internal fun RelatedTokensBlock( onItemClick: ((MarketsListItemUM) -> Unit)?, modifier: Modifier = Modifier, ) { - if (LocalRedesignEnabled.current) { - RelatedTokensBlockV2( - relatedTokensUM = relatedTokensUM, - onItemClick = onItemClick, - modifier = modifier, - ) - } else { - RelatedTokensBlockV1( - relatedTokensUM = relatedTokensUM, - onItemClick = onItemClick, - modifier = modifier, - ) - } -} - -@Composable -internal fun RelatedTokensBlockV1( - relatedTokensUM: RelatedTokensUM, - onItemClick: ((MarketsListItemUM) -> Unit)?, - modifier: Modifier = Modifier, -) { - val isVisible = remember(relatedTokensUM) { - when (relatedTokensUM) { - is RelatedTokensUM.Content -> relatedTokensUM.items.isNotEmpty() - RelatedTokensUM.Loading -> true - RelatedTokensUM.LoadingError -> false - } - } - - if (!isVisible) return - - Column(modifier = modifier) { - SpacerH(40.dp) - Text( - text = stringResourceSafe(R.string.news_related_tokens), - style = TangemTheme.typography.h3, - color = TangemTheme.colors.text.primary1, - ) - SpacerH(12.dp) - - BlockCard( - colors = TangemBlockCardColors.copy(containerColor = TangemTheme.colors.background.action), - ) { - Column(modifier = Modifier.fillMaxWidth()) { - when (relatedTokensUM) { - is RelatedTokensUM.Content -> { - relatedTokensUM.items.fastForEach { marketsListItemUM -> - MarketsListItem( - model = marketsListItemUM, - onClick = { onItemClick?.invoke(marketsListItemUM) }, - ) - } - } - RelatedTokensUM.Loading -> { - repeat(RELATED_TOKEN_MAX_COUNT) { - MarketsListItemPlaceholder() - } - } - RelatedTokensUM.LoadingError -> Unit - } - } - } - } + RelatedTokensBlockV2( + relatedTokensUM = relatedTokensUM, + onItemClick = onItemClick, + modifier = modifier, + ) } @Composable diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/list/NewsListContent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/list/NewsListContent.kt index 89557b63a8..0131495335 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/list/NewsListContent.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/list/NewsListContent.kt @@ -13,16 +13,13 @@ import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.tangem.core.ui.components.SpacerH import com.tangem.core.ui.components.TopFade -import com.tangem.core.ui.components.chip.Chip import com.tangem.core.ui.components.chip.entity.ChipUM import com.tangem.core.ui.components.label.entity.LabelUM import com.tangem.core.ui.ds.tabs.TangemTab import com.tangem.core.ui.event.EventEffect import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.res.LocalMainBottomSheetColor -import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview import com.tangem.features.feed.ui.feed.components.articles.ArticleConfigUM @@ -36,57 +33,11 @@ import kotlinx.collections.immutable.toImmutableSet @Composable internal fun NewsListContent(contentPadding: PaddingValues, state: NewsListUM, modifier: Modifier = Modifier) { - if (LocalRedesignEnabled.current) { - NewsListContentV2( - contentPadding = contentPadding, - state = state, - modifier = modifier, - ) - } else { - NewsListContentV1( - contentPadding = contentPadding, - state = state, - modifier = modifier, - ) - } -} - -@Composable -internal fun NewsListContentV1(contentPadding: PaddingValues, state: NewsListUM, modifier: Modifier = Modifier) { - val background = LocalMainBottomSheetColor.current.value - val lazyListState = rememberLazyListState() - val chipsListState = rememberLazyListState() - - ScrollChipsToSelected(state = state, chipsListState = chipsListState) - - Column( - modifier = modifier - .fillMaxSize() - .background(background), - ) { - SpacerH(contentPadding.calculateTopPadding()) - LazyRow( - state = chipsListState, - contentPadding = PaddingValues(horizontal = 16.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp), - ) { - items( - items = state.filters, - key = { it.id }, - ) { filter -> - Chip(state = filter) - } - } - - SpacerH(16.dp) - - NewsListLazyColumn( - newsListState = state.newsListState, - listOfArticles = state.listOfArticles, - lazyListState = lazyListState, - onArticleClick = state.onArticleClick, - ) - } + NewsListContentV2( + contentPadding = contentPadding, + state = state, + modifier = modifier, + ) } @Composable diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/list/components/NewsListLazyColumn.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/list/components/NewsListLazyColumn.kt index d9262be19c..4ca9919700 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/list/components/NewsListLazyColumn.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/news/list/components/NewsListLazyColumn.kt @@ -19,9 +19,7 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.tangem.core.ui.components.SpacerH import com.tangem.core.ui.components.UnableToLoadData -import com.tangem.core.ui.components.block.TangemBlockCardColors import com.tangem.core.ui.components.list.InfiniteListHandler -import com.tangem.core.ui.res.TangemTheme import com.tangem.features.feed.ui.feed.components.articles.ArticleCard import com.tangem.features.feed.ui.feed.components.articles.ArticleConfigUM import com.tangem.features.feed.ui.feed.components.articles.DefaultLoadingArticle @@ -121,7 +119,6 @@ private fun Content( modifier = Modifier .heightIn(min = 152.dp) .fillMaxWidth(), - colors = TangemBlockCardColors.copy(containerColor = TangemTheme.colors.background.action), articleConfigUM = article, onArticleClick = { onArticleClick(article.id) diff --git a/features/feed/impl/src/test/kotlin/com/tangem/features/feed/model/feed/FeedComponentModelTest.kt b/features/feed/impl/src/test/kotlin/com/tangem/features/feed/model/feed/FeedComponentModelTest.kt index 4b8c0e9f6c..ce4795c2f0 100644 --- a/features/feed/impl/src/test/kotlin/com/tangem/features/feed/model/feed/FeedComponentModelTest.kt +++ b/features/feed/impl/src/test/kotlin/com/tangem/features/feed/model/feed/FeedComponentModelTest.kt @@ -6,7 +6,6 @@ import com.google.common.truth.Truth.assertThat import com.tangem.common.routing.AppRouter import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.decompose.model.MutableParamsContainer -import com.tangem.core.ui.DesignFeatureToggles import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.earn.usecase.FetchTopEarnTokensUseCase @@ -49,7 +48,6 @@ internal class FeedComponentModelTest { private val fetchTopEarnTokensUseCase: FetchTopEarnTokensUseCase = mockk(relaxed = true) private val getTopEarnTokensUseCase: GetTopEarnTokensUseCase = mockk() private val appRouter: AppRouter = mockk(relaxed = true) - private val designFeatureToggles: DesignFeatureToggles = mockk() private val addToPortfolioManagerFactory: AddToPortfolioManager.Factory = mockk(relaxed = true) private val getTopFiveMarketTokenUseCase: GetTopFiveMarketTokenUseCase = mockk(relaxed = true) private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase = mockk() @@ -89,7 +87,6 @@ internal class FeedComponentModelTest { every { getSelectedAppCurrencyUseCase() } returns flowOf(Either.Right(AppCurrency.Default)) every { manageTrendingNewsUseCase.observeTrendingNews() } returns emptyFlow() every { getTopEarnTokensUseCase() } returns emptyFlow() - every { designFeatureToggles.isRedesignEnabled } returns false val paramsContainer = MutableParamsContainer(FeedParams(feedClickIntents = feedClickIntents)) @@ -102,7 +99,6 @@ internal class FeedComponentModelTest { fetchTopEarnTokensUseCase = fetchTopEarnTokensUseCase, getTopEarnTokensUseCase = getTopEarnTokensUseCase, appRouter = appRouter, - designFeatureToggles = designFeatureToggles, addToPortfolioManagerFactory = addToPortfolioManagerFactory, forYouFeatureToggles = forYouFeatureToggles, getTopFiveMarketTokenUseCase = getTopFiveMarketTokenUseCase,