From ece19b66991c2bff4b4074bee224961fe280131a Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 3 Oct 2024 14:05:38 +0400 Subject: [PATCH 1/2] Updated on 2026-08-14 --- .../component/preview/PreviewCustomTokenSelectorComponent.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/component/preview/PreviewCustomTokenSelectorComponent.kt b/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/component/preview/PreviewCustomTokenSelectorComponent.kt index baef39e2e5..8f129079e2 100644 --- a/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/component/preview/PreviewCustomTokenSelectorComponent.kt +++ b/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/component/preview/PreviewCustomTokenSelectorComponent.kt @@ -55,8 +55,8 @@ internal class PreviewCustomTokenSelectorComponent( network = Network( id = n.id, backendId = n.id.value, - name = "", - currencySymbol = "", + name = "Network $index", + currencySymbol = "N$index", derivationPath = Network.DerivationPath.Card(""), isTestnet = false, standardType = Network.StandardType.ERC20, From c04df51ca908a350ba8c46d0ab1b4008be7a8062 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 3 Oct 2024 14:05:53 +0400 Subject: [PATCH 2/2] Updated on 2026-08-14 --- .../tangem/core/ui/components/FadeModifier.kt | 89 +++++++++++++++++++ .../managetokens/ui/CustomTokenFormContent.kt | 26 ++++-- .../ui/CustomTokenSelectorContent.kt | 10 ++- 3 files changed, 112 insertions(+), 13 deletions(-) create mode 100644 core/ui/src/main/java/com/tangem/core/ui/components/FadeModifier.kt diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/FadeModifier.kt b/core/ui/src/main/java/com/tangem/core/ui/components/FadeModifier.kt new file mode 100644 index 0000000000..03d9ba11c0 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/components/FadeModifier.kt @@ -0,0 +1,89 @@ +package com.tangem.core.ui.components + +import androidx.compose.animation.core.AnimationSpec +import androidx.compose.animation.core.animateDpAsState +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.systemBars +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.ui.Modifier +import androidx.compose.ui.composed +import androidx.compose.ui.draw.drawWithContent +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.tangem.core.ui.res.TangemTheme + +@Composable +fun Modifier.edgeFade( + vararg positions: FadePosition, + size: Dp, + isVisible: Boolean = true, + animationSpec: AnimationSpec? = null, + color: Color = TangemTheme.colors.background.secondary, +): Modifier = composed { + require(value = size > 0.dp) { + "Size must be greater than '0'" + } + val animatedSize = animationSpec?.let { + animateDpAsState( + targetValue = if (isVisible) size else 0.dp, + animationSpec = it, + label = "Edge fade width", + ) + } + + drawWithContent { + drawContent() + + positions.forEach { side -> + val (start, end) = this.size.getFadeOffsets(side) + + val staticSizePx = if (isVisible) size.toPx() else 0f + val sizePx = animatedSize?.value?.toPx() ?: staticSizePx + + val fraction = when (side) { + FadePosition.LEFT, FadePosition.RIGHT -> sizePx / this.size.width + FadePosition.BOTTOM, FadePosition.TOP -> sizePx / this.size.height + } + + drawRect( + brush = Brush.linearGradient( + 0f to color, + fraction to Color.Transparent, + start = start, + end = end, + ), + size = this.size, + ) + } + } +} + +@Composable +fun Modifier.bottomFade( + height: Dp = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() } + 96.dp, + color: Color = TangemTheme.colors.background.secondary, +): Modifier = edgeFade( + FadePosition.BOTTOM, + size = height, + color = color, +) + +enum class FadePosition { + TOP, BOTTOM, LEFT, RIGHT; +} + +@Stable +private fun Size.getFadeOffsets(position: FadePosition): Pair { + return when (position) { + FadePosition.LEFT -> Offset.Zero to Offset(width, 0f) + FadePosition.RIGHT -> Offset(width, y = 0f) to Offset.Zero + FadePosition.BOTTOM -> Offset(x = 0f, height) to Offset.Zero + FadePosition.TOP -> Offset.Zero to Offset(x = 0f, height) + } +} \ No newline at end of file diff --git a/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/ui/CustomTokenFormContent.kt b/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/ui/CustomTokenFormContent.kt index 04e750f95c..5f5798395b 100644 --- a/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/ui/CustomTokenFormContent.kt +++ b/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/ui/CustomTokenFormContent.kt @@ -20,9 +20,11 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import androidx.compose.ui.unit.dp import androidx.compose.ui.util.fastForEach import com.tangem.core.ui.components.PrimaryButton import com.tangem.core.ui.components.block.information.InformationBlock +import com.tangem.core.ui.components.bottomFade import com.tangem.core.ui.components.fields.SimpleTextField import com.tangem.core.ui.components.isOpened import com.tangem.core.ui.components.keyboardAsState @@ -60,18 +62,24 @@ internal fun CustomTokenFormContent(model: CustomTokenFormUM, modifier: Modifier .fillMaxSize() .background(color = TangemTheme.colors.background.secondary), ) { - val scrollState = rememberScrollState() - - Column( + Box( modifier = Modifier - .verticalScroll(scrollState) .fillMaxSize() - .padding(bottom = TangemTheme.dimens.spacing76), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing16), + .bottomFade(), ) { - AddCustomTokenDescription() - FormContent(model) + val scrollState = rememberScrollState() + + Column( + modifier = Modifier + .verticalScroll(scrollState) + .fillMaxSize() + .padding(bottom = 128.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing16), + ) { + AddCustomTokenDescription() + FormContent(model) + } } PrimaryButton( diff --git a/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/ui/CustomTokenSelectorContent.kt b/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/ui/CustomTokenSelectorContent.kt index 4196a9c491..21f3daf5e1 100644 --- a/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/ui/CustomTokenSelectorContent.kt +++ b/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/ui/CustomTokenSelectorContent.kt @@ -21,7 +21,9 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import androidx.compose.ui.unit.dp import com.tangem.core.ui.components.block.information.InformationBlock +import com.tangem.core.ui.components.bottomFade import com.tangem.core.ui.components.currency.icon.CurrencyIconState import com.tangem.core.ui.components.rows.ChainRow import com.tangem.core.ui.components.rows.model.ChainRowUM @@ -46,11 +48,11 @@ internal fun CustomTokenSelectorContent(model: CustomTokenSelectorUM, modifier: val lastIndex = model.items.lastIndex LazyColumn( - modifier = modifier.background( - color = TangemTheme.colors.background.secondary, - ), + modifier = modifier + .background(color = TangemTheme.colors.background.secondary) + .bottomFade(), contentPadding = PaddingValues( - bottom = TangemTheme.dimens.spacing16 + bottomBarHeight, + bottom = 96.dp + bottomBarHeight, ), ) { item {