Updated on 2026-08-14
This commit is contained in:
parent
3fe7585ba8
commit
d0bc6087fe
34 changed files with 569 additions and 461 deletions
|
|
@ -72,14 +72,14 @@ fun MarketListItemContentV2(model: MarketsListItemUM, modifier: Modifier = Modif
|
|||
TangemIcon(
|
||||
tangemIconUM = TangemIconUM.Url(model.iconUrl, fallbackRes = R.drawable.ic_custom_token_44),
|
||||
modifier = Modifier
|
||||
.size(40.dp)
|
||||
.size(TangemTheme.dimens2.x10)
|
||||
.layoutId(layoutId = TangemRowLayoutId.HEAD),
|
||||
)
|
||||
|
||||
TokenTitle(
|
||||
modifier = Modifier
|
||||
.layoutId(layoutId = TangemRowLayoutId.START_TOP)
|
||||
.padding(horizontal = TangemTheme.dimens2.x2),
|
||||
.padding(start = TangemTheme.dimens2.x3),
|
||||
name = model.name,
|
||||
currencySymbol = model.currencySymbol,
|
||||
)
|
||||
|
|
@ -97,7 +97,7 @@ fun MarketListItemContentV2(model: MarketsListItemUM, modifier: Modifier = Modif
|
|||
TokenSubtitle(
|
||||
modifier = Modifier
|
||||
.layoutId(layoutId = TangemRowLayoutId.START_BOTTOM)
|
||||
.padding(end = TangemTheme.dimens2.x2, start = TangemTheme.dimens2.x3),
|
||||
.padding(start = TangemTheme.dimens2.x3),
|
||||
ratingPosition = model.ratingPosition,
|
||||
marketCap = model.marketCap,
|
||||
stakingRate = model.stakingRate,
|
||||
|
|
@ -112,7 +112,7 @@ fun MarketListItemContentV2(model: MarketsListItemUM, modifier: Modifier = Modif
|
|||
if (windowSize.widthAtLeast(WindowSizeType.Small)) {
|
||||
Chart(
|
||||
modifier = Modifier
|
||||
.padding(start = TangemTheme.dimens2.x2)
|
||||
.padding(start = TangemTheme.dimens2.x3)
|
||||
.layoutId(layoutId = TangemRowLayoutId.TAIL),
|
||||
chartType = model.chartType,
|
||||
chartRawData = model.chartData,
|
||||
|
|
@ -140,7 +140,7 @@ private fun TokenTitle(name: String, currencySymbol: String, modifier: Modifier
|
|||
modifier = Modifier.alignByBaseline(),
|
||||
text = currencySymbol,
|
||||
color = TangemTheme.colors2.text.neutral.secondary,
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Visible,
|
||||
)
|
||||
|
|
@ -197,7 +197,7 @@ private fun RowScope.TokenRatingPlace(ratingPosition: String?, ratingColor: Colo
|
|||
textAlign = TextAlign.Center,
|
||||
text = ratingPosition ?: MINUS,
|
||||
color = ratingColor,
|
||||
style = TangemTheme.typography2.captionSemibold12.copy(letterSpacing = 0.sp),
|
||||
style = TangemTheme.typography2.captionMedium12.copy(letterSpacing = 0.sp),
|
||||
maxLines = 1,
|
||||
)
|
||||
|
||||
|
|
@ -216,7 +216,7 @@ private fun RowScope.TokenMarketCapText(text: String, ratingColor: Color, modifi
|
|||
modifier = modifier.alignByBaseline(),
|
||||
text = text,
|
||||
color = ratingColor,
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -25,13 +25,17 @@ import dev.chrisbanes.haze.HazeTint
|
|||
* elements and floating button at the bottom of the screen.
|
||||
*/
|
||||
@Composable
|
||||
fun BottomFade(modifier: Modifier = Modifier, backgroundColor: Color = TangemTheme.colors.background.secondary) {
|
||||
fun BottomFade(
|
||||
modifier: Modifier = Modifier,
|
||||
backgroundColor: Color = TangemTheme.colors.background.secondary,
|
||||
height: Dp = 100.dp,
|
||||
) {
|
||||
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
|
||||
|
||||
Box(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.height(TangemTheme.dimens.size100 + bottomBarHeight)
|
||||
.height(height + bottomBarHeight)
|
||||
.background(
|
||||
brush = Brush.verticalGradient(
|
||||
colors = listOf(
|
||||
|
|
|
|||
|
|
@ -6,12 +6,14 @@ import androidx.compose.material3.CardColors
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.ReadOnlyComposable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
@Composable
|
||||
fun BlockCard(
|
||||
modifier: Modifier = Modifier,
|
||||
enabled: Boolean = true,
|
||||
shape: Shape = TangemTheme.shapes.roundedCornersXMedium,
|
||||
colors: CardColors = TangemBlockCardColors,
|
||||
onClick: () -> Unit = {},
|
||||
content: @Composable ColumnScope.() -> Unit = {},
|
||||
|
|
@ -19,7 +21,7 @@ fun BlockCard(
|
|||
Card(
|
||||
modifier = modifier,
|
||||
onClick = onClick,
|
||||
shape = TangemTheme.shapes.roundedCornersXMedium,
|
||||
shape = shape,
|
||||
colors = colors,
|
||||
enabled = enabled,
|
||||
content = content,
|
||||
|
|
|
|||
|
|
@ -127,13 +127,13 @@ private fun DescriptionItemV2(
|
|||
onClick = onReadMoreClick,
|
||||
),
|
||||
text = text,
|
||||
style = TangemTheme.typography2.bodyRegular15,
|
||||
style = TangemTheme.typography2.bodyMedium16,
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
modifier = modifier,
|
||||
text = description.resolveReference(),
|
||||
style = TangemTheme.typography2.bodyRegular15,
|
||||
style = TangemTheme.typography2.bodyMedium16,
|
||||
color = TangemTheme.colors2.text.neutral.tertiary,
|
||||
)
|
||||
}
|
||||
|
|
@ -179,17 +179,17 @@ private fun DescriptionPlaceholderV2(modifier: Modifier = Modifier) {
|
|||
) {
|
||||
TextShimmer(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
style = TangemTheme.typography2.bodyRegular15,
|
||||
style = TangemTheme.typography2.bodyMedium16,
|
||||
radius = TangemTheme.dimens2.x25,
|
||||
)
|
||||
TextShimmer(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
style = TangemTheme.typography2.bodyRegular15,
|
||||
style = TangemTheme.typography2.bodyMedium16,
|
||||
radius = TangemTheme.dimens2.x25,
|
||||
)
|
||||
TextShimmer(
|
||||
modifier = Modifier.fillMaxWidth(fraction = 0.8f),
|
||||
style = TangemTheme.typography2.bodyRegular15,
|
||||
style = TangemTheme.typography2.bodyMedium16,
|
||||
radius = TangemTheme.dimens2.x25,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,20 +14,20 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
|||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.compose.ui.unit.Density
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.*
|
||||
import com.tangem.core.ui.components.haze.hazeEffectTangem
|
||||
import com.tangem.core.ui.extensions.conditionalCompose
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
||||
import dev.chrisbanes.haze.HazeState
|
||||
import dev.chrisbanes.haze.rememberHazeState
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -63,6 +63,7 @@ private val SMALL_DOT_SIZE = DpSize(4.dp, 4.dp)
|
|||
fun TangemPagerIndicator(
|
||||
pagerState: PagerState,
|
||||
modifier: Modifier = Modifier,
|
||||
hazeState: HazeState = rememberHazeState(),
|
||||
colors: PagerIndicatorColors = TangemPagerIndicatorColors,
|
||||
) {
|
||||
val totalPages = pagerState.pageCount
|
||||
|
|
@ -84,10 +85,12 @@ fun TangemPagerIndicator(
|
|||
.width(getSize(totalPages))
|
||||
.conditionalCompose(colors.overlay != null) {
|
||||
colors.overlay?.let { overlay ->
|
||||
background(
|
||||
color = overlay,
|
||||
shape = CircleShape,
|
||||
)
|
||||
this
|
||||
.clip(CircleShape)
|
||||
.hazeEffectTangem(hazeState) {
|
||||
this.blurRadius = 16.dp
|
||||
backgroundColor = overlay
|
||||
}
|
||||
} ?: this
|
||||
}
|
||||
.padding(TangemTheme.dimens2.x3),
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
package com.tangem.core.ui.ds.tabs
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.animation.core.AnimationSpec
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.core.snap
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
|
|
@ -86,7 +88,7 @@ fun TangemSegmentedPicker(
|
|||
val density = LocalDensity.current
|
||||
|
||||
val itemsWidths = remember { mutableStateListOf(*Array(items.size) { 0.dp }) }
|
||||
val selectedIndex = remember { mutableStateOf(items.indexOfFirstOrNull { it == initialSelectedItem } ?: 0) }
|
||||
val selectedIndex = remember { mutableIntStateOf(items.indexOfFirstOrNull { it == initialSelectedItem } ?: 0) }
|
||||
val segmentHeight = remember { mutableStateOf(0.dp) }
|
||||
|
||||
val shape = RoundedCornerShape(TangemTheme.dimens2.x25)
|
||||
|
|
@ -105,7 +107,7 @@ fun TangemSegmentedPicker(
|
|||
) {
|
||||
SegmentSelection(
|
||||
itemsWidths = itemsWidths,
|
||||
selectedIndex = selectedIndex.value,
|
||||
selectedIndex = selectedIndex.intValue,
|
||||
segmentHeight = segmentHeight.value,
|
||||
)
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
|
|
@ -151,18 +153,30 @@ fun TangemSegmentedPicker(
|
|||
|
||||
@Composable
|
||||
private fun SegmentSelection(itemsWidths: SnapshotStateList<Dp>, selectedIndex: Int, segmentHeight: Dp) {
|
||||
var hasInitiallyMeasured by remember { mutableStateOf(false) }
|
||||
|
||||
val animationSpec: AnimationSpec<Dp> = if (hasInitiallyMeasured) {
|
||||
tween(durationMillis = 300)
|
||||
} else {
|
||||
snap()
|
||||
}
|
||||
|
||||
val indicatorOffset by animateDpAsState(
|
||||
targetValue = itemsWidths.take(selectedIndex).fold(0.dp, Dp::plus),
|
||||
animationSpec = tween(durationMillis = 300),
|
||||
animationSpec = animationSpec,
|
||||
label = "indicatorOffset",
|
||||
)
|
||||
|
||||
val indicatorWidth by animateDpAsState(
|
||||
targetValue = itemsWidths[selectedIndex],
|
||||
animationSpec = tween(durationMillis = 300),
|
||||
animationSpec = animationSpec,
|
||||
label = "indicatorWidth",
|
||||
)
|
||||
|
||||
LaunchedEffect(itemsWidths[selectedIndex] > 0.dp) {
|
||||
if (itemsWidths[selectedIndex] > 0.dp) hasInitiallyMeasured = true
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.offset {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ internal fun MetricsCard(
|
|||
modifier = modifier
|
||||
.background(
|
||||
color = cardColor,
|
||||
shape = RoundedCornerShape(TangemTheme.dimens2.x5),
|
||||
shape = RoundedCornerShape(TangemTheme.dimens2.x6),
|
||||
)
|
||||
.conditional(
|
||||
condition = onClick != null,
|
||||
|
|
@ -67,7 +67,7 @@ private fun MetricsCardPreview() {
|
|||
content = {
|
||||
Text(
|
||||
text = "Market cap",
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
color = TangemTheme.colors2.text.neutral.tertiary,
|
||||
)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,14 +1,12 @@
|
|||
package com.tangem.features.feed.ui.earn.components
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
@Composable
|
||||
|
|
@ -17,12 +15,7 @@ internal fun CardFilterBlock(modifier: Modifier = Modifier, content: @Composable
|
|||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.background(
|
||||
color = TangemTheme.colors2.surface.level2,
|
||||
shape = RoundedCornerShape(TangemTheme.dimens2.x5),
|
||||
)
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = TangemTheme.colors2.border.neutral.primary,
|
||||
color = TangemTheme.colors2.surface.level3,
|
||||
shape = RoundedCornerShape(TangemTheme.dimens2.x5),
|
||||
),
|
||||
content = content,
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ internal inline fun <reified T : TangemBottomSheetConfigContent> EarnFilterBotto
|
|||
TangemBottomSheet<T>(
|
||||
config = config,
|
||||
type = TangemBottomSheetType.Modal,
|
||||
containerColor = TangemTheme.colors2.surface.level3,
|
||||
containerColor = TangemTheme.colors2.surface.level2,
|
||||
title = {
|
||||
TangemTopBar(
|
||||
title = resourceReference(R.string.earn_filter_by),
|
||||
|
|
|
|||
|
|
@ -151,7 +151,16 @@ private fun NetworksTypesBlock(
|
|||
addDefaultPadding = false,
|
||||
)
|
||||
.clickable { onOptionClick(item) },
|
||||
contentPadding = PaddingValues(horizontal = 12.dp, vertical = 12.dp),
|
||||
contentPadding = PaddingValues(
|
||||
start = TangemTheme.dimens2.x3,
|
||||
end = TangemTheme.dimens2.x3,
|
||||
top = if (index == 0) 18.dp else TangemTheme.dimens2.x3,
|
||||
bottom = if (index == allMyNetworks.lastIndex) {
|
||||
18.dp
|
||||
} else {
|
||||
TangemTheme.dimens2.x3
|
||||
},
|
||||
),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.layoutId(layoutId = TangemRowLayoutId.START_TOP),
|
||||
|
|
@ -190,7 +199,7 @@ private fun SpecificNetworksBlock(
|
|||
.padding(horizontal = 16.dp)
|
||||
.padding(top = 16.dp, bottom = 8.dp),
|
||||
text = stringResourceSafe(id = R.string.earn_filter_networks),
|
||||
style = TangemTheme.typography2.bodyRegular14,
|
||||
style = TangemTheme.typography2.subheadlineMedium14,
|
||||
color = TangemTheme.colors2.text.neutral.tertiary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
|
|
|
|||
|
|
@ -117,13 +117,15 @@ private fun ContentV2(content: EarnFilterByTypeBottomSheetContentUM) {
|
|||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
|
||||
TangemCheckbox(
|
||||
modifier = Modifier
|
||||
.padding(start = 8.dp)
|
||||
.layoutId(layoutId = TangemRowLayoutId.TAIL),
|
||||
isChecked = type == content.selectedOption,
|
||||
onCheckedChange = { content.onOptionClick(type) },
|
||||
)
|
||||
if (type == content.selectedOption) {
|
||||
TangemCheckbox(
|
||||
modifier = Modifier
|
||||
.padding(start = 8.dp)
|
||||
.layoutId(layoutId = TangemRowLayoutId.TAIL),
|
||||
isChecked = true,
|
||||
onCheckedChange = { content.onOptionClick(type) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.features.feed.ui.earn.components
|
|||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
|
|
@ -46,7 +47,7 @@ private fun MostlyUsedCardV2(item: EarnListItemUM, onClick: () -> Unit, modifier
|
|||
OpportunitiesBG(
|
||||
modifier = modifier
|
||||
.width(178.dp)
|
||||
.clip(TangemTheme.shapes.roundedCornersXMedium)
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens2.x6))
|
||||
.clickable(onClick = onClick),
|
||||
icon = TangemIconUM.Currency(item.currencyIconState),
|
||||
) {
|
||||
|
|
@ -76,7 +77,7 @@ private fun MostlyUsedCardV2(item: EarnListItemUM, onClick: () -> Unit, modifier
|
|||
Text(
|
||||
text = item.symbol.resolveReference(),
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
maxLines = 1,
|
||||
)
|
||||
}
|
||||
|
|
@ -86,7 +87,7 @@ private fun MostlyUsedCardV2(item: EarnListItemUM, onClick: () -> Unit, modifier
|
|||
Text(
|
||||
text = item.earnValue.resolveReference(),
|
||||
color = TangemTheme.colors2.text.status.positive,
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
maxLines = 1,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.*
|
|||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
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
|
||||
|
|
@ -21,6 +22,7 @@ import com.tangem.core.ui.extensions.conditionalCompose
|
|||
import com.tangem.core.ui.res.LocalMainBottomSheetColor
|
||||
import com.tangem.core.ui.res.LocalRedesignEnabled
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
||||
import com.tangem.core.ui.test.BaseSearchBarTestTags.SEARCH_BAR
|
||||
import com.tangem.features.feed.model.market.list.state.SortByTypeUM
|
||||
import com.tangem.features.feed.ui.components.FeedSearchBar
|
||||
|
|
@ -159,4 +161,14 @@ private fun FeedListPreview() {
|
|||
TangemThemePreview {
|
||||
FeedList(state = createFeedPreviewState(), contentPadding = PaddingValues())
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, heightDp = 1500)
|
||||
@Composable
|
||||
private fun FeedListPreviewV2() {
|
||||
TangemThemePreviewRedesign {
|
||||
CompositionLocalProvider(LocalRedesignEnabled provides true) {
|
||||
FeedList(state = createFeedPreviewState(), contentPadding = PaddingValues())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -32,7 +32,7 @@ internal fun ColumnScope.Header(
|
|||
) {
|
||||
val isRedesignEnabled = LocalRedesignEnabled.current
|
||||
if (isRedesignEnabled) {
|
||||
SpacerH(20.dp)
|
||||
SpacerH(16.dp)
|
||||
}
|
||||
AnimatedContent(isLoading) { animatedState ->
|
||||
Row(
|
||||
|
|
|
|||
|
|
@ -48,18 +48,17 @@ private fun DateBlockV2(currentDate: String) {
|
|||
Text(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 24.dp),
|
||||
.padding(horizontal = TangemTheme.dimens2.x6),
|
||||
text = stringResourceSafe(R.string.feed_market_and_news),
|
||||
style = TangemTheme.typography2.headingRegular28,
|
||||
style = TangemTheme.typography2.headingSemibold28,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 24.dp),
|
||||
.padding(horizontal = TangemTheme.dimens2.x6),
|
||||
text = currentDate,
|
||||
style = TangemTheme.typography2.headingRegular28,
|
||||
color = TangemTheme.colors2.text.neutral.tertiary,
|
||||
)
|
||||
SpacerH(TangemTheme.dimens2.x6)
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.*
|
|||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
|
|
@ -117,7 +118,7 @@ internal fun ColumnScope.MarketPulseBlock(marketChartConfig: MarketChartConfig,
|
|||
)
|
||||
|
||||
LazyRow(
|
||||
modifier = Modifier.padding(vertical = if (isRedesignEnabled) 12.dp else 4.dp),
|
||||
modifier = Modifier.padding(vertical = 4.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
contentPadding = if (isRedesignEnabled) {
|
||||
PaddingValues(horizontal = 16.dp, vertical = 6.dp)
|
||||
|
|
@ -180,6 +181,11 @@ private fun Charts(
|
|||
TangemTheme.colors.background.action
|
||||
},
|
||||
),
|
||||
shape = if (isRedesignEnabled) {
|
||||
RoundedCornerShape(TangemTheme.dimens2.x6)
|
||||
} else {
|
||||
TangemTheme.shapes.roundedCornersXMedium
|
||||
},
|
||||
) {
|
||||
Column(modifier = Modifier.fillMaxWidth()) {
|
||||
when (marketChart) {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import androidx.compose.foundation.layout.Column
|
|||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
|
|
@ -37,12 +39,14 @@ import com.tangem.features.feed.ui.feed.state.*
|
|||
internal const val FOURTH_ITEM_INDEX = 3
|
||||
private const val GRADIENT_START = 0f
|
||||
private const val GRADIENT_END = 0.5f
|
||||
private const val LINEAR_GRADIENT_FIRST_PART_V2 = 0xFFA3A0FF
|
||||
private const val LINEAR_GRADIENT_SECOND_PART_V2 = 0xFFF79DFF
|
||||
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
|
||||
internal fun NewsBlock(feedListCallbacks: FeedListCallbacks, news: NewsUM, trendingArticle: ArticleConfigUM?) {
|
||||
AnimatedContent(news.newsUMState) { newsUMState ->
|
||||
|
|
@ -102,10 +106,19 @@ private fun NewsContentBlock(feedListCallbacks: FeedListCallbacks, news: NewsUM,
|
|||
|
||||
SpacerW(4.dp)
|
||||
|
||||
Image(
|
||||
imageVector = ImageVector.vectorResource(R.drawable.ic_stars_20),
|
||||
contentDescription = null,
|
||||
)
|
||||
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,
|
||||
)
|
||||
}
|
||||
|
||||
SpacerW(2.dp)
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ internal fun NewsSlider(newsSliderConfig: NewsSliderConfig) {
|
|||
articleConfigUM = article,
|
||||
onArticleClick = { newsSliderConfig.callbacks.onArticleClick(article.id) },
|
||||
modifier = articleModifier
|
||||
.width(228.dp)
|
||||
.width(280.dp)
|
||||
.heightIn(min = 172.dp)
|
||||
.fillMaxHeight(),
|
||||
colors = TangemBlockCardColors.copy(containerColor = TangemTheme.colors.background.action),
|
||||
|
|
@ -56,7 +56,7 @@ internal fun NewsSlider(newsSliderConfig: NewsSliderConfig) {
|
|||
item(contentType = "show_more") {
|
||||
ShowMoreArticlesCard(
|
||||
modifier = Modifier
|
||||
.width(228.dp)
|
||||
.width(280.dp)
|
||||
.heightIn(min = 172.dp)
|
||||
.onFirstVisible(
|
||||
minFractionVisible = 0.5f,
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import com.tangem.core.ui.extensions.stringResourceSafe
|
|||
import com.tangem.core.ui.res.LocalIsInDarkTheme
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
||||
import com.tangem.utils.StringsSigns
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableSet
|
||||
|
|
@ -70,12 +71,15 @@ private fun TrendingArticle(
|
|||
onClick = onArticleClick,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
modifier = Modifier.padding(TangemTheme.dimens2.x4),
|
||||
horizontalAlignment = Alignment.Start,
|
||||
) {
|
||||
DayAndRatingInfo(rating = stringReference("${articleConfigUM.score}"))
|
||||
DayAndRatingInfo(
|
||||
rating = stringReference("${articleConfigUM.score}"),
|
||||
createdAt = articleConfigUM.createdAt,
|
||||
)
|
||||
|
||||
SpacerH(8.dp)
|
||||
SpacerH(TangemTheme.dimens2.x2)
|
||||
|
||||
Text(
|
||||
text = articleConfigUM.title,
|
||||
|
|
@ -88,17 +92,7 @@ private fun TrendingArticle(
|
|||
textAlign = TextAlign.Start,
|
||||
)
|
||||
|
||||
SpacerH(18.dp)
|
||||
|
||||
Text(
|
||||
text = articleConfigUM.createdAt.resolveReference(),
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
color = TangemTheme.colors2.text.neutral.secondary,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
)
|
||||
|
||||
SpacerH(18.dp)
|
||||
SpacerH(TangemTheme.dimens2.x8)
|
||||
|
||||
Tags(tags = articleConfigUM.tags.toImmutableList())
|
||||
}
|
||||
|
|
@ -111,14 +105,9 @@ internal fun ShowMoreArticlesCardV2(modifier: Modifier = Modifier, onClick: () -
|
|||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.clip(RoundedCornerShape(20.dp))
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens2.x6))
|
||||
.background(color = TangemTheme.colors2.surface.level3)
|
||||
.clickable(onClick = onClick)
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = TangemTheme.colors2.border.neutral.primary,
|
||||
shape = RoundedCornerShape(20.dp),
|
||||
)
|
||||
.padding(vertical = 41.dp, horizontal = 16.dp),
|
||||
) {
|
||||
Image(
|
||||
|
|
@ -139,7 +128,7 @@ internal fun ShowMoreArticlesCardV2(modifier: Modifier = Modifier, onClick: () -
|
|||
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.news_stay_in_the_loop),
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
color = TangemTheme.colors2.text.neutral.secondary,
|
||||
)
|
||||
}
|
||||
|
|
@ -153,24 +142,20 @@ private fun DefaultArticle(
|
|||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.clip(RoundedCornerShape(20.dp))
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens2.x6))
|
||||
.background(color = TangemTheme.colors2.surface.level3)
|
||||
.clickable(onClick = onArticleClick)
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = TangemTheme.colors2.border.neutral.primary,
|
||||
shape = RoundedCornerShape(20.dp),
|
||||
)
|
||||
.padding(16.dp),
|
||||
.padding(TangemTheme.dimens2.x4),
|
||||
) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
RatingInfo(
|
||||
rating = stringReference("${articleConfigUM.score}"),
|
||||
isTrending = false,
|
||||
createdAt = articleConfigUM.createdAt,
|
||||
)
|
||||
}
|
||||
|
||||
SpacerH(8.dp)
|
||||
SpacerH(TangemTheme.dimens2.x2)
|
||||
|
||||
Text(
|
||||
modifier = Modifier.weight(1f),
|
||||
|
|
@ -185,17 +170,7 @@ private fun DefaultArticle(
|
|||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
|
||||
SpacerH(8.dp)
|
||||
|
||||
Text(
|
||||
text = articleConfigUM.createdAt.resolveReference(),
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
color = TangemTheme.colors2.text.neutral.secondary,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
)
|
||||
|
||||
SpacerH(8.dp)
|
||||
SpacerH(TangemTheme.dimens2.x8)
|
||||
|
||||
Tags(tags = articleConfigUM.tags.toImmutableList())
|
||||
}
|
||||
|
|
@ -220,7 +195,7 @@ private fun TrendingArticleBackground(
|
|||
|
||||
Box(
|
||||
modifier = modifier
|
||||
.clip(RoundedCornerShape(20.dp))
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens2.x6))
|
||||
.drawBehind {
|
||||
drawRect(bgColor)
|
||||
|
||||
|
|
@ -279,45 +254,61 @@ private fun TrendingArticleBackground(
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun DayAndRatingInfo(rating: TextReference, modifier: Modifier = Modifier) {
|
||||
private fun DayAndRatingInfo(createdAt: TextReference, rating: TextReference, modifier: Modifier = Modifier) {
|
||||
Row(
|
||||
modifier = modifier,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
RatingInfo(rating = rating, isTrending = true)
|
||||
RatingInfo(rating = rating, isTrending = true, createdAt = createdAt)
|
||||
|
||||
SpacerW(8.dp)
|
||||
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.feed_trending_now),
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RatingInfo(rating: TextReference, isTrending: Boolean) {
|
||||
private fun RatingInfo(rating: TextReference, isTrending: Boolean, createdAt: TextReference) {
|
||||
val iconTint = if (isTrending) {
|
||||
TangemTheme.colors2.fill.status.attention
|
||||
} else {
|
||||
TangemTheme.colors2.markers.iconGray
|
||||
}
|
||||
val captionColor = if (isTrending) {
|
||||
TangemTheme.colors2.text.status.attention
|
||||
} else {
|
||||
TangemTheme.colors2.text.neutral.secondary
|
||||
}
|
||||
|
||||
Icon(
|
||||
imageVector = ImageVector.vectorResource(R.drawable.ic_wrapped_circle_star_16),
|
||||
tint = if (isTrending) {
|
||||
TangemTheme.colors2.fill.status.attention
|
||||
} else {
|
||||
TangemTheme.colors2.markers.iconGray
|
||||
},
|
||||
tint = iconTint,
|
||||
contentDescription = null,
|
||||
)
|
||||
|
||||
SpacerW(2.dp)
|
||||
SpacerW(TangemTheme.dimens2.x1)
|
||||
|
||||
Text(
|
||||
text = rating.resolveReference(),
|
||||
color = if (isTrending) {
|
||||
TangemTheme.colors2.text.status.attention
|
||||
} else {
|
||||
TangemTheme.colors2.text.neutral.secondary
|
||||
},
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
color = captionColor,
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier.padding(horizontal = TangemTheme.dimens2.x0_5),
|
||||
text = StringsSigns.DOT,
|
||||
color = captionColor,
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
)
|
||||
|
||||
Text(
|
||||
text = createdAt.resolveReference(),
|
||||
color = captionColor,
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package com.tangem.features.feed.ui.feed.components.articles
|
|||
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
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
|
|
@ -12,22 +11,16 @@ 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.SpacerW
|
||||
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.TangemBadge
|
||||
import com.tangem.core.ui.ds.badge.TangemBadgeColor
|
||||
import com.tangem.core.ui.ds.badge.TangemBadgeIconPosition
|
||||
import com.tangem.core.ui.ds.badge.TangemBadgeShape
|
||||
import com.tangem.core.ui.ds.badge.TangemBadgeSize
|
||||
import com.tangem.core.ui.ds.badge.TangemBadgeType
|
||||
import com.tangem.core.ui.ds.badge.*
|
||||
import com.tangem.core.ui.ds.image.TangemIconUM
|
||||
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.utils.StringsSigns
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
|
|
@ -100,7 +93,6 @@ private fun ArticleHeaderV1(
|
|||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
private fun ArticleHeaderV2(
|
||||
isTrending: Boolean,
|
||||
|
|
@ -111,127 +103,121 @@ private fun ArticleHeaderV2(
|
|||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(modifier = modifier) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.heightIn(min = 66.dp)
|
||||
.padding(top = 16.dp),
|
||||
verticalAlignment = Alignment.Bottom,
|
||||
) {
|
||||
DateBlock(
|
||||
modifier = Modifier.weight(1f),
|
||||
createdAt = createdAt,
|
||||
)
|
||||
SpacerW(30.dp)
|
||||
VerticalDivider(
|
||||
modifier = Modifier
|
||||
.height(46.dp)
|
||||
.padding(bottom = 4.dp),
|
||||
color = TangemTheme.colors2.border.neutral.primary,
|
||||
)
|
||||
SpacerW(30.dp)
|
||||
ScoreBlock(
|
||||
modifier = Modifier.weight(1f),
|
||||
score = score,
|
||||
isTrending = isTrending,
|
||||
)
|
||||
}
|
||||
|
||||
Text(
|
||||
modifier = Modifier.padding(vertical = 36.dp),
|
||||
text = title,
|
||||
style = TangemTheme.typography2.headingBold34,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
ArticleHeaderV2MetaRow(
|
||||
isTrending = isTrending,
|
||||
score = score,
|
||||
createdAt = createdAt,
|
||||
)
|
||||
|
||||
if (tags.isNotEmpty()) {
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
FlowRow(
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
tags.forEach { 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.X9,
|
||||
type = TangemBadgeType.Tinted,
|
||||
color = TangemBadgeColor.Gray,
|
||||
iconPosition = when (tag.leadingContent) {
|
||||
LabelLeadingContentUM.None -> TangemBadgeIconPosition.None
|
||||
is LabelLeadingContentUM.Token -> TangemBadgeIconPosition.Start
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
ArticleHeaderV2Title(title = title)
|
||||
ArticleHeaderV2Tags(tags = tags)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ScoreBlock(score: Float, isTrending: Boolean, modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier = modifier,
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp),
|
||||
private fun ArticleHeaderV2MetaRow(isTrending: Boolean, score: Float, createdAt: String) {
|
||||
val starTint = if (isTrending) {
|
||||
TangemTheme.colors2.fill.status.attention
|
||||
} else {
|
||||
TangemTheme.colors2.graphic.neutral.primary
|
||||
}
|
||||
val scoreColor = if (isTrending) {
|
||||
TangemTheme.colors2.text.status.attention
|
||||
} else {
|
||||
TangemTheme.colors2.text.neutral.tertiary
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = Modifier.padding(horizontal = TangemTheme.dimens2.x1),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x2),
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(10.dp),
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.size(20.dp),
|
||||
imageVector = ImageVector.vectorResource(R.drawable.ic_wrapped_circle_star_16),
|
||||
tint = if (isTrending) {
|
||||
TangemTheme.colors2.fill.status.attention
|
||||
} else {
|
||||
TangemTheme.colors2.graphic.neutral.primary
|
||||
},
|
||||
contentDescription = null,
|
||||
)
|
||||
Text(
|
||||
text = score.toString(),
|
||||
style = TangemTheme.typography2.bodyRegular16,
|
||||
color = if (isTrending) {
|
||||
TangemTheme.colors2.text.status.attention
|
||||
} else {
|
||||
TangemTheme.colors2.text.neutral.primary
|
||||
},
|
||||
)
|
||||
}
|
||||
Icon(
|
||||
modifier = Modifier.size(TangemTheme.dimens2.x5),
|
||||
imageVector = ImageVector.vectorResource(R.drawable.ic_wrapped_circle_star_16),
|
||||
tint = starTint,
|
||||
contentDescription = null,
|
||||
)
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.news_trending_score),
|
||||
style = TangemTheme.typography2.captionSemibold13,
|
||||
text = score.toString(),
|
||||
style = TangemTheme.typography2.bodyMedium16,
|
||||
color = scoreColor,
|
||||
)
|
||||
Text(
|
||||
text = StringsSigns.DOT,
|
||||
color = TangemTheme.colors2.text.neutral.tertiary,
|
||||
style = TangemTheme.typography2.bodyMedium16,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DateBlock(createdAt: String, modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier = modifier,
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp),
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.size(20.dp),
|
||||
imageVector = ImageVector.vectorResource(R.drawable.ic_calendar_20),
|
||||
tint = TangemTheme.colors2.fill.neutral.primary,
|
||||
tint = TangemTheme.colors2.graphic.neutral.secondary,
|
||||
contentDescription = null,
|
||||
)
|
||||
Text(
|
||||
text = createdAt,
|
||||
style = TangemTheme.typography2.captionSemibold13,
|
||||
color = TangemTheme.colors2.text.neutral.tertiary,
|
||||
style = TangemTheme.typography2.bodyMedium16,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ArticleHeaderV2Title(title: String) {
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
top = TangemTheme.dimens2.x4,
|
||||
bottom = TangemTheme.dimens2.x1_5,
|
||||
start = TangemTheme.dimens2.x1,
|
||||
),
|
||||
text = title,
|
||||
style = TangemTheme.typography2.headingSemibold28,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
private fun ArticleHeaderV2Tags(tags: ImmutableList<LabelUM>) {
|
||||
if (tags.isEmpty()) return
|
||||
|
||||
Spacer(modifier = Modifier.height(TangemTheme.dimens2.x6))
|
||||
FlowRow(
|
||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1),
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1),
|
||||
) {
|
||||
tags.forEach { tag ->
|
||||
ArticleHeaderTagBadge(tag = tag)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ArticleHeaderTagBadge(tag: LabelUM) {
|
||||
TangemBadge(
|
||||
text = tag.text,
|
||||
tangemIconUM = labelLeadingIcon(tag.leadingContent),
|
||||
shape = TangemBadgeShape.Rounded,
|
||||
size = TangemBadgeSize.X9,
|
||||
type = TangemBadgeType.Tinted,
|
||||
color = TangemBadgeColor.Gray,
|
||||
iconPosition = labelLeadingBadgeIconPosition(tag.leadingContent),
|
||||
)
|
||||
}
|
||||
|
||||
private fun labelLeadingIcon(content: LabelLeadingContentUM): TangemIconUM? = when (content) {
|
||||
LabelLeadingContentUM.None -> null
|
||||
is LabelLeadingContentUM.Token -> TangemIconUM.Url(
|
||||
url = content.iconUrl,
|
||||
fallbackRes = R.drawable.ic_alert_24,
|
||||
)
|
||||
}
|
||||
|
||||
private fun labelLeadingBadgeIconPosition(content: LabelLeadingContentUM): TangemBadgeIconPosition = when (content) {
|
||||
LabelLeadingContentUM.None -> TangemBadgeIconPosition.None
|
||||
is LabelLeadingContentUM.Token -> TangemBadgeIconPosition.Start
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Composable
|
||||
private fun ArticleHeaderPreviewV1() {
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ internal object FeedListPreviewDataProvider {
|
|||
}
|
||||
|
||||
private fun createEarnListItemsUM(): ImmutableList<EarnListItemUM> {
|
||||
return List(5) {
|
||||
return List(1) {
|
||||
EarnListItemUM(
|
||||
network = stringReference("Ethereum"),
|
||||
symbol = stringReference("USDT"),
|
||||
|
|
|
|||
|
|
@ -125,7 +125,9 @@ private fun Content(
|
|||
.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
item { SpacerH16() }
|
||||
item {
|
||||
if (isRedesignEnabled) SpacerH(TangemTheme.dimens2.x3) else SpacerH16()
|
||||
}
|
||||
item("intervalSelector") {
|
||||
IntervalSelector(
|
||||
trendInterval = state.selectedInterval,
|
||||
|
|
@ -136,7 +138,9 @@ private fun Content(
|
|||
.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
item { SpacerH32() }
|
||||
item {
|
||||
if (isRedesignEnabled) SpacerH(TangemTheme.dimens2.x3) else SpacerH32()
|
||||
}
|
||||
item("chart") {
|
||||
MarketTokenDetailsChart(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ 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.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
|
|
@ -26,8 +25,6 @@ internal fun InformationTextBlock(
|
|||
text: TextReference,
|
||||
modifier: Modifier = Modifier,
|
||||
onInfoClick: (() -> Unit)? = null,
|
||||
textColor: Color = TangemTheme.colors2.text.neutral.tertiary,
|
||||
infoIconColor: Color = TangemTheme.colors2.markers.iconGray,
|
||||
informationTextBlockIconPosition: InformationTextBlockIconPosition = InformationTextBlockIconPosition.START,
|
||||
) {
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
|
|
@ -36,7 +33,7 @@ internal fun InformationTextBlock(
|
|||
Icon(
|
||||
modifier = Modifier.size(TangemTheme.dimens2.x4),
|
||||
imageVector = ImageVector.vectorResource(id = R.drawable.ic_information_24),
|
||||
tint = infoIconColor,
|
||||
tint = TangemTheme.colors2.fill.neutral.secondary,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
|
|
@ -44,8 +41,8 @@ internal fun InformationTextBlock(
|
|||
val contentText: @Composable () -> Unit = {
|
||||
Text(
|
||||
text = text.resolveReference(),
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
color = textColor,
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
color = TangemTheme.colors2.text.neutral.secondary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@ 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.badge.TangemBadge
|
||||
import com.tangem.core.ui.ds.badge.TangemBadgeIconPosition
|
||||
import com.tangem.core.ui.ds.badge.TangemBadgeShape
|
||||
import com.tangem.core.ui.ds.badge.TangemBadgeSize
|
||||
import com.tangem.core.ui.ds.button.SecondaryTangemButton
|
||||
import com.tangem.core.ui.ds.button.TangemButtonIconPosition
|
||||
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.stringReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
|
|
@ -174,7 +174,7 @@ private fun SubBlockV2(
|
|||
Text(
|
||||
modifier = Modifier.padding(start = 10.dp, top = TangemTheme.dimens2.x4),
|
||||
text = title,
|
||||
style = TangemTheme.typography2.bodySemibold16,
|
||||
style = TangemTheme.typography2.headingSemibold20,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
|
|
@ -185,16 +185,16 @@ private fun SubBlockV2(
|
|||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x2),
|
||||
) {
|
||||
links.fastForEach { link ->
|
||||
TangemBadge(
|
||||
text = stringReference(link.title),
|
||||
SecondaryTangemButton(
|
||||
onClick = { onLinkClick(link) },
|
||||
iconPosition = TangemBadgeIconPosition.Start,
|
||||
text = stringReference(link.title),
|
||||
iconPosition = TangemButtonIconPosition.Start,
|
||||
tangemIconUM = TangemIconUM.Icon(
|
||||
iconRes = link.iconRes,
|
||||
tintReference = { TangemTheme.colors2.markers.iconGray },
|
||||
tintReference = { TangemTheme.colors2.graphic.neutral.primary },
|
||||
),
|
||||
size = TangemBadgeSize.X9,
|
||||
shape = TangemBadgeShape.Rounded,
|
||||
size = TangemButtonSize.X9,
|
||||
shape = TangemButtonShape.Rounded,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,18 +94,18 @@ private fun ListedOnBlockV2(state: ListedOnUM, modifier: Modifier = Modifier) {
|
|||
},
|
||||
title = {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1)) {
|
||||
Text(
|
||||
text = state.title.resolveReference(),
|
||||
style = TangemTheme.typography2.headingSemibold20,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
color = TangemTheme.colors2.text.neutral.secondary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
Text(
|
||||
text = state.description.resolveReference(),
|
||||
style = TangemTheme.typography2.captionSemibold13,
|
||||
color = TangemTheme.colors2.text.neutral.secondary,
|
||||
style = TangemTheme.typography2.headingSemibold20,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
|
|
@ -114,7 +114,7 @@ private fun ListedOnBlockV2(state: ListedOnUM, modifier: Modifier = Modifier) {
|
|||
SpacerWMax()
|
||||
|
||||
Icon(
|
||||
modifier = Modifier.size(20.dp),
|
||||
modifier = Modifier.size(TangemTheme.dimens2.x5),
|
||||
imageVector = ImageVector.vectorResource(R.drawable.ic_chevron_small_right_24),
|
||||
tint = TangemTheme.colors2.markers.iconGray,
|
||||
contentDescription = null,
|
||||
|
|
@ -165,7 +165,7 @@ internal fun ListedOnBlockPlaceholderV2(modifier: Modifier = Modifier) {
|
|||
radius = TangemTheme.dimens2.x25,
|
||||
)
|
||||
TextShimmer(
|
||||
style = TangemTheme.typography2.captionSemibold13,
|
||||
style = TangemTheme.typography2.captionMedium13,
|
||||
modifier = Modifier.width(66.dp),
|
||||
radius = TangemTheme.dimens2.x25,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ import com.tangem.features.feed.ui.market.detailed.state.TrendingVolumeLiquidity
|
|||
internal fun MarketCapCard(item: InfoPointUMV2.MarketCap) {
|
||||
MetricsCard(
|
||||
modifier = Modifier
|
||||
.heightIn(120.dp)
|
||||
.heightIn(104.dp)
|
||||
.fillMaxWidth(),
|
||||
title = { MetricValueText(value = item.capitalizationValue) },
|
||||
content = {
|
||||
|
|
@ -66,7 +66,7 @@ internal fun TradingVolumeCard(item: InfoPointUMV2.TradingVolume) {
|
|||
|
||||
MetricsCard(
|
||||
modifier = Modifier
|
||||
.heightIn(120.dp)
|
||||
.heightIn(104.dp)
|
||||
.fillMaxWidth(),
|
||||
title = {
|
||||
Row {
|
||||
|
|
@ -74,7 +74,7 @@ internal fun TradingVolumeCard(item: InfoPointUMV2.TradingVolume) {
|
|||
Text(
|
||||
modifier = Modifier.padding(TangemTheme.dimens2.x1),
|
||||
text = stringResourceSafe(R.string.markets_token_details_trading_interval),
|
||||
style = TangemTheme.typography2.captionSemibold11,
|
||||
style = TangemTheme.typography2.captionMedium11,
|
||||
color = valueColor,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
|
|
@ -97,24 +97,21 @@ internal fun TradingVolumeCard(item: InfoPointUMV2.TradingVolume) {
|
|||
SpacerH(12.dp)
|
||||
InformationTextBlock(
|
||||
text = resourceReference(R.string.markets_token_details_trading_volume),
|
||||
textColor = tradingColor,
|
||||
infoIconColor = tradingColor,
|
||||
onInfoClick = item.onInfoClick,
|
||||
)
|
||||
}
|
||||
},
|
||||
cardColor = tradingColor.copy(alpha = .2f),
|
||||
cardColor = TangemTheme.colors2.surface.level3,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun MarketPositionCard(item: InfoPointUMV2.MarketPosition) {
|
||||
val ratingCardColor = mapRatingToCardColor(marketRatingType = item.marketRatingType)
|
||||
val ratingColor = mapRatingToColor(marketRatingType = item.marketRatingType)
|
||||
|
||||
MetricsCard(
|
||||
modifier = Modifier
|
||||
.heightIn(120.dp)
|
||||
.heightIn(104.dp)
|
||||
.fillMaxWidth(),
|
||||
title = {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
|
|
@ -140,13 +137,11 @@ internal fun MarketPositionCard(item: InfoPointUMV2.MarketPosition) {
|
|||
SpacerH(12.dp)
|
||||
InformationTextBlock(
|
||||
text = resourceReference(R.string.markets_token_details_market_rating),
|
||||
textColor = ratingColor,
|
||||
infoIconColor = ratingColor,
|
||||
onInfoClick = item.onInfoClick,
|
||||
)
|
||||
}
|
||||
},
|
||||
cardColor = ratingCardColor,
|
||||
cardColor = TangemTheme.colors2.surface.level3,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -154,7 +149,7 @@ internal fun MarketPositionCard(item: InfoPointUMV2.MarketPosition) {
|
|||
internal fun FDVCard(item: InfoPointUMV2.FullyDilutedValuation) {
|
||||
MetricsCard(
|
||||
modifier = Modifier
|
||||
.heightIn(120.dp)
|
||||
.heightIn(104.dp)
|
||||
.fillMaxWidth(),
|
||||
title = {
|
||||
if (item.fullyDilutedValuationChange24 != null) {
|
||||
|
|
@ -163,7 +158,7 @@ internal fun FDVCard(item: InfoPointUMV2.FullyDilutedValuation) {
|
|||
Text(
|
||||
modifier = Modifier.padding(TangemTheme.dimens2.x1),
|
||||
text = stringResourceSafe(R.string.markets_token_details_trading_interval),
|
||||
style = TangemTheme.typography2.captionSemibold11,
|
||||
style = TangemTheme.typography2.captionMedium11,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
|
|
@ -179,7 +174,7 @@ internal fun FDVCard(item: InfoPointUMV2.FullyDilutedValuation) {
|
|||
Text(
|
||||
text = item.value?.resolveReference()
|
||||
?: stringResourceSafe(R.string.token_market_metrics_no_data),
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
|
|
@ -200,14 +195,14 @@ internal fun FDVCard(item: InfoPointUMV2.FullyDilutedValuation) {
|
|||
internal fun CirculatingSupplyCard(item: InfoPointUMV2.CirculatingSupply) {
|
||||
MetricsCard(
|
||||
modifier = Modifier
|
||||
.heightIn(min = if (item.fillValue == null) 88.dp else 114.dp)
|
||||
.heightIn(min = if (item.fillValue == null) 88.dp else 106.dp)
|
||||
.fillMaxWidth(),
|
||||
title = {
|
||||
TangemRowContainer(contentPadding = PaddingValues(0.dp)) {
|
||||
Text(
|
||||
modifier = Modifier.layoutId(TangemRowLayoutId.START_TOP),
|
||||
text = stringResourceSafe(R.string.markets_token_details_circulating_supply),
|
||||
style = TangemTheme.typography2.captionSemibold13,
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
color = TangemTheme.colors2.text.neutral.tertiary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
|
|
@ -223,7 +218,7 @@ internal fun CirculatingSupplyCard(item: InfoPointUMV2.CirculatingSupply) {
|
|||
Text(
|
||||
modifier = Modifier.layoutId(TangemRowLayoutId.END_TOP),
|
||||
text = stringResourceSafe(R.string.markets_token_details_max_supply),
|
||||
style = TangemTheme.typography2.captionSemibold13,
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
color = TangemTheme.colors2.text.neutral.tertiary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
|
|
@ -235,7 +230,7 @@ internal fun CirculatingSupplyCard(item: InfoPointUMV2.CirculatingSupply) {
|
|||
.padding(top = 12.dp)
|
||||
.layoutId(TangemRowLayoutId.END_BOTTOM),
|
||||
text = item.maxValue.resolveReference(),
|
||||
style = TangemTheme.typography2.headingSemibold22,
|
||||
style = TangemTheme.typography2.headingSemibold20,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
|
|
@ -270,7 +265,7 @@ private fun MetricValueText(value: TextReference?, modifier: Modifier = Modifier
|
|||
Text(
|
||||
modifier = modifier,
|
||||
text = value?.resolveReference() ?: stringResourceSafe(R.string.token_market_metrics_no_data),
|
||||
style = TangemTheme.typography2.headingSemibold22,
|
||||
style = TangemTheme.typography2.headingSemibold20,
|
||||
color = metricValueColor(hasData = value != null),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
|
|
@ -338,7 +333,7 @@ private fun RatingChangeContent(iconRes: Int, iconTint: Color, changeValue: Stri
|
|||
SpacerW(2.dp)
|
||||
Text(
|
||||
text = changeValue,
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
color = textColor,
|
||||
)
|
||||
}
|
||||
|
|
@ -366,14 +361,6 @@ private fun MarketRatingType.baseColor(): Color {
|
|||
@Composable
|
||||
private fun mapRatingToColor(marketRatingType: MarketRatingType): Color = marketRatingType.baseColor()
|
||||
|
||||
@Composable
|
||||
private fun mapRatingToCardColor(marketRatingType: MarketRatingType): Color {
|
||||
return when (marketRatingType) {
|
||||
MarketRatingType.OTHER -> TangemTheme.colors2.surface.level3
|
||||
else -> marketRatingType.baseColor().copy(alpha = 0.3f)
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
private const val GOLD_PLACE_COLOR_NIGHT = 0xFFFBEE76
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ 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.ContainerWithDivider
|
||||
import com.tangem.features.feed.ui.components.TokenMarketInformationBlock
|
||||
import com.tangem.features.feed.ui.market.detailed.state.SecurityScoreUM
|
||||
|
||||
@Composable
|
||||
|
|
@ -80,45 +80,42 @@ private fun SecurityScoreBlockV1(state: SecurityScoreUM, modifier: Modifier = Mo
|
|||
|
||||
@Composable
|
||||
private fun SecurityScoreBlockV2(state: SecurityScoreUM, modifier: Modifier = Modifier) {
|
||||
ContainerWithDivider(
|
||||
TokenMarketInformationBlock(
|
||||
modifier = modifier,
|
||||
showDivider = true,
|
||||
) {
|
||||
TangemRowContainer(modifier = Modifier.padding(top = 20.dp, bottom = 24.dp)) {
|
||||
Text(
|
||||
modifier = Modifier.layoutId(layoutId = TangemRowLayoutId.START_TOP),
|
||||
text = "${state.score}",
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
style = TangemTheme.typography2.headingBold28,
|
||||
)
|
||||
title = {
|
||||
TangemRowContainer(contentPadding = PaddingValues()) {
|
||||
Text(
|
||||
modifier = Modifier.layoutId(layoutId = TangemRowLayoutId.START_TOP),
|
||||
text = "${state.score}",
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
style = TangemTheme.typography2.headingSemibold20,
|
||||
)
|
||||
|
||||
InformationTextBlock(
|
||||
modifier = Modifier.layoutId(layoutId = TangemRowLayoutId.START_BOTTOM),
|
||||
text = resourceReference(R.string.markets_token_details_security_score),
|
||||
onInfoClick = state.onInfoClick,
|
||||
textColor = TangemTheme.colors2.text.neutral.primary,
|
||||
informationTextBlockIconPosition = InformationTextBlockIconPosition.END,
|
||||
)
|
||||
InformationTextBlock(
|
||||
modifier = Modifier.layoutId(layoutId = TangemRowLayoutId.START_BOTTOM),
|
||||
text = resourceReference(R.string.markets_token_details_security_score),
|
||||
onInfoClick = state.onInfoClick,
|
||||
informationTextBlockIconPosition = InformationTextBlockIconPosition.START,
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier.layoutId(layoutId = TangemRowLayoutId.END_BOTTOM),
|
||||
text = state.description.resolveReference(),
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
color = TangemTheme.colors2.text.neutral.tertiary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.layoutId(layoutId = TangemRowLayoutId.END_BOTTOM),
|
||||
text = state.description.resolveReference(),
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
color = TangemTheme.colors2.text.neutral.secondary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
|
||||
ScoreStarsBlock(
|
||||
modifier = Modifier
|
||||
.padding(bottom = 16.dp)
|
||||
.layoutId(layoutId = TangemRowLayoutId.END_TOP),
|
||||
score = state.score,
|
||||
scoreTextStyle = TangemTheme.typography.body1,
|
||||
horizontalSpacing = TangemTheme.dimens.spacing8,
|
||||
)
|
||||
}
|
||||
}
|
||||
ScoreStarsBlock(
|
||||
modifier = Modifier.layoutId(layoutId = TangemRowLayoutId.END_TOP),
|
||||
score = state.score,
|
||||
scoreTextStyle = TangemTheme.typography.body1,
|
||||
horizontalSpacing = TangemTheme.dimens.spacing8,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -146,7 +143,7 @@ private fun SecurityScoreBlockPlaceholderV2(modifier: Modifier = Modifier) {
|
|||
.width(74.dp)
|
||||
.padding(top = 8.dp)
|
||||
.layoutId(layoutId = TangemRowLayoutId.START_BOTTOM),
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
radius = TangemTheme.dimens2.x25,
|
||||
)
|
||||
|
||||
|
|
@ -163,7 +160,7 @@ private fun SecurityScoreBlockPlaceholderV2(modifier: Modifier = Modifier) {
|
|||
.width(96.dp)
|
||||
.padding(top = 8.dp)
|
||||
.layoutId(layoutId = TangemRowLayoutId.END_BOTTOM),
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
radius = TangemTheme.dimens2.x25,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,9 @@ 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
|
||||
|
|
@ -161,7 +163,18 @@ private fun LazyListScope.aboutCoinHeader() {
|
|||
private fun LazyListScope.description(description: MarketsTokenDetailsUM.Description) {
|
||||
item("description") {
|
||||
DescriptionItem(
|
||||
modifier = Modifier.blockPaddings(),
|
||||
modifier = Modifier
|
||||
.conditionalCompose(
|
||||
condition = LocalRedesignEnabled.current,
|
||||
modifier = {
|
||||
this
|
||||
.padding(horizontal = TangemTheme.dimens2.x4)
|
||||
.padding(bottom = TangemTheme.dimens2.x8)
|
||||
},
|
||||
otherModifier = {
|
||||
blockPaddings()
|
||||
},
|
||||
),
|
||||
description = description.shortDescription,
|
||||
hasFullDescription = description.fullDescription != null,
|
||||
onReadMoreClick = description.onReadMoreClick,
|
||||
|
|
@ -249,12 +262,6 @@ internal fun LazyListScope.infoBlocksListV2(state: MarketsTokenDetailsUM.Informa
|
|||
)
|
||||
}
|
||||
|
||||
if (relatedNews.articles.isNotEmpty()) {
|
||||
relatedNews(relatedNews)
|
||||
} else {
|
||||
sectionStub(RelatedNews.SECTION_KEY)
|
||||
}
|
||||
|
||||
if (state.securityScore != null) {
|
||||
item("securityScore") {
|
||||
SecurityScoreBlock(
|
||||
|
|
@ -264,6 +271,12 @@ internal fun LazyListScope.infoBlocksListV2(state: MarketsTokenDetailsUM.Informa
|
|||
}
|
||||
}
|
||||
|
||||
if (relatedNews.articles.isNotEmpty()) {
|
||||
relatedNewsV2(relatedNews)
|
||||
} else {
|
||||
sectionStub(RelatedNews.SECTION_KEY)
|
||||
}
|
||||
|
||||
if (state.links != null) {
|
||||
item("links") {
|
||||
LinksBlock(
|
||||
|
|
@ -367,11 +380,52 @@ private fun LazyListScope.relatedNews(relatedNews: RelatedNews) {
|
|||
}
|
||||
}
|
||||
|
||||
private fun LazyListScope.relatedNewsV2(relatedNews: RelatedNews) {
|
||||
item(RelatedNews.SECTION_KEY) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = TangemTheme.dimens2.x8)
|
||||
.onFirstVisible(
|
||||
minFractionVisible = 0.5f,
|
||||
callback = relatedNews.onFirstVisible,
|
||||
),
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x3),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(start = TangemTheme.dimens2.x6),
|
||||
text = stringResourceSafe(R.string.news_related_news),
|
||||
style = TangemTheme.typography2.headingSemibold20,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
)
|
||||
|
||||
NewsSlider(
|
||||
NewsSliderConfig(
|
||||
callbacks = NewsSliderCallbacks(
|
||||
onOpenAllNews = {}, // not applicable here
|
||||
onSliderScroll = relatedNews.onScroll,
|
||||
onSliderEndReached = {}, // not applicable here
|
||||
onArticleClick = relatedNews.onArticledClicked,
|
||||
),
|
||||
content = relatedNews.articles,
|
||||
shouldShowSeeAllNewsItem = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Modifier.blockPaddings(): Modifier {
|
||||
return this.padding(
|
||||
start = TangemTheme.dimens.spacing16,
|
||||
end = TangemTheme.dimens.spacing16,
|
||||
bottom = TangemTheme.dimens.spacing12,
|
||||
)
|
||||
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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -22,6 +22,9 @@ import com.tangem.features.feed.ui.news.details.components.NewsDetailsPlaceholde
|
|||
import com.tangem.features.feed.ui.news.details.state.ArticlesStateUM
|
||||
import com.tangem.features.feed.ui.news.details.state.MockArticlesFactory
|
||||
import com.tangem.features.feed.ui.news.details.state.NewsDetailsUM
|
||||
import dev.chrisbanes.haze.rememberHazeState
|
||||
|
||||
private const val PAGER_BG_ALPHA = .1f
|
||||
|
||||
@Composable
|
||||
internal fun NewsDetailsContent(state: NewsDetailsUM, contentPadding: PaddingValues, modifier: Modifier = Modifier) {
|
||||
|
|
@ -64,6 +67,7 @@ private fun Content(contentPadding: PaddingValues, state: NewsDetailsUM, backgro
|
|||
initialPage = state.selectedArticleIndex,
|
||||
pageCount = { state.articles.size },
|
||||
)
|
||||
val localHaze = rememberHazeState()
|
||||
|
||||
if (state.articles.isNotEmpty()) {
|
||||
LaunchedEffect(pagerState) {
|
||||
|
|
@ -98,6 +102,7 @@ private fun Content(contentPadding: PaddingValues, state: NewsDetailsUM, backgro
|
|||
onLikeClick = { state.onLikeClick(article.id) },
|
||||
relatedTokensUM = state.relatedTokensUM,
|
||||
contentPadding = contentPadding,
|
||||
hazeState = localHaze,
|
||||
)
|
||||
}
|
||||
if (state.articles.size > 1) {
|
||||
|
|
@ -108,8 +113,9 @@ private fun Content(contentPadding: PaddingValues, state: NewsDetailsUM, backgro
|
|||
.align(Alignment.BottomCenter)
|
||||
.windowInsetsPadding(WindowInsets.navigationBars),
|
||||
colors = TangemPagerIndicatorColors.copy(
|
||||
overlay = TangemTheme.colors2.tabs.backgroundSecondary.copy(alpha = .1f),
|
||||
overlay = TangemTheme.colors2.tabs.backgroundSecondary.copy(PAGER_BG_ALPHA),
|
||||
),
|
||||
hazeState = localHaze,
|
||||
)
|
||||
} else {
|
||||
PagerIndicator(
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import androidx.compose.foundation.lazy.LazyColumn
|
|||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
|
|
@ -19,7 +18,6 @@ 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.BottomFadeWithBlur
|
||||
import com.tangem.core.ui.components.SecondaryButtonIconStart
|
||||
import com.tangem.core.ui.components.SpacerH
|
||||
import com.tangem.core.ui.components.buttons.common.TangemButtonSize
|
||||
|
|
@ -38,10 +36,11 @@ import com.tangem.features.feed.ui.feed.components.articles.ArticleHeader
|
|||
import com.tangem.features.feed.ui.news.details.state.ArticleUM
|
||||
import com.tangem.features.feed.ui.news.details.state.RelatedArticleUM
|
||||
import com.tangem.features.feed.ui.news.details.state.RelatedTokensUM
|
||||
import dev.chrisbanes.haze.rememberHazeState
|
||||
import dev.chrisbanes.haze.HazeState
|
||||
|
||||
@Composable
|
||||
internal fun ArticleDetail(
|
||||
hazeState: HazeState,
|
||||
contentPadding: PaddingValues,
|
||||
article: ArticleUM,
|
||||
onLikeClick: () -> Unit,
|
||||
|
|
@ -55,6 +54,7 @@ internal fun ArticleDetail(
|
|||
onLikeClick = onLikeClick,
|
||||
relatedTokensUM = relatedTokensUM,
|
||||
modifier = modifier,
|
||||
hazeState = hazeState,
|
||||
)
|
||||
} else {
|
||||
ArticleDetailV1(
|
||||
|
|
@ -195,7 +195,8 @@ private fun ArticleDetailV1(
|
|||
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
internal fun ArticleDetailV2(
|
||||
private fun ArticleDetailV2(
|
||||
hazeState: HazeState,
|
||||
contentPadding: PaddingValues,
|
||||
article: ArticleUM,
|
||||
onLikeClick: () -> Unit,
|
||||
|
|
@ -206,16 +207,16 @@ internal fun ArticleDetailV2(
|
|||
val density = LocalDensity.current
|
||||
val background = LocalMainBottomSheetColor.current.value
|
||||
val pagerHeight = 32.dp
|
||||
val bottomPadding = pagerHeight + 56.dp + with(density) {
|
||||
val bottomPadding = pagerHeight + TangemTheme.dimens2.x4 + with(density) {
|
||||
WindowInsets.navigationBars.getBottom(this).div(this.density)
|
||||
}.dp
|
||||
|
||||
CompositionLocalProvider(LocalHazeState provides rememberHazeState()) {
|
||||
CompositionLocalProvider(LocalHazeState provides hazeState) {
|
||||
Box(modifier = modifier) {
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.hazeSourceTangem(zIndex = -1f)
|
||||
.hazeSourceTangem(hazeState)
|
||||
.background(background),
|
||||
contentPadding = PaddingValues(bottom = bottomPadding, top = contentPadding.calculateTopPadding()),
|
||||
) {
|
||||
|
|
@ -227,39 +228,27 @@ internal fun ArticleDetailV2(
|
|||
tags = article.tags,
|
||||
isTrending = article.isTrending,
|
||||
modifier = Modifier
|
||||
.padding(top = 16.dp)
|
||||
.padding(horizontal = 16.dp),
|
||||
.padding(top = TangemTheme.dimens2.x1_5, bottom = TangemTheme.dimens2.x6)
|
||||
.padding(horizontal = TangemTheme.dimens2.x4),
|
||||
)
|
||||
|
||||
if (article.shortContent.isNotEmpty()) {
|
||||
QuickRecap(
|
||||
content = article.shortContent,
|
||||
modifier = Modifier
|
||||
.padding(top = 32.dp)
|
||||
.padding(horizontal = 16.dp),
|
||||
modifier = Modifier.padding(horizontal = TangemTheme.dimens2.x4),
|
||||
)
|
||||
}
|
||||
|
||||
Text(
|
||||
text = article.content,
|
||||
style = TangemTheme.typography2.bodyRegular16,
|
||||
style = TangemTheme.typography2.bodyMedium16,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
modifier = Modifier
|
||||
.padding(top = 12.dp)
|
||||
.padding(horizontal = 16.dp),
|
||||
.padding(vertical = TangemTheme.dimens2.x5, horizontal = TangemTheme.dimens2.x6),
|
||||
)
|
||||
|
||||
SpacerH(24.dp)
|
||||
|
||||
HorizontalDivider(
|
||||
modifier = Modifier.padding(horizontal = 24.dp),
|
||||
color = TangemTheme.colors2.border.neutral.primary,
|
||||
)
|
||||
|
||||
SpacerH(20.dp)
|
||||
|
||||
SecondaryTangemButton(
|
||||
modifier = Modifier.padding(horizontal = 24.dp),
|
||||
modifier = Modifier.padding(horizontal = TangemTheme.dimens2.x6),
|
||||
text = resourceReference(R.string.news_like),
|
||||
size = com.tangem.core.ui.ds.button.TangemButtonSize.X9,
|
||||
tangemIconUM = if (article.isLiked) {
|
||||
|
|
@ -286,31 +275,27 @@ internal fun ArticleDetailV2(
|
|||
is RelatedTokensUM.Content -> relatedTokensUM.onTokenClick
|
||||
else -> null
|
||||
},
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
modifier = Modifier.padding(horizontal = TangemTheme.dimens2.x4),
|
||||
)
|
||||
|
||||
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.typography2.headingSemibold20,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
)
|
||||
}
|
||||
SpacerH(TangemTheme.dimens2.x4)
|
||||
Text(
|
||||
modifier = Modifier.padding(horizontal = TangemTheme.dimens2.x6),
|
||||
text = stringResourceSafe(R.string.news_sources),
|
||||
style = TangemTheme.typography2.headingSemibold20,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (article.relatedArticles.isNotEmpty()) {
|
||||
item("relatedArticles") {
|
||||
LazyRow(
|
||||
modifier = Modifier.padding(vertical = 12.dp),
|
||||
modifier = Modifier.padding(vertical = TangemTheme.dimens2.x3),
|
||||
state = rememberLazyListState(),
|
||||
contentPadding = PaddingValues(horizontal = 16.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
contentPadding = PaddingValues(horizontal = TangemTheme.dimens2.x4),
|
||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x3),
|
||||
) {
|
||||
items(
|
||||
items = article.relatedArticles,
|
||||
|
|
@ -326,12 +311,12 @@ internal fun ArticleDetailV2(
|
|||
}
|
||||
}
|
||||
|
||||
BottomFadeWithBlur(
|
||||
BottomFade(
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.height(80.dp)
|
||||
.fillMaxWidth(),
|
||||
backgroundColor = background,
|
||||
height = TangemTheme.dimens2.x15,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package com.tangem.features.feed.ui.news.details.components
|
|||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.VerticalDivider
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
|
@ -111,38 +110,12 @@ private fun NewsDetailsPlaceholderV2(contentPadding: PaddingValues, background:
|
|||
.padding(16.dp),
|
||||
) {
|
||||
SpacerH(contentPadding.calculateTopPadding())
|
||||
Row(
|
||||
modifier = Modifier.height(50.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(30.dp),
|
||||
) {
|
||||
Column {
|
||||
RectangleShimmer(
|
||||
modifier = Modifier.size(width = 50.dp, height = 20.dp),
|
||||
radius = TangemTheme.dimens2.x25,
|
||||
)
|
||||
SpacerH(10.dp)
|
||||
RectangleShimmer(
|
||||
modifier = Modifier.size(width = 90.dp, height = 18.dp),
|
||||
radius = TangemTheme.dimens2.x25,
|
||||
)
|
||||
}
|
||||
RectangleShimmer(
|
||||
modifier = Modifier.size(width = 90.dp, height = 20.dp),
|
||||
radius = TangemTheme.dimens2.x25,
|
||||
)
|
||||
|
||||
VerticalDivider(color = TangemTheme.colors2.border.neutral.primary)
|
||||
|
||||
Column {
|
||||
RectangleShimmer(
|
||||
modifier = Modifier.size(width = 50.dp, height = 20.dp),
|
||||
radius = TangemTheme.dimens2.x25,
|
||||
)
|
||||
SpacerH(10.dp)
|
||||
RectangleShimmer(
|
||||
modifier = Modifier.size(width = 90.dp, height = 18.dp),
|
||||
radius = TangemTheme.dimens2.x25,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
SpacerH(36.dp)
|
||||
SpacerH(16.dp)
|
||||
|
||||
RectangleShimmer(
|
||||
modifier = Modifier
|
||||
|
|
@ -161,7 +134,7 @@ private fun NewsDetailsPlaceholderV2(contentPadding: PaddingValues, background:
|
|||
radius = TangemTheme.dimens2.x25,
|
||||
)
|
||||
|
||||
SpacerH(36.dp)
|
||||
SpacerH(30.dp)
|
||||
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
|
||||
RectangleShimmer(
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ private fun QuickRecapV2(content: String, modifier: Modifier = Modifier) {
|
|||
contentDescription = null,
|
||||
)
|
||||
|
||||
SpacerW(2.dp)
|
||||
SpacerW(TangemTheme.dimens2.x1)
|
||||
|
||||
Text(
|
||||
text = buildAnnotatedString {
|
||||
|
|
@ -97,26 +97,26 @@ private fun QuickRecapV2(content: String, modifier: Modifier = Modifier) {
|
|||
append(stringResourceSafe(R.string.news_quick_recap))
|
||||
}
|
||||
},
|
||||
style = TangemTheme.typography2.bodyRegular14,
|
||||
style = TangemTheme.typography2.subheadlineMedium14,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
)
|
||||
}
|
||||
|
||||
SpacerH(10.dp)
|
||||
SpacerH(TangemTheme.dimens2.x2_5)
|
||||
|
||||
Box {
|
||||
VerticalDivider(
|
||||
modifier = Modifier
|
||||
.fillMaxHeight()
|
||||
.padding(start = 10.dp),
|
||||
thickness = 2.dp,
|
||||
.padding(start = TangemTheme.dimens2.x2_5),
|
||||
thickness = TangemTheme.dimens2.x0_5,
|
||||
color = Color(QUICK_RECAP_DIVIDER_COLOR),
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(start = 20.dp),
|
||||
modifier = Modifier.padding(start = TangemTheme.dimens2.x5),
|
||||
text = content,
|
||||
style = TangemTheme.typography2.bodyRegular16,
|
||||
style = TangemTheme.typography2.bodyMedium16,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
)
|
||||
}
|
||||
|
|
@ -138,7 +138,7 @@ private fun QuickRecapPreview() {
|
|||
}
|
||||
|
||||
private const val QUICK_RECAP_DIVIDER_COLOR = 0xFFA99FFF
|
||||
private const val LINEAR_GRADIENT_FIRST_PART = 0xFFA3A0FF
|
||||
private const val LINEAR_GRADIENT_SECOND_PART = 0xFFF79DFF
|
||||
private const val LINEAR_GRADIENT_FIRST_PART = 0xFF7B78FF
|
||||
private const val LINEAR_GRADIENT_SECOND_PART = 0xFFC56BCD
|
||||
private const val GRADIENT_START = 0f
|
||||
private const val GRADIENT_END = 0.5f
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
package com.tangem.features.feed.ui.news.details.components
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
|
|
@ -113,42 +112,37 @@ private fun RelatedNewsItemV1(relatedArticle: RelatedArticleUM, modifier: Modifi
|
|||
private fun RelatedNewsItemV2(relatedArticle: RelatedArticleUM, modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.sizeIn(maxWidth = 228.dp, minHeight = 160.dp)
|
||||
.sizeIn(maxWidth = 280.dp, minHeight = 164.dp)
|
||||
.background(
|
||||
color = TangemTheme.colors2.surface.level3,
|
||||
shape = RoundedCornerShape(TangemTheme.dimens2.x5),
|
||||
shape = RoundedCornerShape(TangemTheme.dimens2.x6),
|
||||
)
|
||||
.clickable(onClick = relatedArticle.onClick)
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = TangemTheme.colors2.border.neutral.primary,
|
||||
shape = RoundedCornerShape(TangemTheme.dimens2.x5),
|
||||
)
|
||||
.padding(16.dp),
|
||||
.padding(TangemTheme.dimens2.x4),
|
||||
) {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x4)) {
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(bottom = 4.dp)) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_explore_16),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors2.markers.iconGray,
|
||||
modifier = Modifier.size(16.dp),
|
||||
modifier = Modifier.size(TangemTheme.dimens2.x4),
|
||||
)
|
||||
SpacerW(2.dp)
|
||||
SpacerW(TangemTheme.dimens2.x0_5)
|
||||
Text(
|
||||
text = relatedArticle.media.name,
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
color = TangemTheme.colors2.text.neutral.secondary,
|
||||
)
|
||||
}
|
||||
if (relatedArticle.title.isNotEmpty()) {
|
||||
SpacerH(8.dp)
|
||||
SpacerH(TangemTheme.dimens2.x2)
|
||||
Text(
|
||||
text = relatedArticle.title,
|
||||
style = TangemTheme.typography2.bodyRegular16,
|
||||
style = TangemTheme.typography2.bodyMedium16,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
maxLines = 3,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
|
|
@ -181,7 +175,7 @@ private fun RelatedNewsItemV2(relatedArticle: RelatedArticleUM, modifier: Modifi
|
|||
SpacerHMax()
|
||||
Text(
|
||||
text = relatedArticle.publishedAt.resolveReference(),
|
||||
style = TangemTheme.typography2.captionSemibold12,
|
||||
style = TangemTheme.typography2.captionMedium12,
|
||||
color = TangemTheme.colors2.text.neutral.secondary,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
package com.tangem.features.feed.ui.news.details.components
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
|
|
@ -28,7 +31,27 @@ internal fun RelatedTokensBlock(
|
|||
onItemClick: ((MarketsListItemUM) -> Unit)?,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val isRedesignEnabled = LocalRedesignEnabled.current
|
||||
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()
|
||||
|
|
@ -41,30 +64,15 @@ internal fun RelatedTokensBlock(
|
|||
|
||||
Column(modifier = modifier) {
|
||||
SpacerH(40.dp)
|
||||
if (isRedesignEnabled) {
|
||||
Text(
|
||||
modifier = Modifier.padding(horizontal = 8.dp),
|
||||
text = stringResourceSafe(R.string.news_related_tokens),
|
||||
style = TangemTheme.typography2.headingSemibold20,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.news_related_tokens),
|
||||
style = TangemTheme.typography.h3,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
}
|
||||
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 = if (isRedesignEnabled) {
|
||||
TangemTheme.colors2.surface.level3
|
||||
} else {
|
||||
TangemTheme.colors.background.action
|
||||
},
|
||||
),
|
||||
colors = TangemBlockCardColors.copy(containerColor = TangemTheme.colors.background.action),
|
||||
) {
|
||||
Column(modifier = Modifier.fillMaxWidth()) {
|
||||
when (relatedTokensUM) {
|
||||
|
|
@ -86,4 +94,72 @@ internal fun RelatedTokensBlock(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun RelatedTokensBlockV2(
|
||||
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(TangemTheme.dimens2.x6)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = TangemTheme.dimens2.x2)
|
||||
.padding(top = TangemTheme.dimens2.x4, bottom = TangemTheme.dimens2.x2),
|
||||
text = stringResourceSafe(R.string.news_related_tokens),
|
||||
style = TangemTheme.typography2.headingSemibold20,
|
||||
color = TangemTheme.colors2.text.neutral.primary,
|
||||
)
|
||||
SpacerH(TangemTheme.dimens2.x3)
|
||||
|
||||
Column(modifier = Modifier.fillMaxWidth()) {
|
||||
when (relatedTokensUM) {
|
||||
is RelatedTokensUM.Content -> {
|
||||
relatedTokensUM.items.fastForEach { marketsListItemUM ->
|
||||
WithDecorated {
|
||||
MarketsListItem(
|
||||
model = marketsListItemUM,
|
||||
onClick = { onItemClick?.invoke(marketsListItemUM) },
|
||||
)
|
||||
}
|
||||
SpacerH(TangemTheme.dimens2.x2)
|
||||
}
|
||||
}
|
||||
RelatedTokensUM.Loading -> {
|
||||
repeat(RELATED_TOKEN_MAX_COUNT) {
|
||||
WithDecorated {
|
||||
MarketsListItemPlaceholder()
|
||||
}
|
||||
SpacerH(TangemTheme.dimens2.x2)
|
||||
}
|
||||
}
|
||||
RelatedTokensUM.LoadingError -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun WithDecorated(modifier: Modifier = Modifier, content: @Composable ColumnScope.() -> Unit) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.background(
|
||||
color = TangemTheme.colors2.surface.level3,
|
||||
shape = RoundedCornerShape(TangemTheme.dimens2.x5),
|
||||
),
|
||||
content = content,
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue