Updated on 2026-08-14

This commit is contained in:
Tangem 2025-06-24 14:43:38 +05:00
parent 22ad2ddc67
commit 281b5ec956
13 changed files with 371 additions and 20 deletions

View file

@ -0,0 +1,180 @@
package com.tangem.common.ui.amountScreen.ui
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.material.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.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.common.ui.R
import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.common.ui.amountScreen.preview.AmountStatePreviewData
import com.tangem.core.ui.components.currency.icon.CurrencyIcon
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.format.bigdecimal.crypto
import com.tangem.core.ui.format.bigdecimal.fiat
import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
@Composable
fun AmountBlockV2(
amountState: AmountState,
currencyIconState: CurrencyIconState,
isClickDisabled: Boolean,
isEditingDisabled: Boolean,
onClick: () -> Unit,
modifier: Modifier = Modifier,
) {
if (amountState !is AmountState.Data) return
val amount = amountState.amountTextField
val cryptoAmount = amount.cryptoAmount.value?.format {
crypto(
symbol = "",
decimals = amount.cryptoAmount.decimals,
)
}.orEmpty()
val fiatAmount = amount.fiatAmount.value.format {
fiat(
fiatCurrencySymbol = amount.fiatAmount.currencySymbol,
fiatCurrencyCode = amountState.appCurrency.code,
)
}
val (firstAmount, secondAmount) = if (amount.isFiatValue) {
fiatAmount to cryptoAmount
} else {
cryptoAmount to fiatAmount
}
val title = TextReference.Str(
stringResourceSafe(
R.string.send_from_wallet_name,
amountState.title
.resolveReference(),
),
)
val currencyTitle = amount.cryptoAmount.currencySymbol
AmountBlockV2(
title = title,
balance = amountState.availableBalance,
currencyTitle = currencyTitle,
currencyIconState = currencyIconState,
firstAmount = firstAmount,
secondAmount = secondAmount,
isClickDisabled = isClickDisabled,
isEditingDisabled = isEditingDisabled,
onClick = onClick,
modifier = modifier,
)
}
@Suppress("LongParameterList")
@Composable
internal fun AmountBlockV2(
title: TextReference,
balance: TextReference,
currencyTitle: String,
currencyIconState: CurrencyIconState,
firstAmount: String,
secondAmount: String,
isClickDisabled: Boolean,
isEditingDisabled: Boolean,
onClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier
.clip(TangemTheme.shapes.roundedCornersXMedium)
.background(TangemTheme.colors.background.action)
.clickable(enabled = !isClickDisabled && !isEditingDisabled, onClick = onClick)
.padding(TangemTheme.dimens.spacing16),
) {
Row {
Text(
text = title.resolveReference(),
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.tertiary,
)
Spacer(modifier = modifier.weight(1f))
Text(
text = balance.resolveReference(),
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.tertiary,
)
}
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth(),
) {
Column(
verticalArrangement = Arrangement.spacedBy(4.dp),
modifier = Modifier.padding(top = 8.dp),
) {
Text(
text = firstAmount,
style = TangemTheme.typography.h2,
color = TangemTheme.colors.text.primary1,
)
Text(
text = secondAmount,
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.tertiary,
)
}
Column(
verticalArrangement = Arrangement.spacedBy(2.dp),
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.padding(top = 6.dp),
) {
CurrencyIcon(
state = currencyIconState,
modifier = Modifier.padding(horizontal = 14.dp),
)
Text(
text = currencyTitle,
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.primary1,
)
}
}
}
}
// region Preview
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun AmountBlockPreview(@PreviewParameter(AmountBlockV2PreviewProvider::class) value: AmountState) {
TangemThemePreview {
AmountBlockV2(
amountState = value,
currencyIconState = CurrencyIconState.Empty(),
isClickDisabled = false,
isEditingDisabled = false,
onClick = {},
)
}
}
private class AmountBlockV2PreviewProvider : PreviewParameterProvider<AmountState> {
override val values: Sequence<AmountState>
get() = sequenceOf(
AmountStatePreviewData.amountState,
)
}
// endregion

View file

@ -822,6 +822,7 @@
<string name="send_fee_unreachable_error_text">Check your network connection</string> <string name="send_fee_unreachable_error_text">Check your network connection</string>
<string name="send_fee_unreachable_error_title">Network fee info unreachable</string> <string name="send_fee_unreachable_error_title">Network fee info unreachable</string>
<string name="send_from_wallet_android">From</string> <string name="send_from_wallet_android">From</string>
<string name="send_from_wallet_name">From %s</string>
<string name="send_gas_limit">Gas limit</string> <string name="send_gas_limit">Gas limit</string>
<string name="send_gas_limit_footer">This is the maximum amount of gas that will be spent to complete a transaction or contract. A gas limit prevents unexpected or unlimited charges when executing a transaction.</string> <string name="send_gas_limit_footer">This is the maximum amount of gas that will be spent to complete a transaction or contract. A gas limit prevents unexpected or unlimited charges when executing a transaction.</string>
<string name="send_gas_price">Gas price</string> <string name="send_gas_price">Gas price</string>
@ -829,6 +830,7 @@
<string name="send_max_amount">Max</string> <string name="send_max_amount">Max</string>
<string name="send_max_amount_label">Maximum amount</string> <string name="send_max_amount_label">Maximum amount</string>
<string name="send_max_fee">Fee up to</string> <string name="send_max_fee">Fee up to</string>
<string name="send_memo">Memo: %s</string>
<string name="send_memo_destination_tag_error">Invalid Memo</string> <string name="send_memo_destination_tag_error">Invalid Memo</string>
<string name="send_network_fee_warning_title">Network fee coverage</string> <string name="send_network_fee_warning_title">Network fee coverage</string>
<string name="send_nonce">Nonce</string> <string name="send_nonce">Nonce</string>
@ -879,6 +881,7 @@
<string name="send_summary_transaction_description_suffix_fee_covered">network fee will be covered by using %1$s energy</string> <string name="send_summary_transaction_description_suffix_fee_covered">network fee will be covered by using %1$s energy</string>
<string name="send_summary_transaction_description_suffix_fee_reduced">network fee will be reduced by spending %1$s energy</string> <string name="send_summary_transaction_description_suffix_fee_reduced">network fee will be reduced by spending %1$s energy</string>
<string name="send_summary_transaction_description_suffix_including">including a network fee of %1$s</string> <string name="send_summary_transaction_description_suffix_including">including a network fee of %1$s</string>
<string name="send_to_address">To address</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_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_tron_account_activation_error">%1$s is an asset in the Tron network. To calculate the fee and make a transaction you need to deposit some Tron (TRX) in your account.</string> <string name="send_tron_account_activation_error">%1$s is an asset in the Tron network. To calculate the fee and make a transaction you need to deposit some Tron (TRX) in your account.</string>
<string name="send_validation_amount_exceeds_balance">Amount exceeds balance</string> <string name="send_validation_amount_exceeds_balance">Amount exceeds balance</string>
@ -888,6 +891,7 @@
<string name="send_validation_invalid_fee">Fee exceeds balance</string> <string name="send_validation_invalid_fee">Fee exceeds balance</string>
<string name="send_validation_invalid_total">Total amount exceeds balance</string> <string name="send_validation_invalid_total">Total amount exceeds balance</string>
<string name="send_with_swap_notification_text">Send any token, and well convert it on the way. Your recipient gets exactly what they need—seamlessly.</string> <string name="send_with_swap_notification_text">Send any token, and well convert it on the way. Your recipient gets exactly what they need—seamlessly.</string>
<string name="send_with_swap_recipient_amount_text">Will be sent a recipient</string>
<string name="send_with_swap_title">Send with swap</string> <string name="send_with_swap_title">Send with swap</string>
<string name="sent_transaction_sent_title">Transaction sent</string> <string name="sent_transaction_sent_title">Transaction sent</string>
<string name="settings_card_settings_footer">Prepare to scan card or ring you want to set up.</string> <string name="settings_card_settings_footer">Prepare to scan card or ring you want to set up.</string>

View file

@ -1,10 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="16dp" android:viewportHeight="24" android:viewportWidth="24" android:width="16dp">
android:width="16dp"
android:height="17dp" <path android:fillColor="#1E1E1E" android:fillType="evenOdd" android:pathData="M10,3H6C4.343,3 3,4.343 3,6V10.5H5V6C5,5.448 5.448,5 6,5H10V3ZM3,15V18C3,19.657 4.343,21 6,21H10V19H6C5.448,19 5,18.552 5,18V15H19V18C19,18.552 18.552,19 18,19H14V21H18C19.657,21 21,19.657 21,18V15H22V13H2V15H3ZM21,6V10.5H19V6C19,5.448 18.552,5 18,5H14V3H18C19.657,3 21,4.343 21,6Z"/>
android:viewportWidth="16"
android:viewportHeight="17">
<path
android:pathData="M6.666,2.391H4C2.895,2.391 2,3.287 2,4.391V7.391L3.333,7.391V4.391C3.333,4.023 3.631,3.725 4,3.725H6.666V2.391ZM2,10.391V12.391C2,13.496 2.895,14.391 4,14.391H6.666V13.058H4C3.631,13.058 3.333,12.759 3.333,12.391V10.391H12.666V12.391C12.666,12.759 12.368,13.058 12,13.058H9.333V14.391H12C13.104,14.391 14,13.496 14,12.391V10.391H14.666V9.058H1.333V10.391H2ZM14,4.391V7.391H12.666V4.391C12.666,4.023 12.368,3.725 12,3.725H9.333V2.391H12C13.104,2.391 14,3.287 14,4.391Z"
android:fillColor="#1E1E1E"
android:fillType="evenOdd"/>
</vector> </vector>

View file

@ -206,6 +206,7 @@ internal class DefaultSendComponent @AssistedInject constructor(
childStack = childStack, childStack = childStack,
) )
}, },
isRedesignEnabled = model.uiState.value.isRedesignEnabled,
), ),
) )
} else { } else {
@ -225,6 +226,7 @@ internal class DefaultSendComponent @AssistedInject constructor(
return if (sendAmount != null && destinationAddress != null && return if (sendAmount != null && destinationAddress != null &&
feeCryptoCurrencyStatus != null && cryptoCurrencyStatus != null feeCryptoCurrencyStatus != null && cryptoCurrencyStatus != null
) { ) {
// TODO Apply new component [REDACTED_TASK_KEY]
SendFeeComponent( SendFeeComponent(
appComponentContext = factoryContext, appComponentContext = factoryContext,
params = SendFeeComponentParams.FeeParams( params = SendFeeComponentParams.FeeParams(

View file

@ -65,6 +65,7 @@ internal class SendConfirmComponent(
appCurrency = params.appCurrency, appCurrency = params.appCurrency,
blockClickEnableFlow = blockClickEnableFlow.asStateFlow(), blockClickEnableFlow = blockClickEnableFlow.asStateFlow(),
predefinedValues = params.predefinedValues, predefinedValues = params.predefinedValues,
isRedesignEnabled = model.uiState.value.isRedesignEnabled,
), ),
onResult = model::onAmountResult, onResult = model::onAmountResult,
onClick = model::showEditAmount, onClick = model::showEditAmount,

View file

@ -454,6 +454,7 @@ internal class SendConfirmModel @Inject constructor(
} }
} }
@Suppress("LongMethod")
private fun configConfirmNavigation() { private fun configConfirmNavigation() {
combine( combine(
flow = uiState, flow = uiState,
@ -470,7 +471,11 @@ internal class SendConfirmModel @Inject constructor(
id = R.string.send_summary_title, id = R.string.send_summary_title,
formatArgs = wrappedList(params.cryptoCurrencyStatus.currency.name), formatArgs = wrappedList(params.cryptoCurrencyStatus.currency.name),
), ),
subtitle = amountUM?.title, subtitle = if (uiState.value.isRedesignEnabled) {
null
} else {
amountUM?.title
},
backIconRes = R.drawable.ic_close_24, backIconRes = R.drawable.ic_close_24,
backIconClick = { backIconClick = {
analyticsEventHandler.send( analyticsEventHandler.send(

View file

@ -98,8 +98,13 @@ private fun LazyListScope.blocks(
modifier = Modifier.padding(vertical = 12.dp), modifier = Modifier.padding(vertical = 12.dp),
) )
} }
if (uiState.isRedesignEnabled) {
amountBlockComponent.Content(modifier = Modifier)
destinationBlockComponent.Content(modifier = Modifier)
} else {
destinationBlockComponent.Content(modifier = Modifier) destinationBlockComponent.Content(modifier = Modifier)
amountBlockComponent.Content(modifier = Modifier) amountBlockComponent.Content(modifier = Modifier)
}
feeBlockComponent.Content(modifier = Modifier) feeBlockComponent.Content(modifier = Modifier)
} }
} }

View file

@ -364,5 +364,6 @@ internal class SendModel @Inject constructor(
feeUM = FeeUM.Empty(), feeUM = FeeUM.Empty(),
confirmUM = ConfirmUM.Empty, confirmUM = ConfirmUM.Empty,
navigationUM = NavigationUM.Empty, navigationUM = NavigationUM.Empty,
isRedesignEnabled = sendFeatureToggles.isSendRedesignEnabled,
) )
} }

View file

@ -12,4 +12,5 @@ internal data class SendUM(
val feeUM: FeeUM, val feeUM: FeeUM,
val confirmUM: ConfirmUM, val confirmUM: ConfirmUM,
val navigationUM: NavigationUM, val navigationUM: NavigationUM,
val isRedesignEnabled: Boolean,
) )

View file

@ -6,6 +6,7 @@ import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.common.ui.amountScreen.models.AmountState import com.tangem.common.ui.amountScreen.models.AmountState
import com.tangem.common.ui.amountScreen.ui.AmountBlock import com.tangem.common.ui.amountScreen.ui.AmountBlock
import com.tangem.common.ui.amountScreen.ui.AmountBlockV2
import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.ui.decompose.ComposableContentComponent import com.tangem.core.ui.decompose.ComposableContentComponent
@ -37,6 +38,18 @@ internal class SendAmountBlockComponent(
val state by model.uiState.collectAsStateWithLifecycle() val state by model.uiState.collectAsStateWithLifecycle()
val isClickEnabled by params.blockClickEnableFlow.collectAsStateWithLifecycle() val isClickEnabled by params.blockClickEnableFlow.collectAsStateWithLifecycle()
if (params.isRedesignEnabled) {
val amountState = state as? AmountState.Data ?: return
AmountBlockV2(
amountState = state,
currencyIconState = amountState.tokenIconState,
isClickDisabled = !isClickEnabled,
isEditingDisabled = params.predefinedValues is PredefinedValues.Content.Deeplink,
onClick = onClick,
modifier = modifier,
)
} else {
AmountBlock( AmountBlock(
amountState = state, amountState = state,
isClickDisabled = !isClickEnabled, isClickDisabled = !isClickEnabled,
@ -45,3 +58,4 @@ internal class SendAmountBlockComponent(
) )
} }
} }
}

View file

@ -18,6 +18,7 @@ internal sealed class SendAmountComponentParams {
abstract val appCurrency: AppCurrency abstract val appCurrency: AppCurrency
abstract val cryptoCurrencyStatus: CryptoCurrencyStatus abstract val cryptoCurrencyStatus: CryptoCurrencyStatus
abstract val predefinedValues: PredefinedValues abstract val predefinedValues: PredefinedValues
abstract val isRedesignEnabled: Boolean
data class AmountParams( data class AmountParams(
override val state: AmountState, override val state: AmountState,
@ -26,6 +27,7 @@ internal sealed class SendAmountComponentParams {
override val appCurrency: AppCurrency, override val appCurrency: AppCurrency,
override val cryptoCurrencyStatus: CryptoCurrencyStatus, override val cryptoCurrencyStatus: CryptoCurrencyStatus,
override val predefinedValues: PredefinedValues, override val predefinedValues: PredefinedValues,
override val isRedesignEnabled: Boolean,
val callback: ModelCallback, val callback: ModelCallback,
val currentRoute: Flow<CommonSendRoute.Amount>, val currentRoute: Flow<CommonSendRoute.Amount>,
val isBalanceHidingFlow: StateFlow<Boolean>, val isBalanceHidingFlow: StateFlow<Boolean>,
@ -40,6 +42,7 @@ internal sealed class SendAmountComponentParams {
override val appCurrency: AppCurrency, override val appCurrency: AppCurrency,
override val cryptoCurrencyStatus: CryptoCurrencyStatus, override val cryptoCurrencyStatus: CryptoCurrencyStatus,
override val predefinedValues: PredefinedValues, override val predefinedValues: PredefinedValues,
override val isRedesignEnabled: Boolean,
val blockClickEnableFlow: StateFlow<Boolean>, val blockClickEnableFlow: StateFlow<Boolean>,
) : SendAmountComponentParams() ) : SendAmountComponentParams()
} }

View file

@ -40,6 +40,7 @@ internal class SendDestinationBlockComponent(
destinationUM = state, destinationUM = state,
isClickDisabled = !isClickEnabled, isClickDisabled = !isClickEnabled,
isEditingDisabled = params.predefinedValues is PredefinedValues.Content.Deeplink, isEditingDisabled = params.predefinedValues is PredefinedValues.Content.Deeplink,
isRedesignEnabled = (params.state as? DestinationUM.Content)?.isRedesignEnabled ?: false,
onClick = onClick, onClick = onClick,
) )
} }

View file

@ -1,26 +1,38 @@
package com.tangem.features.send.v2.subcomponents.destination.ui package com.tangem.features.send.v2.subcomponents.destination.ui
import android.content.res.Configuration
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import com.tangem.core.ui.components.icons.identicon.IdentIcon import com.tangem.core.ui.components.icons.identicon.IdentIcon
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.send.v2.impl.R
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationRecipientListUM
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationTextFieldUM import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationTextFieldUM
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
import kotlinx.collections.immutable.toImmutableList
@Composable @Composable
internal fun DestinationBlock( internal fun DestinationBlock(
destinationUM: DestinationUM, destinationUM: DestinationUM,
isClickDisabled: Boolean, isClickDisabled: Boolean,
isEditingDisabled: Boolean, isEditingDisabled: Boolean,
isRedesignEnabled: Boolean,
onClick: () -> Unit, onClick: () -> Unit,
) { ) {
if (destinationUM !is DestinationUM.Content) return if (destinationUM !is DestinationUM.Content) return
@ -33,10 +45,17 @@ internal fun DestinationBlock(
.clickable(enabled = !isClickDisabled && !isEditingDisabled, onClick = onClick) .clickable(enabled = !isClickDisabled && !isEditingDisabled, onClick = onClick)
.padding(TangemTheme.dimens.spacing12), .padding(TangemTheme.dimens.spacing12),
) { ) {
if (isRedesignEnabled) {
AddressWithMemoBlock(
address = destinationUM.addressTextField,
memo = destinationUM.memoTextField,
)
} else {
AddressBlock(destinationUM.addressTextField) AddressBlock(destinationUM.addressTextField)
MemoBlock(destinationUM.memoTextField) MemoBlock(destinationUM.memoTextField)
} }
} }
}
@Composable @Composable
private fun AddressBlock(address: DestinationTextFieldUM.RecipientAddress) { private fun AddressBlock(address: DestinationTextFieldUM.RecipientAddress) {
@ -85,3 +104,123 @@ private fun MemoBlock(memo: DestinationTextFieldUM.RecipientMemo?) {
) )
} }
} }
@Composable
private fun AddressWithMemoBlock(
address: DestinationTextFieldUM.RecipientAddress,
memo: DestinationTextFieldUM.RecipientMemo?,
) {
Text(
text = stringResourceSafe(R.string.send_to_address),
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.tertiary,
)
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing24),
modifier = Modifier.padding(top = TangemTheme.dimens.spacing8),
) {
Text(
modifier = Modifier.weight(1f),
text = address.value,
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.primary1,
)
IdentIcon(
address = address.value,
modifier = Modifier
.size(TangemTheme.dimens.size36)
.clip(RoundedCornerShape(TangemTheme.dimens.radius18))
.background(TangemTheme.colors.background.tertiary),
)
}
if (memo != null && memo.value.isNotBlank()) {
Text(
text = stringResourceSafe(R.string.send_memo, memo.value),
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
modifier = Modifier.padding(top = TangemTheme.dimens.spacing8),
)
}
}
@Preview(showBackground = true, widthDp = 360)
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun DestinationBlockPreview(
@PreviewParameter(DestinationBlockPreviewProvider::class) state: DestinationUM.Content,
) {
TangemThemePreview {
DestinationBlock(
destinationUM = state,
isClickDisabled = false,
isEditingDisabled = false,
isRedesignEnabled = state.isRedesignEnabled,
onClick = {},
)
}
}
private class DestinationBlockPreviewProvider : PreviewParameterProvider<DestinationUM.Content> {
override val values: Sequence<DestinationUM.Content>
get() = sequenceOf(
DestinationUM.Content(
isPrimaryButtonEnabled = true,
addressTextField = DestinationTextFieldUM.RecipientAddress(
value = "0x34B4492A412D84A6E606288f3Bd714b89135D4dE",
keyboardOptions = KeyboardOptions.Default,
placeholder = TextReference.Str("Enter address"),
label = TextReference.Str("Recipient Address"),
isError = false,
error = null,
isValuePasted = false,
),
memoTextField = DestinationTextFieldUM.RecipientMemo(
value = "Test memo for transaction",
keyboardOptions = KeyboardOptions.Default,
placeholder = TextReference.Str("Enter memo (optional)"),
label = TextReference.Str("Memo"),
isError = false,
error = null,
disabledText = TextReference.Str("Memo disabled"),
isEnabled = true,
isValuePasted = false,
),
recent = emptyList<DestinationRecipientListUM>().toImmutableList(),
wallets = emptyList<DestinationRecipientListUM>().toImmutableList(),
networkName = "Ethereum",
isValidating = false,
isInitialized = true,
isRedesignEnabled = false,
),
DestinationUM.Content(
isPrimaryButtonEnabled = true,
addressTextField = DestinationTextFieldUM.RecipientAddress(
value = "0x34B4492A412D84A6E606288f3Bd714b89135D4dE",
keyboardOptions = KeyboardOptions.Default,
placeholder = TextReference.Str("Enter address"),
label = TextReference.Str("Recipient Address"),
isError = false,
error = null,
isValuePasted = false,
),
memoTextField = DestinationTextFieldUM.RecipientMemo(
value = "Test memo for transaction",
keyboardOptions = KeyboardOptions.Default,
placeholder = TextReference.Str("Enter memo (optional)"),
label = TextReference.Str("Memo"),
isError = false,
error = null,
disabledText = TextReference.Str("Memo disabled"),
isEnabled = true,
isValuePasted = false,
),
recent = emptyList<DestinationRecipientListUM>().toImmutableList(),
wallets = emptyList<DestinationRecipientListUM>().toImmutableList(),
networkName = "Ethereum",
isValidating = false,
isInitialized = true,
isRedesignEnabled = true,
),
)
}