diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/token/internal/TokenTitle.kt b/core/ui/src/main/java/com/tangem/core/ui/components/token/internal/TokenTitle.kt index 2cbd277ce7..6c4a0dea38 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/token/internal/TokenTitle.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/token/internal/TokenTitle.kt @@ -11,6 +11,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.composed import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.tangem.core.ui.R @@ -21,10 +22,14 @@ import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.components.token.state.TokenItemState.TitleState as TokenTitleState @Composable -fun TokenTitle(state: TokenTitleState?, modifier: Modifier = Modifier) { +fun TokenTitle( + state: TokenTitleState?, + modifier: Modifier = Modifier, + textStyle: TextStyle = TangemTheme.typography.subtitle2, +) { when (state) { is TokenTitleState.Content -> { - ContentTitle(state = state, modifier = modifier) + ContentTitle(state = state, modifier = modifier, textStyle = textStyle) } is TokenTitleState.Loading -> { RectangleShimmer(modifier = modifier.placeholderSize(), radius = TangemTheme.dimens.radius4) @@ -37,7 +42,7 @@ fun TokenTitle(state: TokenTitleState?, modifier: Modifier = Modifier) { } @Composable -private fun ContentTitle(state: TokenTitleState.Content, modifier: Modifier = Modifier) { +private fun ContentTitle(state: TokenTitleState.Content, textStyle: TextStyle, modifier: Modifier = Modifier) { Row( modifier = modifier, horizontalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing6), @@ -50,6 +55,7 @@ private fun ContentTitle(state: TokenTitleState.Content, modifier: Modifier = Mo CurrencyNameText( name = state.text.resolveReference(), isAvailable = state.isAvailable, + textStyle = textStyle, modifier = Modifier.weight(weight = 1f, fill = false), ) @@ -71,14 +77,14 @@ private fun ContentTitle(state: TokenTitleState.Content, modifier: Modifier = Mo } @Composable -private fun CurrencyNameText(name: String, isAvailable: Boolean, modifier: Modifier = Modifier) { +private fun CurrencyNameText(name: String, isAvailable: Boolean, textStyle: TextStyle, modifier: Modifier = Modifier) { Text( text = name, modifier = modifier, color = if (isAvailable) TangemTheme.colors.text.primary1 else TangemTheme.colors.text.tertiary, overflow = TextOverflow.Ellipsis, maxLines = 1, - style = TangemTheme.typography.subtitle2, + style = textStyle, ) } diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/tokenlist/TokenListItem.kt b/core/ui/src/main/java/com/tangem/core/ui/components/tokenlist/TokenListItem.kt index 797beea50b..d1ec807e9b 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/tokenlist/TokenListItem.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/tokenlist/TokenListItem.kt @@ -1,25 +1,23 @@ package com.tangem.core.ui.components.tokenlist -import androidx.compose.animation.AnimatedContent -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.BoundsTransform -import androidx.compose.animation.SharedTransitionLayout -import androidx.compose.animation.SharedTransitionScope +import androidx.compose.animation.* +import androidx.compose.animation.SharedTransitionScope.ResizeMode.Companion.scaleToBounds +import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.tween -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.animation.togetherWith import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import com.tangem.core.ui.R import com.tangem.core.ui.components.SpacerW4 import com.tangem.core.ui.components.account.AccountCharIcon @@ -67,7 +65,7 @@ fun TokenListItem(state: TokensListItemUM, isBalanceHidden: Boolean, modifier: M } } -@Suppress("MagicNumber", "ReusedModifierInstance") +@Suppress("MagicNumber", "ReusedModifierInstance", "LongMethod") @Composable fun PortfolioListItem(state: TokensListItemUM.Portfolio, isBalanceHidden: Boolean, modifier: Modifier = Modifier) { // Box is not needed here, but due to a bug in compose @@ -86,7 +84,7 @@ fun PortfolioListItem(state: TokensListItemUM.Portfolio, isBalanceHidden: Boolea val titleSharedContentState = rememberSharedContentState(key = "title") val boundsTransform = BoundsTransform { _, _ -> tween(350) } - val composables = + val composables = remember { TokenItemComposables( icon = { modifier: Modifier -> val iconState = when (val icon = state.tokenItemUM.iconState) { @@ -113,24 +111,51 @@ fun PortfolioListItem(state: TokensListItemUM.Portfolio, isBalanceHidden: Boolea ) }, title = { modifier: Modifier -> + val textStyle = if (isExpanded) { + TangemTheme.typography.caption1 + } else { + TangemTheme.typography.subtitle2 + } + + val textSize by animateFloatAsState( + targetValue = textStyle.fontSize.value, + animationSpec = tween(350), + ) + TokenTitle( state = state.tokenItemUM.titleState, + textStyle = textStyle.copy(fontSize = textSize.sp), modifier = modifier - .sharedElement( + .sharedBounds( sharedContentState = titleSharedContentState, animatedVisibilityScope = animatedContentScope, boundsTransform = boundsTransform, - placeholderSize = SharedTransitionScope.PlaceholderSize.AnimatedSize, + resizeMode = scaleToBounds(ContentScale.Fit, Alignment.CenterStart), ), ) }, ) + } if (isExpanded) { ExpandedPortfolioHeader( state = state.tokenItemUM, isCollapsable = state.isCollapsable, composables = composables, + balanceTextModifier = Modifier + .animateEnterExit( + enter = fadeIn(tween(350)) + + slideInHorizontally( + tween(350), + initialOffsetX = { fullWidth -> fullWidth * 2 }, + ), + exit = fadeOut( + tween(350), + ) + slideOutHorizontally( + tween(350), + targetOffsetX = { fullWidth -> fullWidth * 2 }, + ), + ), ) } else { TokenItem( @@ -163,6 +188,7 @@ fun ExpandedPortfolioHeader( isCollapsable: Boolean, composables: TokenItemComposables?, modifier: Modifier = Modifier, + balanceTextModifier: Modifier = Modifier, ) { Row( verticalAlignment = Alignment.CenterVertically, @@ -227,18 +253,16 @@ fun ExpandedPortfolioHeader( else -> null } - AnimatedVisibility(text != null) { - Text( - text = text.orEmpty(), - modifier = Modifier - .alignByBaseline() - .padding(horizontal = 8.dp), - color = TangemTheme.colors.text.tertiary, - style = TangemTheme.typography.caption1, - overflow = TextOverflow.Ellipsis, - maxLines = 1, - ) - } + Text( + text = text.orEmpty(), + modifier = balanceTextModifier + .alignByBaseline() + .padding(horizontal = 8.dp), + color = TangemTheme.colors.text.tertiary, + style = TangemTheme.typography.caption1, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + ) } if (isCollapsable) { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/multicurrency/MultiCurrencyAccountContent.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/multicurrency/MultiCurrencyAccountContent.kt index 74d4b0079b..0cf245d560 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/multicurrency/MultiCurrencyAccountContent.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/multicurrency/MultiCurrencyAccountContent.kt @@ -113,6 +113,7 @@ internal fun LazyListScope.portfolioTokensList( ) } +@Suppress("MagicNumber") private fun LazyListScope.portfolioItem( portfolio: TokensListItemUM.Portfolio, modifier: Modifier, @@ -140,7 +141,7 @@ private fun LazyListScope.portfolioItem( lastIndexProxy = lastIndex return@LaunchedEffect } - delay(timeMillis = (50 * tokens.size).toLong()) + delay(timeMillis = minOf(50 * tokens.size, 350).toLong()) lastIndexProxy = 0 } @@ -168,19 +169,23 @@ private fun SlideInItemVisibility( modifier: Modifier = Modifier, content: @Composable () -> Unit, ) { + val maxDelay = 250 + val delayEnter = minOf(50 * currentIndex, maxDelay) + val delayExit = minOf(50 * (lastIndex - currentIndex - 1), maxDelay) + AnimatedVisibility( modifier = modifier, visible = visible, enter = fadeIn( - tween(100, delayMillis = 50 * currentIndex), + tween(100, delayMillis = delayEnter), ) + expandVertically( - tween(100, delayMillis = 50 * currentIndex), + tween(100, delayMillis = delayEnter), expandFrom = Alignment.Top, ), exit = fadeOut( - tween(100, delayMillis = 50 * (lastIndex - currentIndex - 1)), + tween(100, delayMillis = delayExit), ) + shrinkVertically( - tween(100, delayMillis = 50 * (lastIndex - currentIndex - 1)), + tween(100, delayMillis = delayExit), shrinkTowards = Alignment.Top, ), ) {