diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/text/BladeAnimation.kt b/core/ui/src/main/java/com/tangem/core/ui/components/text/BladeAnimation.kt index 1d0dbc825f..b71c7e3dbf 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/text/BladeAnimation.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/text/BladeAnimation.kt @@ -20,13 +20,14 @@ data class BladeAnimation( @Composable fun rememberBladeAnimation(): BladeAnimation { - val infiniteTransition = rememberInfiniteTransition() + val infiniteTransition = rememberInfiniteTransition(label = "BladeAnimation") val offsetState = infiniteTransition.animateFloat( initialValue = 0f, targetValue = 1f, animationSpec = infiniteRepeatable( animation = tween(durationMillis = 1500, easing = LinearEasing), ), + label = "BladeOffset", ) return remember(offsetState) { @@ -37,51 +38,56 @@ fun rememberBladeAnimation(): BladeAnimation { @Suppress("MagicNumber") @Composable fun TextStyle.applyBladeBrush(isEnabled: Boolean, textColor: Color): TextStyle { - return if (isEnabled) { - val offset by LocalBladeAnimation.current.offsetState + val offsetState = LocalBladeAnimation.current.offsetState + val offset = if (isEnabled) offsetState.value else 0f - val brush = remember(offset, textColor) { - object : ShaderBrush() { - override fun createShader(size: Size): Shader { - val center = Offset(size.width / 2f, size.height / 2f) - val diagonal = sqrt(size.width * size.width + size.height * size.height) - // Subtle diagonal angle, similar to iOS shimmer - val direction = Offset(x = 1f, y = 0.3f) - - // Half-width of the blob (80% of diagonal total — wide, soft sweep) - val bandHalf = diagonal * 0.40f - - // Sweep the highlight center from left-of-element to right-of-element. - // offset 0..1 maps to a full pass including off-screen padding on both sides. - val shift = direction * ((offset - 0.5f) * diagonal * 1.5f) - val highlightCenter = center + shift - - // Full color text with a wide, gradual low-alpha dip sweeping left → right + val brush = remember(offset, textColor, isEnabled) { + object : ShaderBrush() { + override fun createShader(size: Size): Shader { + if (!isEnabled) { + // Solid color via the same shader path (LinearGradientShader needs >= 2 colors). return LinearGradientShader( - colors = listOf( - textColor, - textColor.copy(alpha = 0.75f), - textColor.copy(alpha = 0.45f), - textColor.copy(alpha = 0.3f), - textColor.copy(alpha = 0.45f), - textColor.copy(alpha = 0.75f), - textColor, - ), - from = highlightCenter - direction * bandHalf, - to = highlightCenter + direction * bandHalf, - colorStops = listOf(0f, 0.15f, 0.35f, 0.5f, 0.65f, 0.85f, 1f), + colors = listOf(textColor, textColor), + from = Offset.Zero, + to = Offset(size.width, size.height), tileMode = TileMode.Clamp, ) } + + val center = Offset(size.width / 2f, size.height / 2f) + val diagonal = sqrt(size.width * size.width + size.height * size.height) + // Subtle diagonal angle, similar to iOS shimmer + val direction = Offset(x = 1f, y = 0.3f) + + // Half-width of the blob (80% of diagonal total — wide, soft sweep) + val bandHalf = diagonal * 0.40f + + // Sweep the highlight center from left-of-element to right-of-element. + // offset 0..1 maps to a full pass including off-screen padding on both sides. + val shift = direction * ((offset - 0.5f) * diagonal * 1.5f) + val highlightCenter = center + shift + + // Full color text with a wide, gradual low-alpha dip sweeping left → right + return LinearGradientShader( + colors = listOf( + textColor, + textColor.copy(alpha = 0.75f), + textColor.copy(alpha = 0.45f), + textColor.copy(alpha = 0.3f), + textColor.copy(alpha = 0.45f), + textColor.copy(alpha = 0.75f), + textColor, + ), + from = highlightCenter - direction * bandHalf, + to = highlightCenter + direction * bandHalf, + colorStops = listOf(0f, 0.15f, 0.35f, 0.5f, 0.65f, 0.85f, 1f), + tileMode = TileMode.Clamp, + ) } } - - this.copy(brush = brush) - } else { - this.copy( - color = textColor, - ) } + + return this.copy(brush = brush) } @Preview(showBackground = true) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletBalance.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletBalance.kt index e381e363ee..cdb2f79b77 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletBalance.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletBalance.kt @@ -167,6 +167,7 @@ private fun SubtitleRow(walletBalanceUM: WalletBalanceUM, modifier: Modifier = M private fun Balance(walletBalanceUM: WalletBalanceUM, isBalanceHidden: Boolean, modifier: Modifier = Modifier) { AnimatedContent( targetState = walletBalanceUM, + contentKey = { it::class }, label = "Update the balance", modifier = modifier.testTag(MainScreenTestTags.WALLET_BALANCE), transitionSpec = {