Updated on 2026-08-14

This commit is contained in:
Tangem 2023-10-24 15:08:44 +03:00
parent e1fd5fc2d2
commit cd28b90873
15 changed files with 557 additions and 78 deletions

View file

@ -90,6 +90,7 @@
<string name="common_like">Нравится</string>
<string name="common_locked">Заблокирован</string>
<string name="common_main_network">Основная сеть</string>
<string name="common_next">Далее</string>
<string name="common_no">Нет</string>
<string name="common_no_address">Нет адреса</string>
<string name="common_no_data">Нет данных</string>

View file

@ -89,6 +89,7 @@
<string name="common_like">Like</string>
<string name="common_locked">Locked</string>
<string name="common_main_network">Main network</string>
<string name="common_next">Next</string>
<string name="common_no">No</string>
<string name="common_no_address">No address</string>
<string name="common_no_data">No data</string>
@ -114,7 +115,6 @@
<string name="common_submit">Submit</string>
<string name="common_success">Success</string>
<string name="common_swap">Swap</string>
<string name="common_next">Next</string>
<string name="common_terms_and_conditions">terms and conditions</string>
<string name="common_transaction_failed">Transaction failed</string>
<string name="common_transactions">Transactions</string>
@ -392,6 +392,7 @@
<string name="send_fee_picker_normal">Normal</string>
<string name="send_fee_picker_priority">Priority</string>
<string name="send_max_amount_label">Maximum amount</string>
<string name="send_max_amount">Max</string>
<string name="send_network_fee_title">Network fee</string>
<string name="send_title_currency_format">Sending %s</string>
<string name="send_total_label">Total</string>
@ -400,6 +401,7 @@
<string name="send_total_subtitle_format">%s will be sent</string>
<string name="send_transaction_success">Transaction has been successfully signed and sent to the blockchain node. Wallet balance will be updated in a while</string>
<string name="send_validation_invalid_address">Invalid address</string>
<string name="send_insufficient_funds">Insufficient funds for transfer</string>
<string name="shop_buy_now">Buy now</string>
<string name="shop_i_have_a_promo_code">I have a promo code…</string>
<string name="shop_one_wallet">Tangem Wallet</string>

View file

@ -7,11 +7,10 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.R
import com.tangem.core.ui.components.buttons.common.TangemButton
import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition
import com.tangem.core.ui.components.buttons.common.TangemButtonSize
import com.tangem.core.ui.components.buttons.common.*
import com.tangem.core.ui.components.buttons.common.TangemButtonsDefaults
import com.tangem.core.ui.res.TangemTheme
@ -146,6 +145,8 @@ fun SecondaryButton(
modifier: Modifier = Modifier,
showProgress: Boolean = false,
enabled: Boolean = true,
size: TangemButtonSize = TangemButtonSize.Default,
shape: Shape = size.toShape(),
) {
TangemButton(
modifier = modifier,
@ -155,6 +156,8 @@ fun SecondaryButton(
colors = TangemButtonsDefaults.secondaryButtonColors,
enabled = enabled,
showProgress = showProgress,
size = size,
shape = shape,
)
}

View file

@ -6,6 +6,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
@ -29,13 +30,14 @@ fun TangemButton(
size: TangemButtonSize = TangemButtonSize.Default,
elevation: ButtonElevation = TangemButtonsDefaults.elevation,
textStyle: TextStyle = TangemTheme.typography.button,
shape: Shape = size.toShape(),
) {
Button(
modifier = modifier.heightIn(min = size.toHeightDp()),
onClick = { if (!showProgress) onClick() },
enabled = enabled,
elevation = elevation,
shape = size.toShape(),
shape = shape,
colors = colors,
contentPadding = size.toContentPadding(icon = icon),
) {

View file

@ -0,0 +1,161 @@
package com.tangem.core.ui.components.buttons.segmentedbutton
import androidx.compose.foundation.LocalIndication
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import com.tangem.core.ui.res.TangemTheme
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.persistentListOf
/**
* Segmented buttons
*
* [Figma component](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=1961-2004&mode=design&t=OFPQ18YhLHVAANab-4)
*
* @param config list of buttons in SegmentedButtons
* @param onClick button click
* @param modifier component modifier
* @param color default button color
* @param selectedColor selected button color
* @param dividerColor border and divider color
* @param showIndication show ripple indication
* @param buttonContent content as separate button
*/
@Composable
inline fun <reified T> SegmentedButtons(
config: PersistentList<T>,
crossinline onClick: (T) -> Unit,
modifier: Modifier = Modifier,
color: Color = TangemTheme.colors.background.tertiary,
selectedColor: Color = TangemTheme.colors.background.action,
dividerColor: Color = TangemTheme.colors.stroke.primary,
showIndication: Boolean = true,
crossinline buttonContent: @Composable (T) -> Unit,
) {
if (config.isEmpty() || config.size == 1) return
var selected by remember { mutableIntStateOf(0) }
Row(
modifier = modifier
.clip(RoundedCornerShape(TangemTheme.dimens.radius26))
.background(dividerColor)
.padding(TangemTheme.dimens.spacing1),
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing1),
) {
repeat(config.size) { index ->
val leftRadius = if (index == 0) TangemTheme.dimens.radius26 else TangemTheme.dimens.radius0
val rightRadius = if (index == config.lastIndex) TangemTheme.dimens.radius26 else TangemTheme.dimens.radius0
Box(
modifier = Modifier
.weight(1f)
.background(
color = if (index == selected) selectedColor else color,
shape = RoundedCornerShape(
topStart = leftRadius,
topEnd = rightRadius,
bottomEnd = rightRadius,
bottomStart = leftRadius,
),
)
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = if (showIndication) LocalIndication.current else null,
) {
onClick(config[index])
selected = index
},
) {
buttonContent.invoke(config[index])
}
}
}
}
@Preview
@Composable
private fun SegmentedButtonsPreview_Light(
@PreviewParameter(SegmentedButtonsPreviewProvider::class) config: PersistentList<SegmentedButtonsConfigPreview>,
) {
TangemTheme {
SegmentedButtons(
config = config,
onClick = {},
) {
Text(
text = it.text,
modifier = Modifier.padding(TangemTheme.dimens.spacing16),
)
}
}
}
@Preview
@Composable
private fun SegmentedButtonsPreview_Dark(
@PreviewParameter(SegmentedButtonsPreviewProvider::class) config: PersistentList<SegmentedButtonsConfigPreview>,
) {
TangemTheme(isDark = true) {
SegmentedButtons(
config = config,
onClick = {},
) {
Text(
text = it.text,
modifier = Modifier.padding(TangemTheme.dimens.spacing16),
)
}
}
}
//region Preview config
/**
* Segmented buttons preview model
*
* @param text button title
*/
internal data class SegmentedButtonsConfigPreview(
val text: String,
)
/**
* Segmented button preview provider
*/
internal class SegmentedButtonsPreviewProvider :
CollectionPreviewParameterProvider<PersistentList<SegmentedButtonsConfigPreview>>(
collection = listOf(
persistentListOf(
SegmentedButtonsConfigPreview(
text = "Title 1",
),
SegmentedButtonsConfigPreview(
text = "Title 2",
),
SegmentedButtonsConfigPreview(
text = "Title 3",
),
),
persistentListOf(
SegmentedButtonsConfigPreview(
text = "Title 1",
),
SegmentedButtonsConfigPreview(
text = "Title 2",
),
),
),
)
//endregion

View file

@ -14,7 +14,11 @@ dependencies {
/** AndroidX */
implementation(deps.androidx.fragment.ktx)
implementation(deps.androidx.appCompat)
/** Other dependencies */
implementation(deps.kotlin.immutable.collections)
implementation(deps.material)
implementation(deps.arrow.core)
/** Compose */
implementation(deps.compose.accompanist.systemUiController)
@ -23,13 +27,23 @@ dependencies {
implementation(deps.compose.ui)
implementation(deps.compose.ui.tooling)
implementation(deps.compose.navigation)
implementation(deps.compose.navigation.hilt)
/** Common */
implementation(projects.common)
/** Core modules */
implementation(projects.core.featuretoggles)
implementation(projects.core.ui)
implementation(projects.core.utils)
/** Domain modules */
implementation(projects.domain.tokens)
implementation(projects.domain.tokens.models)
implementation(projects.domain.wallets)
implementation(projects.domain.wallets.models)
implementation(projects.domain.appCurrency)
implementation(projects.domain.appCurrency.models)
/** Feature modules */
implementation(projects.features.send.api)

View file

@ -0,0 +1,21 @@
package com.tangem.features.send.impl.presentation.send.state
import androidx.compose.runtime.Immutable
import com.tangem.core.ui.components.currency.tokenicon.TokenIconState
import com.tangem.core.ui.extensions.TextReference
/**
* Segmented buttons config
*
* @param title button title
* @param iconState currency icon state
* @param iconUrl currency icon url
* @param isFiat is fiat currency
*/
@Immutable
internal data class SendAmountSegmentedButtonsConfig(
val title: TextReference,
val iconState: TokenIconState? = null,
val iconUrl: String? = null,
val isFiat: Boolean,
)

View file

@ -0,0 +1,57 @@
package com.tangem.features.send.impl.presentation.send.state
import androidx.compose.runtime.Immutable
import com.tangem.core.ui.components.currency.tokenicon.TokenIconState
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.send.impl.presentation.send.state.fields.SendTextField
import kotlinx.collections.immutable.PersistentList
/**
* Ui states of the send screen
*/
@Immutable
internal sealed class SendUiState {
/** States with content */
sealed class Content : SendUiState() {
abstract val nextButtonEnabled: Boolean
/** Initial state */
data class Initial(
override val nextButtonEnabled: Boolean = false,
) : Content()
/** Amount state */
data class AmountState(
override val nextButtonEnabled: Boolean = false,
val walletName: String,
val walletBalance: String,
val tokenIconState: TokenIconState,
val cryptoCurrencyStatus: CryptoCurrencyStatus,
val appCurrency: AppCurrency,
val isFiatValue: Boolean,
val segmentedButtonConfig: PersistentList<SendAmountSegmentedButtonConfig>,
val amountTextField: SendTextField.Amount,
) : Content()
// todo [REDACTED_JIRA]
/** Recipient state */
data class RecipientState(
override val nextButtonEnabled: Boolean = false,
) : Content()
// todo [REDACTED_JIRA]
/** Fee and speed state */
data class FeeState(
override val nextButtonEnabled: Boolean = false,
) : Content()
// todo [REDACTED_JIRA]
/** Send state */
data class SendState(
override val nextButtonEnabled: Boolean = true,
) : Content()
}
}

View file

@ -0,0 +1,35 @@
package com.tangem.features.send.impl.presentation.send.state.fields
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.runtime.Immutable
import com.tangem.core.ui.extensions.TextReference
@Immutable
internal sealed class SendTextField {
/** Current value */
abstract val value: String
/** Lambda be invoked when value is been changed */
abstract val onValueChange: (String) -> Unit
/** Keyboard options */
abstract val keyboardOptions: KeyboardOptions
/** Label */
abstract val label: TextReference
/** Placeholder (hint) */
abstract val placeholder: TextReference
data class Amount(
override val value: String,
override val onValueChange: (String) -> Unit,
override val keyboardOptions: KeyboardOptions,
override val label: TextReference,
override val placeholder: TextReference,
val fiatValue: String,
val isError: Boolean,
val error: TextReference,
) : SendTextField()
}

View file

@ -1,7 +0,0 @@
package com.tangem.features.send.impl.presentation.send.ui
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
data class SendBottomSheetConfig(
val currentState: SendStates,
) : TangemBottomSheetConfigContent

View file

@ -18,17 +18,18 @@ import com.tangem.core.ui.R
import com.tangem.core.ui.components.PrimaryButton
import com.tangem.core.ui.components.PrimaryButtonIconEnd
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.send.impl.presentation.send.state.SendUiState
@Composable
internal fun SendNavigationButtons(currentState: SendStates) {
internal fun SendNavigationButtons(uiState: SendUiState.Content) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(bottom = TangemTheme.dimens.spacing12),
) {
SendSecondaryNavigationButton(currentState)
SendSecondaryNavigationButton(uiState)
SendPrimaryNavigationButton(
currentState,
uiState = uiState,
modifier = Modifier
.weight(1f)
.padding(horizontal = TangemTheme.dimens.spacing16),
@ -37,9 +38,9 @@ internal fun SendNavigationButtons(currentState: SendStates) {
}
@Composable
private fun SendSecondaryNavigationButton(currentState: SendStates) {
private fun SendSecondaryNavigationButton(uiState: SendUiState.Content) {
AnimatedVisibility(
visible = currentState == SendStates.Recipient || currentState == SendStates.Fee,
visible = uiState is SendUiState.Content.RecipientState || uiState is SendUiState.Content.FeeState,
) {
Icon(
modifier = Modifier
@ -57,40 +58,37 @@ private fun SendSecondaryNavigationButton(currentState: SendStates) {
}
@Composable
private fun SendPrimaryNavigationButton(currentState: SendStates, modifier: Modifier = Modifier) {
val buttonTextId = when (currentState) {
SendStates.Amount,
SendStates.Recipient,
SendStates.Fee,
private fun SendPrimaryNavigationButton(uiState: SendUiState.Content, modifier: Modifier = Modifier) {
val buttonTextId = when (uiState) {
is SendUiState.Content.AmountState,
is SendUiState.Content.RecipientState,
is SendUiState.Content.FeeState,
-> R.string.common_next
SendStates.Filled -> R.string.common_send
SendStates.Done -> R.string.common_close
is SendUiState.Content.SendState -> R.string.common_send
else -> R.string.common_close
}
AnimatedContent(
targetState = buttonTextId,
label = "Update send screen state",
modifier = modifier,
) { textId ->
when (currentState) {
SendStates.Amount,
SendStates.Recipient,
SendStates.Fee,
SendStates.Done,
-> PrimaryButton(
if (uiState is SendUiState.Content.SendState) {
PrimaryButtonIconEnd(
text = stringResource(textId),
iconResId = R.drawable.ic_tangem_24,
enabled = uiState.nextButtonEnabled,
onClick = {
// todo add next click
},
)
} else {
PrimaryButton(
text = stringResource(textId),
enabled = uiState.nextButtonEnabled,
onClick = {
// todo add next click
},
)
SendStates.Filled -> {
PrimaryButtonIconEnd(
text = stringResource(textId),
iconResId = R.drawable.ic_tangem_24,
onClick = {
// todo add next click
},
)
}
}
}
}

View file

@ -9,17 +9,14 @@ import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetDraggableHeader
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.send.impl.presentation.send.state.SendUiState
@Composable
fun SendScreen() {
// todo will be removed
val config = remember { SendBottomSheetConfig(SendStates.Amount) }
Column(
modifier = Modifier
.imePadding()
@ -42,7 +39,7 @@ fun SendScreen() {
) {
SendScreenContent()
}
SendNavigationButtons(config.currentState)
SendNavigationButtons(uiState = SendUiState.Content.Initial())
}
}

View file

@ -1,34 +0,0 @@
package com.tangem.features.send.impl.presentation.send.ui
/**
* Screen states of Send
*/
enum class SendStates {
Amount,
Recipient,
Fee,
Filled,
Done,
;
companion object {
/** Get next [SendStates] */
fun SendStates.next(): SendStates {
return if (this.ordinal < SendStates.values().last().ordinal) {
SendStates.values()[this.ordinal + 1]
} else {
this
}
}
/** Get previous [SendStates] */
fun SendStates.previous(): SendStates {
return if (this.ordinal > 0) {
SendStates.values()[this.ordinal - 1]
} else {
this
}
}
}
}

View file

@ -0,0 +1,168 @@
package com.tangem.features.send.impl.presentation.send.ui.amount
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Alignment.Companion.BottomCenter
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.input.OffsetMapping
import androidx.compose.ui.text.input.TransformedText
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.text.style.TextAlign
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.send.impl.presentation.send.state.fields.SendTextField
@Composable
internal fun ColumnScope.AmountField(
sendField: SendTextField.Amount,
cryptoSymbol: String,
fiatSymbol: String,
isFiat: Boolean,
) {
val value = if (isFiat) sendField.fiatValue else sendField.value
val secondaryValue = if (!isFiat) sendField.fiatValue else sendField.value
val symbol = if (isFiat) fiatSymbol else cryptoSymbol
val secondarySymbol = if (!isFiat) fiatSymbol else cryptoSymbol
AmountFieldInner(
value = value,
placeholder = sendField.placeholder,
symbol = symbol,
onValueChange = sendField.onValueChange,
keyboardOptions = sendField.keyboardOptions,
modifier = Modifier
.align(CenterHorizontally)
.padding(
top = TangemTheme.dimens.spacing24,
start = TangemTheme.dimens.spacing12,
end = TangemTheme.dimens.spacing12,
),
)
Box(
modifier = Modifier
.align(CenterHorizontally)
.padding(
top = TangemTheme.dimens.spacing8,
start = TangemTheme.dimens.spacing12,
end = TangemTheme.dimens.spacing12,
),
) {
Text(
text = "$secondaryValue $secondarySymbol",
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
textAlign = TextAlign.Center,
modifier = Modifier
.align(BottomCenter)
.padding(bottom = TangemTheme.dimens.spacing32),
)
AmountFieldError(
isError = sendField.isError,
error = sendField.error,
modifier = Modifier
.align(BottomCenter)
.padding(bottom = TangemTheme.dimens.spacing12),
)
}
}
@Composable
private fun AmountFieldInner(
value: String,
placeholder: TextReference,
symbol: String,
onValueChange: (String) -> Unit,
keyboardOptions: KeyboardOptions,
modifier: Modifier = Modifier,
) {
val focusRequester = remember { FocusRequester() }
BasicTextField(
value = value,
onValueChange = onValueChange,
modifier = modifier
.focusRequester(focusRequester)
.background(TangemTheme.colors.background.action),
textStyle = TangemTheme.typography.h2.copy(
color = TangemTheme.colors.text.primary1,
textAlign = TextAlign.Center,
),
keyboardOptions = keyboardOptions,
singleLine = true,
visualTransformation = AmountVisualTransformation(symbol),
decorationBox = { innerTextField ->
Box {
if (value.isBlank()) {
Text(
text = "${placeholder.resolveReference()} $symbol",
style = TangemTheme.typography.h2,
color = TangemTheme.colors.text.disabled,
textAlign = TextAlign.Center,
modifier = Modifier
.align(Alignment.TopCenter),
)
}
innerTextField()
}
},
)
}
@Composable
private fun AmountFieldError(isError: Boolean, error: TextReference, modifier: Modifier = Modifier) {
AnimatedVisibility(
visible = isError,
enter = fadeIn(),
exit = fadeOut(),
modifier = modifier,
) {
Text(
text = error.resolveReference(),
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.warning,
textAlign = TextAlign.Center,
)
}
}
private class AmountVisualTransformation(
private val symbol: String,
) : VisualTransformation {
override fun filter(text: AnnotatedString): TransformedText {
return TransformedText(
buildAnnotatedString {
append(text)
if (text.isNotBlank()) {
append(" ")
append(symbol)
}
},
object : OffsetMapping {
override fun originalToTransformed(offset: Int): Int {
return text.length
}
override fun transformedToOriginal(offset: Int): Int {
return text.length
}
},
)
}
}

View file

@ -0,0 +1,61 @@
package com.tangem.features.send.impl.presentation.send.ui.amount
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.text.style.TextAlign
import com.tangem.core.ui.components.currency.tokenicon.TokenIcon
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.send.impl.presentation.send.state.SendUiState
@Composable
internal fun AmountFieldContainer(amountState: SendUiState.Content.AmountState, modifier: Modifier = Modifier) {
Column(
modifier = modifier
.fillMaxWidth()
.padding(
top = TangemTheme.dimens.spacing4,
start = TangemTheme.dimens.spacing16,
end = TangemTheme.dimens.spacing16,
)
.clip(RoundedCornerShape(TangemTheme.dimens.radius16))
.background(TangemTheme.colors.background.action),
) {
Text(
text = amountState.walletName,
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.tertiary,
modifier = Modifier
.padding(top = TangemTheme.dimens.spacing14)
.align(Alignment.CenterHorizontally),
)
Text(
text = amountState.walletBalance,
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
textAlign = TextAlign.Center,
modifier = Modifier
.padding(top = TangemTheme.dimens.spacing2)
.align(Alignment.CenterHorizontally),
)
TokenIcon(
state = amountState.tokenIconState,
modifier = Modifier
.padding(top = TangemTheme.dimens.spacing32)
.align(Alignment.CenterHorizontally),
)
AmountField(
sendField = amountState.amountTextField,
cryptoSymbol = amountState.cryptoCurrencyStatus.currency.symbol,
fiatSymbol = amountState.appCurrency.symbol,
isFiat = amountState.isFiatValue,
)
}
}