From a285866cab4ef01300549dd205eb1c4892896364 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 29 Sep 2023 18:44:50 +0800 Subject: [PATCH] Updated on 2026-08-14 --- .../common/component/token/LockedRectangle.kt | 2 +- .../common/component/token/icon/TokenIcon.kt | 2 +- .../components/WalletBottomSheetConfig.kt | 4 - .../state/components/WalletTokensListState.kt | 7 +- .../ui/components/common/WalletBottomSheet.kt | 24 ++---- .../multicurrency/MultiCurrencyContent.kt | 11 +-- .../wallet/ui/utils/ChangeWalletAnimator.kt | 83 +++++++++++++++++++ .../ui/utils/WalletContentItemAnimator.kt | 76 ----------------- 8 files changed, 98 insertions(+), 111 deletions(-) create mode 100644 features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/utils/ChangeWalletAnimator.kt delete mode 100644 features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/utils/WalletContentItemAnimator.kt diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/component/token/LockedRectangle.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/component/token/LockedRectangle.kt index cf31ecffca..238d2ebb0d 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/component/token/LockedRectangle.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/component/token/LockedRectangle.kt @@ -11,7 +11,7 @@ import com.tangem.core.ui.res.TangemTheme internal fun LockedRectangle(modifier: Modifier = Modifier) { Box( modifier = modifier.background( - color = TangemTheme.colors.background.secondary, + color = TangemTheme.colors.field.primary, shape = RoundedCornerShape(TangemTheme.dimens.radius4), ), ) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/component/token/icon/TokenIcon.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/component/token/icon/TokenIcon.kt index 9a5cd1bee0..fce5631f81 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/component/token/icon/TokenIcon.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/component/token/icon/TokenIcon.kt @@ -52,7 +52,7 @@ private fun LockedIcon(modifier: Modifier = Modifier) { modifier = Modifier .matchParentSize() .background( - color = TangemTheme.colors.background.secondary, + color = TangemTheme.colors.field.primary, shape = CircleShape, ), ) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/components/WalletBottomSheetConfig.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/components/WalletBottomSheetConfig.kt index 44d45cf615..271da5128b 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/components/WalletBottomSheetConfig.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/components/WalletBottomSheetConfig.kt @@ -1,12 +1,10 @@ package com.tangem.feature.wallet.presentation.wallet.state.components import androidx.annotation.DrawableRes -import androidx.compose.ui.graphics.Color import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.wrappedList -import com.tangem.core.ui.res.TangemColorPalette import com.tangem.feature.wallet.impl.R /** @@ -18,7 +16,6 @@ sealed class WalletBottomSheetConfig( open val title: TextReference, open val subtitle: TextReference, @DrawableRes open val iconResId: Int, - open val tint: Color? = null, val primaryButtonConfig: ButtonConfig, val secondaryButtonConfig: ButtonConfig, ) : TangemBottomSheetConfigContent { @@ -38,7 +35,6 @@ sealed class WalletBottomSheetConfig( ), ), iconResId = R.drawable.ic_locked_24, - tint = TangemColorPalette.Black, primaryButtonConfig = ButtonConfig( text = resourceReference(id = R.string.user_wallet_list_unlock_all), onClick = onUnlockClick, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/components/WalletTokensListState.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/components/WalletTokensListState.kt index b81f513cc0..fe750ba585 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/components/WalletTokensListState.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/components/WalletTokensListState.kt @@ -33,10 +33,7 @@ internal sealed class WalletTokensListState { * @property items content items */ data class Loading( - override val items: ImmutableList = persistentListOf( - TokensListItemState.Token(state = TokenItemState.Loading(id = FIRST_LOADING_TOKEN_ID)), - TokensListItemState.Token(state = TokenItemState.Loading(id = SECOND_LOADING_TOKEN_ID)), - ), + override val items: ImmutableList = persistentListOf(), ) : ContentState(items = items, organizeTokensButton = OrganizeTokensButtonState.Hidden) /** @@ -107,8 +104,6 @@ internal sealed class WalletTokensListState { } private companion object { - const val FIRST_LOADING_TOKEN_ID = "Loading#1" - const val SECOND_LOADING_TOKEN_ID = "Loading#2" const val LOCKED_TOKEN_ID = "Locked#1" } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletBottomSheet.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletBottomSheet.kt index 8794acf686..a5e778dce6 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletBottomSheet.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletBottomSheet.kt @@ -1,6 +1,5 @@ package com.tangem.feature.wallet.presentation.wallet.ui.components.common -import androidx.compose.foundation.Image import androidx.compose.foundation.layout.* import androidx.compose.material3.* import androidx.compose.runtime.Composable @@ -47,21 +46,14 @@ private fun BottomSheetContent(config: WalletBottomSheetConfig) { verticalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing40), horizontalAlignment = Alignment.CenterHorizontally, ) { - val iconTint = config.tint - if (iconTint != null) { - Icon( - painter = painterResource(id = config.iconResId), - contentDescription = null, - modifier = Modifier.size(size = TangemTheme.dimens.size48), - tint = iconTint, - ) - } else { - Image( - painter = painterResource(id = config.iconResId), - contentDescription = null, - modifier = Modifier.size(size = TangemTheme.dimens.size48), - ) - } + Icon( + painter = painterResource(id = config.iconResId), + contentDescription = null, + modifier = Modifier.size(size = TangemTheme.dimens.size48), + tint = when (config) { + is WalletBottomSheetConfig.UnlockWallets -> TangemTheme.colors.icon.primary1 + }, + ) Text( text = config.title.resolveReference(), 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 1330515bf4..9bdaf10b43 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 @@ -37,7 +37,6 @@ internal fun LazyListScope.tokensListItems(state: WalletTokensListState, modifie } } -@OptIn(ExperimentalFoundationApi::class) private fun LazyListScope.contentItems( items: ImmutableList, modifier: Modifier = Modifier, @@ -49,12 +48,10 @@ private fun LazyListScope.contentItems( itemContent = { index, item -> MultiCurrencyContentItem( state = item, - modifier = modifier - .animateItemPlacement() - .roundedShapeItemDecoration( - currentIndex = index, - lastIndex = items.lastIndex, - ), + modifier = modifier.roundedShapeItemDecoration( + currentIndex = index, + lastIndex = items.lastIndex, + ), ) }, ) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/utils/ChangeWalletAnimator.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/utils/ChangeWalletAnimator.kt new file mode 100644 index 0000000000..d211e051f1 --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/utils/ChangeWalletAnimator.kt @@ -0,0 +1,83 @@ +package com.tangem.feature.wallet.presentation.wallet.ui.utils + +import androidx.compose.animation.core.animateDpAsState +import androidx.compose.animation.core.animateFloatAsState +import androidx.compose.foundation.layout.absoluteOffset +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.runtime.* +import androidx.compose.ui.Modifier +import androidx.compose.ui.composed +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.coerceIn +import androidx.compose.ui.unit.dp +import kotlin.math.sin + +private val minOffset = 0.dp +private val maxOffset = 40.dp + +private const val MIN_ALPHA = 0f +private const val MAX_ALPHA = 1f + +private const val PI = Math.PI.toFloat() +private const val HALF_PI = PI / 2 +private const val DOUBLE_PI = 2 * PI + +private const val Y_AXIS_OFFSET = 0.5f +private const val AMPLITUDE_MULTIPLIER = 0.5f + +/** + * Modifier extension for setting [absoluteOffset] and [alpha] animations of wallet change + * + * @param lazyListState lazy list state + * +[REDACTED_AUTHOR] + */ +internal fun Modifier.changeWalletAnimator(lazyListState: LazyListState) = composed { + val offset by remember(lazyListState) { derivedStateOf { lazyListState.firstVisibleItemScrollOffset } } + + val size by remember(lazyListState) { + derivedStateOf { lazyListState.layoutInfo.visibleItemsInfo.firstOrNull()?.size ?: 1 } + } + + val contentOffsetY by rememberOffsetY(offset = offset, size = size) + val contentAlpha by rememberAlpha(offset = offset, size = size) + + val animatedOffsetY by animateDpAsState(targetValue = contentOffsetY, label = "offsetY") + val animatedContentAlpha by animateFloatAsState(targetValue = contentAlpha, label = "alpha") + + this + .absoluteOffset(y = animatedOffsetY) + .alpha(alpha = animatedContentAlpha) +} + +/** + * y = ANIMATION_MAX_OFFSET_IN_DP.dp * sin(π / size * offset) + * + * @see Graphic + */ +@Composable +private fun rememberOffsetY(offset: Int, size: Int): State { + return remember(offset) { + derivedStateOf { + val y = maxOffset * sin(x = PI / size * offset) + y.coerceIn(minimumValue = minOffset, maximumValue = maxOffset) + } + } +} + +/** + * y = 0.5 * sin(2 * pi / size * offset + pi / 2) + 0.5 + * + * @see Graphic + */ +@Composable +private fun rememberAlpha(offset: Int, size: Int): State { + return remember(offset) { + derivedStateOf { + val y = AMPLITUDE_MULTIPLIER * sin(x = DOUBLE_PI / size * offset + HALF_PI) + Y_AXIS_OFFSET + y.coerceIn(MIN_ALPHA, MAX_ALPHA) + } + } +} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/utils/WalletContentItemAnimator.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/utils/WalletContentItemAnimator.kt deleted file mode 100644 index 61a190a01f..0000000000 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/utils/WalletContentItemAnimator.kt +++ /dev/null @@ -1,76 +0,0 @@ -package com.tangem.feature.wallet.presentation.wallet.ui.utils - -import androidx.compose.animation.core.animateDpAsState -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.foundation.layout.absoluteOffset -import androidx.compose.foundation.lazy.LazyListState -import androidx.compose.runtime.derivedStateOf -import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.composed -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.unit.dp - -private const val ANIMATION_MAX_OFFSET_IN_DP = 80 -private const val ANIMATION_MAX_ALPHA = 1f - -/** - * Modifier extension for setting [absoluteOffset] and [alpha] animations of wallet change - * - * @param lazyListState lazy list state - * -[REDACTED_AUTHOR] - */ -internal fun Modifier.changeWalletAnimator(lazyListState: LazyListState) = composed { - val walletItemOffset by remember(lazyListState) { derivedStateOf { lazyListState.firstVisibleItemScrollOffset } } - - val walletItemSize by remember(lazyListState) { - derivedStateOf { lazyListState.layoutInfo.visibleItemsInfo.firstOrNull()?.size ?: 1 } - } - - val walletHalfItemSize by remember { - derivedStateOf { walletItemSize / 2 } - } - - val contentOffsetY by remember { - derivedStateOf { - /* - * Until [walletItemOffset] is less than [walletHalfItemSize], - * then content offset animation has positive value (downward movement). - * Otherwise, it has negative value (upward movement). - */ - val position = if (walletItemOffset < walletHalfItemSize) { - walletItemOffset - } else { - walletItemSize - walletItemOffset - } - - ANIMATION_MAX_OFFSET_IN_DP.dp / walletItemSize * position - } - } - - val contentAlpha by remember { - derivedStateOf { - /* - * Until [walletItemOffset] is less than [walletHalfItemSize], - * then content alpha animation has negative value (fade out). - * Otherwise, it has positive value (fade in). - */ - val position = if (walletItemOffset < walletHalfItemSize) { - walletHalfItemSize - walletItemOffset - } else { - walletItemOffset - walletHalfItemSize - } - - ANIMATION_MAX_ALPHA / walletHalfItemSize * position - } - } - - val animatedOffsetY by animateDpAsState(targetValue = contentOffsetY) - val animatedContentAlpha by animateFloatAsState(targetValue = contentAlpha) - - this - .absoluteOffset(y = animatedOffsetY) - .alpha(alpha = animatedContentAlpha) -} \ No newline at end of file