Updated on 2026-08-14

This commit is contained in:
Tangem 2026-07-06 09:11:39 +02:00
parent 5ba7c63987
commit d950f3ed0c
5 changed files with 59 additions and 18 deletions

View file

@ -900,6 +900,7 @@
<string name="markets_portfolio_block_add_token_title">**Add to your portfolio** to start buying, exchanging or receiving this asset</string>
<string name="markets_portfolio_block_subtitle">In your portfolio</string>
<string name="markets_portfolio_block_title">Your portfolio</string>
<string name="markets_portfolio_block_token_unsupported">**Token not supported**. This token is currently not supported in the wallet</string>
<string name="markets_pulse_common_title">Market Pulse</string>
<string name="markets_quick_actions">Quick actions</string>
<string name="markets_search_clear_all_hints">Clear all</string>

View file

@ -76,7 +76,7 @@ internal class DefaultMarketsTokenDetailsComponent(
}
private val portfolioBlockComponent: PortfolioBlockComponent? =
if (updatedParams.shouldShowPortfolio && designFeatureToggles.isRedesignEnabled) {
if (designFeatureToggles.isRedesignEnabled) {
portfolioBlockComponentFactory.create(
context = child("portfolio_block"),
params = PortfolioBlockComponent.Params(token = updatedParams.token),

View file

@ -47,7 +47,7 @@ internal class PortfolioBlockModel @Inject constructor(
) : Model() {
val state: StateFlow<PortfolioBlockUM>
field = MutableStateFlow<PortfolioBlockUM>(PortfolioBlockUM.Loading)
field = MutableStateFlow<PortfolioBlockUM>(PortfolioBlockUM.Hidden)
val cryptoCurrencyIdState: StateFlow<CryptoCurrency.ID?>
field = MutableStateFlow(null)
@ -86,7 +86,7 @@ internal class PortfolioBlockModel @Inject constructor(
private fun combineData(): Flow<PortfolioBlockUM> {
return availableNetworks.transformLatest { networks ->
if (networks.isEmpty()) {
emit(PortfolioBlockUM.Hidden)
emit(PortfolioBlockUM.Unsupported(tokenIcon = tokenIcon))
} else {
emitAll(portfolioFlow().distinctUntilChanged())
}
@ -145,7 +145,7 @@ internal class PortfolioBlockModel @Inject constructor(
onAddClick = { parentRouter?.openAddToPortfolioDirect() },
)
} else {
PortfolioBlockUM.Hidden
PortfolioBlockUM.Unsupported(tokenIcon = tokenIcon)
}
}

View file

@ -43,12 +43,11 @@ import com.tangem.features.feed.impl.R
@Composable
internal fun PortfolioBlock(state: PortfolioBlockUM, modifier: Modifier = Modifier) {
val isVisible = state is PortfolioBlockUM.AddToken || state is PortfolioBlockUM.Content
val screenHeightPx = with(LocalDensity.current) { LocalWindowSize.current.height.toPx() }
Box(modifier = modifier) {
AnimatedVisibility(
visible = isVisible,
visible = state !is PortfolioBlockUM.Hidden,
enter = fadeIn(animationSpec = tween(durationMillis = 300)),
) {
TangemFade(
@ -63,7 +62,7 @@ internal fun PortfolioBlock(state: PortfolioBlockUM, modifier: Modifier = Modifi
AnimatedVisibility(
modifier = Modifier.align(Alignment.BottomCenter),
visible = isVisible,
visible = state !is PortfolioBlockUM.Hidden,
enter = fadeIn(animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing)),
exit = fadeOut(animationSpec = tween(durationMillis = 300)),
) {
@ -87,9 +86,8 @@ internal fun PortfolioBlock(state: PortfolioBlockUM, modifier: Modifier = Modifi
when (state) {
is PortfolioBlockUM.AddToken -> AddTokenBlock(state)
is PortfolioBlockUM.Content -> ContentBlock(state)
is PortfolioBlockUM.Hidden,
is PortfolioBlockUM.Loading,
-> Unit
is PortfolioBlockUM.Unsupported -> UnsupportedTokenBlock(state.tokenIcon)
is PortfolioBlockUM.Hidden -> Unit
}
}
}
@ -158,13 +156,19 @@ private fun AddTokenBlock(state: PortfolioBlockUM.AddToken, modifier: Modifier =
FloatingCard(modifier = modifier) {
Row(
modifier = Modifier
.padding(TangemTheme.dimens2.x3)
.padding(
vertical = 12.dp,
horizontal = 16.dp,
)
.clickableSingle(onClick = state.onAddClick),
verticalAlignment = Alignment.CenterVertically,
) {
CurrencyIcon(state.tokenIcon)
CurrencyIcon(
state = state.tokenIcon,
iconSize = 40.dp,
)
SpacerW(TangemTheme.dimens2.x3)
SpacerW(8.dp)
Text(
text = formatAnnotatedWithBoldColor(
@ -192,6 +196,39 @@ private fun AddTokenBlock(state: PortfolioBlockUM.AddToken, modifier: Modifier =
}
}
@Composable
private fun UnsupportedTokenBlock(icon: CurrencyIconState, modifier: Modifier = Modifier) {
FloatingCard(modifier = modifier) {
Row(
modifier = Modifier
.padding(
vertical = 12.dp,
horizontal = 16.dp,
)
.clickableSingle(onClick = {}), // just intercept
verticalAlignment = Alignment.CenterVertically,
) {
CurrencyIcon(
state = icon,
iconSize = 40.dp,
)
SpacerW(8.dp)
Text(
text = formatAnnotatedWithBoldColor(
rawString = stringResourceSafe(R.string.markets_portfolio_block_token_unsupported),
boldColor = TangemTheme.colors2.text.neutral.primary,
),
style = TangemTheme.typography2.captionMedium12,
color = TangemTheme.colors2.text.neutral.secondary,
modifier = Modifier.weight(1f),
maxLines = 2,
)
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun FloatingCard(modifier: Modifier = Modifier, content: @Composable () -> Unit) {

View file

@ -5,15 +5,14 @@ import com.tangem.core.ui.components.currency.icon.CurrencyIconState
import com.tangem.core.ui.extensions.TextReference
@Immutable
internal sealed class PortfolioBlockUM {
internal sealed interface PortfolioBlockUM {
data object Loading : PortfolioBlockUM()
data object Hidden : PortfolioBlockUM()
data object Hidden : PortfolioBlockUM
data class AddToken(
val tokenIcon: CurrencyIconState,
val onAddClick: () -> Unit,
) : PortfolioBlockUM()
) : PortfolioBlockUM
data class Content(
val totalBalance: TextReference,
@ -24,5 +23,9 @@ internal sealed class PortfolioBlockUM {
val isBalanceHidden: Boolean,
val onRowClick: () -> Unit,
val onAddFundsClick: () -> Unit,
) : PortfolioBlockUM()
) : PortfolioBlockUM
data class Unsupported(
val tokenIcon: CurrencyIconState,
) : PortfolioBlockUM
}