diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletContent.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletContent.kt index 3d542d67a6..6217c6f14f 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletContent.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletContent.kt @@ -15,6 +15,7 @@ import com.tangem.common.ui.notifications.notificationsCarousel import com.tangem.core.ui.components.transactions.state.TxHistoryState import com.tangem.core.ui.components.transactions.txHistoryItems import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.utils.TangemSharedTransitionLayout import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState import com.tangem.feature.wallet.presentation.wallet.state.model.WalletUM import com.tangem.feature.wallet.presentation.wallet.ui.components.multicurrency.tokensListItems @@ -37,39 +38,40 @@ internal fun WalletListContent( val movableItemModifier = Modifier.padding(horizontal = TangemTheme.dimens2.x3) val itemModifier = movableItemModifier.padding(top = TangemTheme.dimens2.x3) - LazyColumn( - modifier = modifier, - state = listState, - contentPadding = contentPadding, - horizontalAlignment = Alignment.CenterHorizontally, - overscrollEffect = rememberOverscrollEffect(), - ) { - notifications( - notifications = currentWallet.notifications.map { it.messageUM }.toPersistentList(), - contentColor = containerColor, - modifier = movableItemModifier, - ) - notificationsCarousel( - containerColor = containerColor, - modifier = movableItemModifier, - notifications = currentWallet.notificationsCarousel.map { it.messageUM }.toPersistentList(), - ) + TangemSharedTransitionLayout(modifier) { + LazyColumn( + state = listState, + contentPadding = contentPadding, + horizontalAlignment = Alignment.CenterHorizontally, + overscrollEffect = rememberOverscrollEffect(), + ) { + notifications( + notifications = currentWallet.notifications.map { it.messageUM }.toPersistentList(), + contentColor = containerColor, + modifier = movableItemModifier, + ) + notificationsCarousel( + containerColor = containerColor, + modifier = movableItemModifier, + notifications = currentWallet.notificationsCarousel.map { it.messageUM }.toPersistentList(), + ) - tangemPay( - walletUM = currentWallet, - isBalanceHiding = isBalanceHidden, - modifier = itemModifier, - ) + tangemPay( + walletUM = currentWallet, + isBalanceHiding = isBalanceHidden, + modifier = itemModifier, + ) - tokensListItems2( - walletTokensListUM = currentWallet.tokensListUM, - modifier = movableItemModifier, - isBalanceHidden = isBalanceHidden, - ) + tokensListItems2( + walletTokensListUM = currentWallet.tokensListUM, + modifier = movableItemModifier, + isBalanceHidden = isBalanceHidden, + ) - nftCollections2(state = currentWallet, itemModifier = itemModifier) + nftCollections2(state = currentWallet, itemModifier = itemModifier) - organizeTokens2(state = currentWallet, itemModifier = itemModifier) + organizeTokens2(state = currentWallet, itemModifier = itemModifier) + } } } 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 f8349a879c..e9a092a806 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 @@ -2,6 +2,9 @@ package com.tangem.feature.wallet.presentation.wallet.ui.components.multicurrenc import androidx.compose.animation.* import androidx.compose.animation.core.FastOutLinearInEasing +import androidx.compose.animation.core.LinearOutSlowInEasing +import androidx.compose.animation.core.animateIntAsState +import androidx.compose.animation.core.snap import androidx.compose.animation.core.tween import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding @@ -26,7 +29,6 @@ import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.test.MainScreenTestTags import com.tangem.core.ui.utils.lazyListItemPosition import kotlinx.collections.immutable.ImmutableList -import kotlinx.coroutines.delay internal fun LazyListScope.portfolioContentItems( items: ImmutableList, @@ -155,18 +157,17 @@ private fun LazyListScope.portfolioItem( key = "account-${portfolio.id}", contentType = "account-content", ) { - var lastIndexProxy by remember { mutableIntStateOf(lastIndex) } - - // When collapsing the portfolio, we delay updating lastIndexProxy to allow - // shrinking animation to complete before changing the shape. - LaunchedEffect(lastIndex) { - if (lastIndex != 0) { - lastIndexProxy = lastIndex - return@LaunchedEffect - } - delay(timeMillis = minOf(50 * tokens.size, 250).toLong()) - lastIndexProxy = 0 - } + // Snap immediately on expand; on collapse, hold until all child items finish + // their shrink animation, then snap to fully-rounded shape. + val effectiveLastIndex by animateIntAsState( + targetValue = lastIndex, + animationSpec = if (lastIndex != 0) { + snap() + } else { + snap(delayMillis = minOf(50 * tokens.lastIndex, 250) + 150) + }, + label = "lastIndex", + ) PortfolioListItem( state = portfolio, @@ -176,7 +177,7 @@ private fun LazyListScope.portfolioItem( .roundedShapeItemDecoration( currentIndex = 0, radius = TangemTheme.dimens.radius14, - lastIndex = lastIndexProxy, + lastIndex = effectiveLastIndex, backgroundColor = TangemTheme.colors.background.primary, ), ) @@ -199,18 +200,14 @@ internal fun SlideInItemVisibility( AnimatedVisibility( modifier = modifier, visible = visible, - enter = fadeIn( - tween(100, delayMillis = delayEnter), - ) + expandVertically( - tween(100, delayMillis = delayEnter, easing = FastOutLinearInEasing), + enter = expandVertically( + tween(200, delayMillis = delayEnter, easing = LinearOutSlowInEasing), expandFrom = Alignment.Top, - ), - exit = fadeOut( - tween(100, delayMillis = delayExit), - ) + shrinkVertically( - tween(100, delayMillis = delayExit, easing = FastOutLinearInEasing), + ) + fadeIn(tween(200, delayMillis = delayEnter, easing = LinearOutSlowInEasing)), + exit = shrinkVertically( + tween(150, delayMillis = delayExit, easing = FastOutLinearInEasing), shrinkTowards = Alignment.Top, - ), + ) + fadeOut(tween(150, delayMillis = delayExit, easing = FastOutLinearInEasing)), ) { content() } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/multicurrency/MultiCurrencyContent.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/multicurrency/MultiCurrencyContent.kt index 5041832a6b..2f1006c1cc 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/multicurrency/MultiCurrencyContent.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/multicurrency/MultiCurrencyContent.kt @@ -3,6 +3,8 @@ package com.tangem.feature.wallet.presentation.wallet.ui.components.multicurrenc import androidx.compose.animation.* import androidx.compose.animation.SharedTransitionScope.ResizeMode.Companion.scaleToBounds import androidx.compose.animation.core.animateFloatAsState +import androidx.compose.animation.core.animateIntAsState +import androidx.compose.animation.core.snap import androidx.compose.animation.core.tween import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -214,6 +216,7 @@ private fun LazyListScope.portfolioItem( ) } +@Suppress("MagicNumber") private fun LazyListScope.accountItem( listItem: TokensListItemUM2.Portfolio, modifier: Modifier, @@ -225,6 +228,18 @@ private fun LazyListScope.accountItem( key = listItem.tokenRowUM.id, contentType = listItem.tokenRowUM::class.java, ) { + // Snap immediately on expand; on collapse, hold the current value until all + // child items finish their shrink animation, then snap to fully-rounded shape. + val effectiveLastIndex by animateIntAsState( + targetValue = if (listItem.isExpanded) lastIndex else 0, + animationSpec = if (listItem.isExpanded) { + snap() + } else { + snap(delayMillis = minOf(50 * maxOf(listItem.tokenList.lastIndex, 0), 250) + 150) + }, + label = "lastIndex", + ) + val portfolioModifier = modifier .padding(top = if (index != 0) TangemTheme.dimens2.x2 else TangemTheme.dimens2.x3) .testTag(MainScreenTestTags.TOKEN_LIST_ITEM) @@ -233,7 +248,7 @@ private fun LazyListScope.accountItem( currentIndex = 0, radius = 18.dp, addDefaultPadding = false, - lastIndex = if (listItem.isExpanded) lastIndex else 0, + lastIndex = effectiveLastIndex, backgroundColor = TangemTheme.colors2.surface.level3, ) if (listItem.isCollapsable) { @@ -288,10 +303,9 @@ internal fun PortfolioRowItem( isBalanceHidden: Boolean, modifier: Modifier = Modifier, ) { - // TangemSharedTransitionLayout { ProvideSharedTransitionScope(modifier) { - val iconSharedContentState = rememberSharedContentState(key = "icon") - val titleSharedContentState = rememberSharedContentState(key = "title") + val iconSharedContentState = rememberSharedContentState(key = "icon_${item.tokenRowUM.id}") + val titleSharedContentState = rememberSharedContentState(key = "title_${item.tokenRowUM.id}") val boundsTransform = BoundsTransform { _, _ -> tween(250) } AnimatedContent( @@ -382,7 +396,6 @@ internal fun PortfolioRowItem( ) } } - // } } }