diff --git a/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/tokenselector/SingleUserAssetItem.kt b/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/tokenselector/SingleUserAssetItem.kt index 62d8e486f5..0347e87447 100644 --- a/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/tokenselector/SingleUserAssetItem.kt +++ b/common/ui-markets/src/main/kotlin/com/tangem/common/ui/markets/tokenselector/SingleUserAssetItem.kt @@ -2,7 +2,10 @@ package com.tangem.common.ui.markets.tokenselector import androidx.compose.animation.AnimatedContent import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.remember @@ -10,7 +13,6 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.layout.layoutId import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp import com.tangem.core.ui.components.marketprice.PriceChangeInPercent import com.tangem.core.ui.components.marketprice.PriceChangeState import com.tangem.core.ui.ds.image.TangemIcon @@ -26,8 +28,8 @@ fun SingleUserAssetItem(shouldUsePriceBlock: Boolean, item: UserAssetItemUM.Sing TangemIcon( modifier = Modifier .layoutId(layoutId = TangemRowLayoutId.HEAD) - .size(40.dp) - .padding(end = TangemTheme.dimens2.x1), + .padding(end = TangemTheme.dimens2.x3) + .size(TangemTheme.dimens2.x10), tangemIconUM = item.icon, ) diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/account/AccountIcon.kt b/core/ui/src/main/java/com/tangem/core/ui/components/account/AccountIcon.kt index 38674b5788..0d2a37f3fd 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/account/AccountIcon.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/account/AccountIcon.kt @@ -46,7 +46,7 @@ enum class AccountIconSize { @Composable fun AccountResIcon(@DrawableRes resId: Int, color: Color, size: AccountIconSize, modifier: Modifier = Modifier) { val boxSize by animateDpAsState( - targetValue = size.boxSizeInDp(), + targetValue = size.toBoxSize(), animationSpec = animation(), ) val boxShapeCornerSize by animateDpAsState( @@ -84,7 +84,7 @@ fun AccountResIcon(@DrawableRes resId: Int, color: Color, size: AccountIconSize, @Composable fun PaymentAccountIcon(size: AccountIconSize, modifier: Modifier = Modifier) { val boxSize by animateDpAsState( - targetValue = size.boxSizeInDp(), + targetValue = size.toBoxSize(), animationSpec = animation(), ) val boxShapeCornerSize by animateDpAsState( @@ -115,7 +115,7 @@ fun PaymentAccountIcon(size: AccountIconSize, modifier: Modifier = Modifier) { @Composable fun AccountCharIcon(char: Char, color: Color, size: AccountIconSize, modifier: Modifier = Modifier) { val boxSize by animateDpAsState( - size.boxSizeInDp(), + size.toBoxSize(), animationSpec = animation(), ) val boxShapeCornerSize by animateDpAsState( @@ -163,7 +163,7 @@ private fun AccountIconSize.iconSizeInDp(): Dp = when (this) { AccountIconSize.RedesignedDefault -> 20.dp } -private fun AccountIconSize.boxSizeInDp(): Dp = when (this) { +fun AccountIconSize.toBoxSize(): Dp = when (this) { AccountIconSize.Default -> 36.dp AccountIconSize.Large -> 88.dp AccountIconSize.Medium -> 28.dp diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/currency/icon/CurrencyIcon.kt b/core/ui/src/main/java/com/tangem/core/ui/components/currency/icon/CurrencyIcon.kt index c0e1f4704f..a303ff1acc 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/currency/icon/CurrencyIcon.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/currency/icon/CurrencyIcon.kt @@ -19,10 +19,49 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.tangem.core.ui.components.CircleShimmer import com.tangem.core.ui.extensions.conditional +import com.tangem.core.ui.res.LocalRedesignEnabled import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.test.TokenElementsTestTags import com.tangem.core.ui.utils.getGreyScaleColorFilter +/** + * Cryptocurrency icon driven entirely by the supplied [modifier]: the icon and the network badge + * lay out within the size set by the modifier — !!!no fixed icon/badge size params!!!. + * Use the more configurable [CurrencyIcon] when custom sizing is required. + */ +@Composable +fun TangemCurrencyIcon(state: CurrencyIconState, modifier: Modifier = Modifier, shouldDisplayNetwork: Boolean = true) { + Box(modifier = modifier) { + val iconModifier = Modifier.matchParentSize() + + when (state) { + is CurrencyIconState.Loading -> LoadingIcon(modifier = iconModifier) + is CurrencyIconState.Locked -> LockedIcon(modifier = iconModifier) + is CurrencyIconState.Empty -> EmptyIcon(resId = state.resId, modifier = iconModifier) + is CurrencyIconState.CoinIcon, + is CurrencyIconState.FiatIcon, + is CurrencyIconState.CustomTokenIcon, + is CurrencyIconState.TokenIcon, + is CurrencyIconState.PaymentAccount, + is CurrencyIconState.CryptoPortfolio.Icon, + is CurrencyIconState.CryptoPortfolio.Letter, + -> { + ContentIconContainer( + icon = state, + modifier = iconModifier, + shouldShowTopBadge = shouldDisplayNetwork, + networkBadgeSize = 14.dp, + networkBadgeBackground = if (LocalRedesignEnabled.current) { + TangemTheme.colors2.surface.level1 + } else { + TangemTheme.colors.background.primary + }, + ) + } + } + } +} + /** * Cryptocurrency icon with network badge * diff --git a/core/ui/src/main/java/com/tangem/core/ui/ds/image/TangemIconUM.kt b/core/ui/src/main/java/com/tangem/core/ui/ds/image/TangemIconUM.kt index 86bf70b0c4..2a6dc14bdc 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/ds/image/TangemIconUM.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/ds/image/TangemIconUM.kt @@ -16,8 +16,8 @@ import androidx.compose.ui.res.vectorResource import coil.compose.SubcomposeAsyncImage import coil.request.ImageRequest import com.tangem.core.ui.components.CircleShimmer -import com.tangem.core.ui.components.currency.icon.CurrencyIcon import com.tangem.core.ui.components.currency.icon.CurrencyIconState +import com.tangem.core.ui.components.currency.icon.TangemCurrencyIcon import com.tangem.core.ui.components.icons.identicon.IdentIcon import com.tangem.core.ui.extensions.ColorReference2 import com.tangem.core.ui.res.TangemTheme @@ -69,7 +69,7 @@ sealed interface TangemIconUM { fun TangemIcon(tangemIconUM: TangemIconUM, modifier: Modifier = Modifier) { when (tangemIconUM) { is TangemIconUM.Currency -> { - CurrencyIcon( + TangemCurrencyIcon( state = tangemIconUM.currencyIconState, modifier = modifier, ) 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 2c3c85e529..a9d942b51e 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 @@ -87,7 +87,7 @@ internal class MarketsTokenDetailsModel @Inject constructor( getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase, getUserCountryUseCase: GetUserCountryUseCase, paramsContainer: ParamsContainer, - private val addToPortfolioManagerFactory: AddToPortfolioManager.Factory, + addToPortfolioManagerFactory: AddToPortfolioManager.Factory, private val designFeatureToggles: DesignFeatureToggles, private val getTokenPriceChartUseCase: GetTokenPriceChartUseCase, private val getTokenMarketInfoUseCase: GetTokenMarketInfoUseCase, @@ -247,6 +247,7 @@ internal class MarketsTokenDetailsModel @Inject constructor( val state = MutableStateFlow( MarketsTokenDetailsUM( tokenName = params.token.name, + symbol = params.token.symbol, priceText = params.token.tokenQuotes.currentPrice.format { fiat( fiatCurrencyCode = currentAppCurrency.value.code, 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 d0bf1b73b9..b086f0a2f4 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 @@ -21,6 +21,7 @@ import com.tangem.core.ui.extensions.conditionalCompose 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.contentFeedEntryStackAnimation @@ -138,7 +139,9 @@ private fun EntryContentV2( }, ) .hazeSourceTangem(zIndex = 0f, state = hazeState), - contentPadding = PaddingValues(top = topBarHeight), + contentPadding = PaddingValues( + top = if (isOpenedInBottomSheet) topBarHeight else TangemTheme.dimens2.x2_5, + ), bottomSheetState = bottomSheetState, ) } 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 ffdf82486b..fe24ef79ea 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 @@ -266,13 +266,13 @@ private fun LazyListScope.bestOpportunitiesItemsV2(state: EarnBestOpportunitiesU is EarnBestOpportunitiesUM.Empty -> { item(key = "best_opportunities_empty") { SpacerH(12.dp) - BestOpportunitiesEmpty() // TODO in [REDACTED_TASK_KEY] + BestOpportunitiesEmpty() } } is EarnBestOpportunitiesUM.EmptyFiltered -> { item(key = "best_opportunities_empty_filtered") { SpacerH(12.dp) - BestOpportunitiesEmptyFiltered(onClearFilterClick = state.onClearFilterClick) // TODO in [REDACTED_TASK_KEY] + BestOpportunitiesEmptyFiltered(onClearFilterClick = state.onClearFilterClick) } } is EarnBestOpportunitiesUM.Content -> { @@ -305,7 +305,7 @@ private fun LazyListScope.bestOpportunitiesItemsV2(state: EarnBestOpportunitiesU color = TangemTheme.colors2.surface.level3, shape = RoundedCornerShape(TangemTheme.dimens2.x5), ) - .padding(vertical = 142.dp, horizontal = 114.dp), + .padding(vertical = 142.dp, horizontal = 16.dp), contentAlignment = Alignment.Center, ) { UnableToLoadData(onRetryClick = state.onRetryClicked) 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 eaee4b4be9..2eac5ad631 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 @@ -85,7 +85,7 @@ private fun BestOpportunitiesEmptyV2(modifier: Modifier = Modifier) { Text( modifier = Modifier.padding(horizontal = TangemTheme.dimens2.x8), text = stringResourceSafe(R.string.earn_empty), - style = TangemTheme.typography2.bodyRegular14, + style = TangemTheme.typography2.subheadlineMedium14, color = TangemTheme.colors2.text.neutral.secondary, textAlign = TextAlign.Center, ) 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 87314ee2f0..755b7df0a2 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 @@ -44,7 +44,7 @@ private fun BestOpportunitiesEmptyFilteredV2(onClearFilterClick: () -> Unit, mod ) { Text( text = stringResourceSafe(R.string.earn_no_results), - style = TangemTheme.typography2.bodyRegular14, + style = TangemTheme.typography2.subheadlineMedium14, color = TangemTheme.colors2.text.neutral.secondary, ) SpacerH(TangemTheme.dimens2.x2) 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 50ffe3073a..bb5e5b99d4 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 @@ -175,13 +175,15 @@ private fun NetworksTypesBlock( overflow = TextOverflow.Ellipsis, ) - TangemCheckbox( - modifier = Modifier - .padding(start = 8.dp) - .layoutId(layoutId = TangemRowLayoutId.TAIL), - isChecked = item.isSelected, - onCheckedChange = { onOptionClick(item) }, - ) + if (item.isSelected) { + TangemCheckbox( + modifier = Modifier + .padding(start = 8.dp) + .layoutId(layoutId = TangemRowLayoutId.TAIL), + isChecked = true, + onCheckedChange = { onOptionClick(item) }, + ) + } } } } @@ -233,13 +235,15 @@ private fun SpecificNetworksBlock( overflow = TextOverflow.Ellipsis, ) - TangemCheckbox( - modifier = Modifier - .padding(start = 8.dp) - .layoutId(layoutId = TangemRowLayoutId.TAIL), - isChecked = item.isSelected, - onCheckedChange = { onOptionClick(item) }, - ) + if (item.isSelected) { + TangemCheckbox( + modifier = Modifier + .padding(start = 8.dp) + .layoutId(layoutId = TangemRowLayoutId.TAIL), + isChecked = true, + onCheckedChange = { onOptionClick(item) }, + ) + } } } } 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 66ead3805f..b4b2932dca 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 @@ -115,7 +115,8 @@ private fun EarnListItemV2(item: EarnListItemUM, modifier: Modifier = Modifier) tangemIconUM = TangemIconUM.Currency(item.currencyIconState), modifier = Modifier .layoutId(layoutId = TangemRowLayoutId.HEAD) - .padding(end = TangemTheme.dimens2.x2), + .padding(end = TangemTheme.dimens2.x2) + .size(TangemTheme.dimens2.x10), ) TokenTitle( 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 e1e90b4328..9d3c18477f 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 @@ -15,10 +15,10 @@ 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.ds.opportunities.OpportunitiesBG 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.TangemIconUM +import com.tangem.core.ui.ds.opportunities.OpportunitiesBG import com.tangem.core.ui.extensions.resolveReference import com.tangem.core.ui.extensions.stringReference import com.tangem.core.ui.res.* @@ -53,10 +53,10 @@ private fun MostlyUsedCardV2(item: EarnListItemUM, onClick: () -> Unit, modifier ) { Column(modifier = Modifier.padding(12.dp)) { CurrencyIcon( - modifier = Modifier.size(32.dp), state = item.currencyIconState, shouldDisplayNetwork = true, - networkBadgeSize = 12.dp, + networkBadgeSize = TangemTheme.dimens2.x4, + iconSize = TangemTheme.dimens2.x10, networkBadgeBackground = TangemTheme.colors.background.action, ) 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 b84d7cde77..d9dd9222f6 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 @@ -118,12 +118,7 @@ private fun Content( contentPadding = PaddingValues(bottom = bottomBarHeight, top = contentPadding.calculateTopPadding()), ) { item("header") { - Header( - state = state, - modifier = Modifier - .padding(horizontal = TangemTheme.dimens.spacing16) - .fillMaxWidth(), - ) + Header(state = state) } item { if (isRedesignEnabled) SpacerH(TangemTheme.dimens2.x3) else SpacerH16() @@ -202,15 +197,33 @@ internal fun MarketsTokenDetailsTopBar( } @Composable -private fun Header(state: MarketsTokenDetailsUM, modifier: Modifier = Modifier) { +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)) { - TokenPriceText( + TokenPriceTextV1( price = state.priceText, - priceAnnotated = state.priceAnnotated, triggerPriceChange = state.triggerPriceChange, ) Row(horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing4)) { @@ -240,23 +253,55 @@ private fun Header(state: MarketsTokenDetailsUM, modifier: Modifier = Modifier) } @Composable -private fun TokenPriceText( - price: String, - triggerPriceChange: StateEvent, - priceAnnotated: TextReference, - modifier: Modifier = Modifier, -) { - if (LocalRedesignEnabled.current) { - TokenPriceTextV2( - priceAnnotated = priceAnnotated, - triggerPriceChange = triggerPriceChange, - modifier = modifier, - ) - } else { - TokenPriceTextV1( - price = price, - triggerPriceChange = triggerPriceChange, - modifier = modifier, +private fun HeaderV2(state: MarketsTokenDetailsUM, modifier: Modifier = Modifier) { + Row( + modifier = modifier, + horizontalArrangement = Arrangement.SpaceBetween, + ) { + Column(modifier = Modifier.weight(1f)) { + Row( + verticalAlignment = Alignment.Bottom, + horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1), + ) { + Text( + text = state.tokenName, + style = TangemTheme.typography2.bodySemibold16, + color = TangemTheme.colors2.text.neutral.primary, + ) + Text( + text = state.symbol, + style = TangemTheme.typography2.captionMedium12, + color = TangemTheme.colors2.text.neutral.tertiary, + ) + } + SpacerH(TangemTheme.dimens2.x1) + TokenPriceTextV2( + priceAnnotated = state.priceAnnotated, + triggerPriceChange = state.triggerPriceChange, + ) + SpacerH(TangemTheme.dimens2.x4) + Row(horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1)) { + Text( + text = state.dateTimeText.resolveReference(), + style = TangemTheme.typography2.captionMedium12, + color = TangemTheme.colors2.text.neutral.primary, + ) + if (state.priceChangePercentText != null) { + PriceChangeInPercent( + valueInPercent = state.priceChangePercentText, + type = state.priceChangeType, + textStyle = TangemTheme.typography2.captionMedium12, + ) + } + } + } + SpacerW4() + CoinIcon( + modifier = Modifier.requiredSize(70.dp), + url = state.iconUrl, + alpha = 1f, + colorFilter = null, + fallbackResId = R.drawable.ic_custom_token_44, ) } } @@ -323,9 +368,9 @@ private fun TokenPriceTextV2( text = priceAnnotated.resolveAnnotatedReference(), modifier = modifier, color = color.value, - autoSize = TextAutoSize.StepBased(maxFontSize = TangemTheme.typography2.headingBold34.fontSize), + autoSize = TextAutoSize.StepBased(maxFontSize = TangemTheme.typography2.titleRegular44.fontSize), maxLines = 1, - style = TangemTheme.typography2.headingBold34, + style = TangemTheme.typography2.titleRegular44, ) } 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 7d88242f03..d613f5e228 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 @@ -11,6 +11,7 @@ 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 @@ -49,6 +50,7 @@ import com.tangem.core.ui.extensions.* 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.state.ExchangeItemUM import com.tangem.features.feed.ui.market.detailed.state.ExchangesBottomSheetContent @@ -273,7 +275,7 @@ private fun ErrorV2(content: ExchangesBottomSheetContent.Error, modifier: Modifi text = stringResourceSafe(id = content.message), color = TangemTheme.colors2.text.neutral.tertiary, textAlign = TextAlign.Center, - style = TangemTheme.typography2.bodyRegular14, + style = TangemTheme.typography2.subheadlineMedium14, ) SpacerH(8.dp) @@ -369,6 +371,7 @@ private fun ExchangeItemRowPlaceholder(modifier: Modifier = Modifier) { .layoutId(TangemRowLayoutId.HEAD), ) RectangleShimmer( + radius = TangemTheme.dimens2.x25, modifier = Modifier .width(108.dp) .height(20.dp) @@ -376,6 +379,7 @@ private fun ExchangeItemRowPlaceholder(modifier: Modifier = Modifier) { .layoutId(TangemRowLayoutId.START_TOP), ) RectangleShimmer( + radius = TangemTheme.dimens2.x25, modifier = Modifier .width(52.dp) .height(16.dp) @@ -383,6 +387,7 @@ private fun ExchangeItemRowPlaceholder(modifier: Modifier = Modifier) { .layoutId(TangemRowLayoutId.START_BOTTOM), ) RectangleShimmer( + radius = TangemTheme.dimens2.x25, modifier = Modifier .width(106.dp) .height(20.dp) @@ -390,6 +395,7 @@ private fun ExchangeItemRowPlaceholder(modifier: Modifier = Modifier) { .layoutId(TangemRowLayoutId.END_TOP), ) RectangleShimmer( + radius = TangemTheme.dimens2.x25, modifier = Modifier .width(52.dp) .height(16.dp) @@ -428,6 +434,25 @@ 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/preview/MarketsTokenDetailsPreview.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/preview/MarketsTokenDetailsPreview.kt index 63b06d0833..c73cfa497c 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/preview/MarketsTokenDetailsPreview.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/preview/MarketsTokenDetailsPreview.kt @@ -20,6 +20,7 @@ internal object MarketsTokenDetailsPreview { val loadingState = MarketsTokenDetailsUM( tokenName = "Token Name", + symbol = "USDT", priceText = "$0.00000000324", dateTimeText = stringReference("Today"), priceChangePercentText = "52.00%", @@ -55,6 +56,7 @@ internal object MarketsTokenDetailsPreview { val contentState = MarketsTokenDetailsUM( tokenName = "Token Name", + symbol = "USDT", priceText = "$0.00000000324", dateTimeText = stringReference("Today"), priceChangePercentText = "52.00%", diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/state/MarketsTokenDetailsUM.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/state/MarketsTokenDetailsUM.kt index cb53a7dd7e..a9e4a602a4 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/state/MarketsTokenDetailsUM.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/detailed/state/MarketsTokenDetailsUM.kt @@ -14,6 +14,7 @@ import java.math.BigDecimal internal data class MarketsTokenDetailsUM( val tokenName: String, + val symbol: String, val priceText: String, val priceAnnotated: TextReference, val iconUrl: String?, diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/components/SortByMenu.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/components/SortByMenu.kt index 559240a0ca..34588157c5 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/components/SortByMenu.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/ui/market/list/components/SortByMenu.kt @@ -1,11 +1,25 @@ package com.tangem.features.feed.ui.market.list.components +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.HorizontalDivider +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 +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.graphics.vector.rememberVectorPainter +import androidx.compose.ui.res.vectorResource import androidx.compose.ui.unit.DpOffset -import androidx.compose.ui.util.fastForEach +import androidx.compose.ui.unit.dp +import androidx.compose.ui.util.fastForEachIndexed +import com.tangem.core.ui.R import com.tangem.core.ui.ds.contextmenu.TangemContextMenu -import com.tangem.core.ui.ds.contextmenu.TangemContextMenuCheckboxItem +import com.tangem.core.ui.extensions.clickableSingle +import com.tangem.core.ui.extensions.resolveReference +import com.tangem.core.ui.res.TangemTheme import com.tangem.features.feed.model.market.list.state.SortByMenuUM import com.tangem.features.feed.model.market.list.state.SortByTypeUM @@ -22,15 +36,61 @@ internal fun SortByMenu( offset = DpOffset.Zero, modifier = modifier, ) { - SortByTypeUM.entries.fastForEach { sortType -> - TangemContextMenuCheckboxItem( - title = sortType.text, - isChecked = sortMenuUM.selectedOption == sortType, - onClick = { - sortMenuUM.onOptionClicked(sortType) - onDropdownDismiss() - }, - ) + SortByTypeUM.entries.fastForEachIndexed { index, sortType -> + Column { + Row( + horizontalArrangement = Arrangement.SpaceBetween, + modifier = Modifier + .fillMaxWidth() + .width(238.dp) + .clickableSingle( + onClick = { + sortMenuUM.onOptionClicked(sortType) + onDropdownDismiss() + }, + ) + .padding( + vertical = TangemTheme.dimens2.x5, + horizontal = TangemTheme.dimens2.x4, + ), + ) { + Text( + text = sortType.text.resolveReference(), + style = TangemTheme.typography2.headingSemibold17, + color = TangemTheme.colors2.text.neutral.primary, + maxLines = 1, + ) + if (sortMenuUM.selectedOption == sortType) { + Box( + modifier = Modifier + .padding(TangemTheme.dimens2.x0_5) + .size(TangemTheme.dimens2.x5) + .background( + color = TangemTheme.colors2.graphic.neutral.primary, + shape = CircleShape, + ), + ) { + Icon( + painter = rememberVectorPainter( + ImageVector.vectorResource(R.drawable.ic_check_default_24), + ), + contentDescription = null, + tint = TangemTheme.colors2.graphic.neutral.primaryInverted, + modifier = Modifier + .align(Alignment.Center) + .padding(TangemTheme.dimens2.x0_5) + .size(TangemTheme.dimens2.x4), + ) + } + } + } + if (index < SortByTypeUM.entries.size - 1) { + HorizontalDivider( + thickness = 0.5.dp, + color = TangemTheme.colors2.border.neutral.quaternary, + ) + } + } } } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen2.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen2.kt index 376948e5ae..f9a4714b79 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen2.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen2.kt @@ -209,16 +209,27 @@ private fun WalletContent2( .fillMaxSize() .hazeSourceTangem(zIndex = -2f), ) { - NorthernLightsBackground( - containerColor = if (LocalIsInDarkTheme.current) { - TangemTheme.colors2.surface.level1 - } else { - TangemTheme.colors2.surface.level2 - }, + val backgroundColor = if (LocalIsInDarkTheme.current) { + TangemTheme.colors2.surface.level1 + } else { + TangemTheme.colors2.surface.level2 + } + Box( modifier = Modifier - .graphicsLayer { alpha = 1 - behavior.state.collapsedFraction * 2 } - .matchParentSize(), + .matchParentSize() + .background(backgroundColor), ) + val isSheetExpanded by remember { + derivedStateOf { bottomSheetState.targetValue == TangemSheetValue.Expanded } + } + if (!isSheetExpanded) { + NorthernLightsBackground( + containerColor = backgroundColor, + modifier = Modifier + .graphicsLayer { alpha = 1 - behavior.state.collapsedFraction * 2 } + .matchParentSize(), + ) + } WalletPagerIndicator( pagerState = walletsPagerState, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/multicurrency/MultiCurrencyContent.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/multicurrency/MultiCurrencyContent.kt index 1c4838b7b9..87350a5742 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/multicurrency/MultiCurrencyContent.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/multicurrency/MultiCurrencyContent.kt @@ -34,6 +34,7 @@ import com.tangem.common.ui.tokens.NonContentItemContent import com.tangem.common.ui.tokens.SlideInItemVisibility import com.tangem.core.ui.components.SpacerH import com.tangem.core.ui.components.account.AccountIconSize +import com.tangem.core.ui.components.account.toBoxSize import com.tangem.core.ui.components.currency.icon.CurrencyIconState import com.tangem.core.ui.components.tokenlist.NON_CONTENT_TOKENS_LIST_KEY import com.tangem.core.ui.components.tokenlist.TokenListItem @@ -382,12 +383,14 @@ internal fun PortfolioRowItem( headIcon } + val iconBoxSize = when (headIcon) { + is TangemIconUM.Empty -> TangemTheme.dimens2.x9 + else -> size.toBoxSize() + } TangemIcon( tangemIconUM = sizedHeadIcon, modifier = modifier - .conditionalCompose(headIcon is TangemIconUM.Empty) { - size(TangemTheme.dimens2.x9) - } + .size(iconBoxSize) .sharedBounds( sharedContentState = iconSharedContentState, animatedVisibilityScope = animatedContentScope,