diff --git a/core/config-toggles/src/main/assets/configs/feature_toggles_config.json b/core/config-toggles/src/main/assets/configs/feature_toggles_config.json
index 602bd04e20..a63c34bcdd 100644
--- a/core/config-toggles/src/main/assets/configs/feature_toggles_config.json
+++ b/core/config-toggles/src/main/assets/configs/feature_toggles_config.json
@@ -70,5 +70,9 @@
{
"name": "SWAP_REDESIGN_ENABLED",
"version": "undefined"
+ },
+ {
+ "name": "SEND_REDESIGN_ENABLED",
+ "version": "undefined"
}
]
diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index 92d6363206..41d8a84e62 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -856,8 +856,12 @@
Recipient
Not a valid address
Ensure the receiving wallet address is on the %s network to avoid losing your tokens
+ send to %s
+ Ensure you %s network address, as errors may result in lost transfers
Send to
A Memo/Destination Tag is a unique ID for differentiating transactions sent to the same recipient on the same network. Caution: Omitting a memo may lead to misplaced funds
+ Memo / Destination Tag is a code separating transactions to a shared recipient in a crypto network.
+ Caution: Missing a memo may lead to fund loss.
My wallets
A way of measuring Bitcoin transaction fees. It indicates the number of the smallest Bitcoin unit (Satoshi) for each virtual byte in a transaction. The higher the number, the faster the transaction will be processed by miners.
Satoshi / vByte
@@ -885,7 +889,7 @@
Forget wallet
This will remove the wallet from the application. The wallet itself can be added again.
Name
- Join staking with this token
+ Put your token to work
The amount to stake must be at least %s
Staking amount will be rounded to %1$s TRX due to network rules.
Unstaking amount will be rounded to %1$s TRX due to network rules.
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/containers/FooterContainer.kt b/core/ui/src/main/java/com/tangem/core/ui/components/containers/FooterContainer.kt
index bebd090e66..028be341c1 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/containers/FooterContainer.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/containers/FooterContainer.kt
@@ -9,7 +9,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
import com.tangem.core.ui.extensions.TextReference
-import com.tangem.core.ui.extensions.resolveReference
+import com.tangem.core.ui.extensions.resolveAnnotatedReference
import com.tangem.core.ui.res.TangemTheme
/**
@@ -32,7 +32,7 @@ fun FooterContainer(
AnimatedVisibility(visible = footer != null) {
val footerWrapped = remember(this) { requireNotNull(footer) }
Text(
- text = footerWrapped.resolveReference(),
+ text = footerWrapped.resolveAnnotatedReference(),
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
modifier = Modifier
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowRecipient.kt b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowRecipient.kt
index 8d5363d3cc..8991b68840 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowRecipient.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowRecipient.kt
@@ -2,6 +2,10 @@ package com.tangem.core.ui.components.inputrow
import android.content.res.Configuration
import androidx.compose.animation.AnimatedContent
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.core.tween
+import androidx.compose.animation.fadeIn
+import androidx.compose.animation.fadeOut
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
@@ -16,6 +20,7 @@ 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.R
+import com.tangem.core.ui.components.buttons.small.TangemIconButton
import com.tangem.core.ui.components.fields.SimpleTextField
import com.tangem.core.ui.components.icons.identicon.IdentIcon
import com.tangem.core.ui.components.inputrow.inner.CrossIcon
@@ -25,24 +30,29 @@ import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
+import com.tangem.core.ui.utils.DEFAULT_ANIMATION_DURATION
import kotlinx.coroutines.delay
/**
- * [Input Row Recipient](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=2100-826&mode=design&t=IQ5lBJEkFGU4WSvi-4)
+ * * [Design Reference](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=2100-826&mode=design&t=IQ5lBJEkFGU4WSvi-4)
*
- * @param title title reference
- * @param value recipient address
- * @param placeholder placeholder
- * @param onValueChange callback for value change
- * @param onPasteClick callback for paste
- * @param modifier composable modifier
- * @param singleLine is single line text
- * @param error error text
- * @param isError is error flag
- * @param showDivider show divider
+ * @param title The title text reference to display above the input field
+ * @param value The current recipient address value to display in the input field
+ * @param placeholder The placeholder text reference to show when the input is empty
+ * @param onValueChange Callback invoked when the input value changes, receives the new string value
+ * @param onPasteClick Callback invoked when the paste button is clicked, receives the pasted string
+ * @param onQrCodeClick Callback invoked when the QR code scan button is clicked
+ * @param modifier Optional modifier to apply to the composable
+ * @param singleLine Whether the text field should be constrained to a single line (default: false)
+ * @param error Optional error text reference to display when validation fails
+ * @param isError Whether the input is in an error state, affects styling and title color
+ * @param showDivider Whether to show a divider below the component (default: false)
+ * @param isLoading Whether to show a loading indicator instead of the identicon (default: false)
+ * @param isValuePasted Whether the current value was pasted, affects visual feedback (default: false)
*
- * @see InputRowRecipientDefault for readonly version
+ * @see InputRowRecipientDefault for a read-only version of this component
*/
+@Suppress("LongParameterList", "LongMethod")
@Composable
fun InputRowRecipient(
title: TextReference,
@@ -50,6 +60,8 @@ fun InputRowRecipient(
placeholder: TextReference,
onValueChange: (String) -> Unit,
onPasteClick: (String) -> Unit,
+ onQrCodeClick: () -> Unit,
+ isRedesignEnabled: Boolean,
modifier: Modifier = Modifier,
singleLine: Boolean = false,
error: TextReference? = null,
@@ -109,18 +121,55 @@ fun InputRowRecipient(
.padding(start = TangemTheme.dimens.spacing8),
)
}
- PasteButton(
- isPasteButtonVisible = value.isBlank(),
- onClick = onPasteClick,
+ Row(
modifier = Modifier
- .align(CenterEnd)
- .padding(start = TangemTheme.dimens.spacing8),
- )
+ .align(CenterEnd),
+ ) {
+ if (isRedesignEnabled) {
+ QrButton(
+ visible = !singleLine,
+ onQrCodeClick = onQrCodeClick,
+ )
+ }
+ PasteButton(
+ isPasteButtonVisible = value.isBlank(),
+ onClick = onPasteClick,
+ backgroundColorEnabled = if (isRedesignEnabled) {
+ TangemTheme.colors.button.secondary
+ } else {
+ TangemTheme.colors.button.primary
+ },
+ textColor = if (isRedesignEnabled) {
+ TangemTheme.colors.text.primary1
+ } else {
+ TangemTheme.colors.text.primary2
+ },
+ modifier = Modifier
+ .padding(start = TangemTheme.dimens.spacing8),
+ )
+ }
}
}
}
}
+@Composable
+private fun QrButton(visible: Boolean, onQrCodeClick: () -> Unit, modifier: Modifier = Modifier) {
+ AnimatedVisibility(
+ visible = visible,
+ enter = fadeIn(),
+ exit = fadeOut(animationSpec = tween(DEFAULT_ANIMATION_DURATION)),
+ modifier = modifier,
+ ) {
+ TangemIconButton(
+ iconRes = R.drawable.ic_scan_16,
+ onClick = onQrCodeClick,
+ background = TangemTheme.colors.button.secondary,
+ iconTint = TangemTheme.colors.text.primary1,
+ )
+ }
+}
+
@Composable
private fun RowScope.InputIcon(isLoading: Boolean, value: String) {
var isLoadingProxy by remember { mutableStateOf(isLoading) }
@@ -172,7 +221,9 @@ private fun InputRowRecipientPreview(
showDivider = true,
onValueChange = {},
onPasteClick = {},
+ onQrCodeClick = {},
modifier = Modifier.background(TangemTheme.colors.background.primary),
+ isRedesignEnabled = false,
)
}
}
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/inner/PasteButton.kt b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/inner/PasteButton.kt
index ef23a4babc..d816b39eb6 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/inner/PasteButton.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/inner/PasteButton.kt
@@ -14,6 +14,7 @@ import androidx.compose.material3.Text
import androidx.compose.material3.ripple
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalHapticFeedback
@@ -34,14 +35,21 @@ import com.tangem.core.ui.utils.DEFAULT_ANIMATION_DURATION
* @param modifier composable modifier
*/
@Composable
-fun PasteButton(isPasteButtonVisible: Boolean, onClick: (String) -> Unit, modifier: Modifier = Modifier) {
+fun PasteButton(
+ isPasteButtonVisible: Boolean,
+ onClick: (String) -> Unit,
+ modifier: Modifier = Modifier,
+ backgroundColorEnabled: Color = TangemTheme.colors.button.primary,
+ backgroundColorDisabled: Color = TangemTheme.colors.button.secondary,
+ textColor: Color = TangemTheme.colors.text.primary2,
+) {
val clipboardManager = LocalClipboardManager.current
val hapticFeedback = LocalHapticFeedback.current
val isPasteEnabled = !clipboardManager.getText()?.text.isNullOrEmpty()
val color = if (isPasteEnabled) {
- TangemTheme.colors.button.primary
+ backgroundColorEnabled
} else {
- TangemTheme.colors.button.secondary
+ backgroundColorDisabled
}
AnimatedVisibility(
visible = isPasteButtonVisible,
@@ -53,7 +61,7 @@ fun PasteButton(isPasteButtonVisible: Boolean, onClick: (String) -> Unit, modifi
Text(
text = stringResourceSafe(R.string.common_paste),
style = TangemTheme.typography.caption1,
- color = TangemTheme.colors.text.primary2,
+ color = textColor,
modifier = Modifier
.background(
color = color,
diff --git a/core/ui/src/main/java/com/tangem/core/ui/extensions/MarkdownExtension.kt b/core/ui/src/main/java/com/tangem/core/ui/extensions/MarkdownExtension.kt
index c510835242..f1e49e308f 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/extensions/MarkdownExtension.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/extensions/MarkdownExtension.kt
@@ -60,4 +60,40 @@ fun AnnotatedString.Builder.appendSpace() = append(" ")
fun AnnotatedString.Builder.appendColored(text: String, color: Color) = withStyle(SpanStyle(color = color)) {
append(text)
+}
+
+/**
+ * Appends text from a template string to the AnnotatedString.Builder, replacing a placeholder (default "%s")
+ * with custom styled content provided by a lambda. The lambda allows you to insert styled or complex content
+ * (e.g., colored, bold, or annotated text) at the placeholder position.
+ *
+ * If the placeholder is not found in the template, the function does nothing.
+ *
+ * Example usage:
+ * builder.appendWithStyledPlaceholder(
+ * template = "Ensure you %s network address, as errors may result in lost transfers"
+ * ) {
+ * withStyle(SpanStyle(color = Color.Red, fontWeight = FontWeight.Bold)) {
+ * append("Ethereum")
+ * }
+ * }
+ *
+ * @param template The template string containing the placeholder to be replaced.
+ * @param placeholder The placeholder string to be replaced by styled content. Default is "%s".
+ * @param styledContent Lambda to build the styled content to insert at the placeholder position.
+ */
+fun AnnotatedString.Builder.appendWithStyledPlaceholder(
+ template: String,
+ placeholder: String = "%s",
+ styledContent: AnnotatedString.Builder.() -> Unit,
+) {
+ val index = template.indexOf(placeholder)
+ if (index < 0) return
+ // Append before placeholder
+ if (index > 0) append(template.substring(0, index))
+ // Append styled content
+ styledContent()
+ // Append after placeholder
+ val afterIndex = index + placeholder.length
+ if (afterIndex < template.length) append(template.substring(afterIndex))
}
\ No newline at end of file
diff --git a/core/ui/src/main/res/drawable/ic_scan_16.xml b/core/ui/src/main/res/drawable/ic_scan_16.xml
new file mode 100644
index 0000000000..16a9aa2ffb
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_scan_16.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/SendFeatureToggles.kt b/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/SendFeatureToggles.kt
index 4dbf452662..0e08965245 100644
--- a/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/SendFeatureToggles.kt
+++ b/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/SendFeatureToggles.kt
@@ -1,3 +1,6 @@
package com.tangem.features.send.v2.api
-interface SendFeatureToggles
\ No newline at end of file
+interface SendFeatureToggles {
+
+ val isSendRedesignEnabled: Boolean
+}
\ No newline at end of file
diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/DefaultSendFeatureToggles.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/DefaultSendFeatureToggles.kt
index 326f72db7e..cce9c99562 100644
--- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/DefaultSendFeatureToggles.kt
+++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/DefaultSendFeatureToggles.kt
@@ -4,5 +4,8 @@ import com.tangem.core.configtoggle.feature.FeatureTogglesManager
import com.tangem.features.send.v2.api.SendFeatureToggles
internal class DefaultSendFeatureToggles(
- @Suppress("UnusedPrivateMember") private val featureToggles: FeatureTogglesManager,
-) : SendFeatureToggles
\ No newline at end of file
+ private val featureToggles: FeatureTogglesManager,
+) : SendFeatureToggles {
+ override val isSendRedesignEnabled: Boolean
+ get() = featureToggles.isFeatureEnabled("SEND_REDESIGN_ENABLED")
+}
\ No newline at end of file
diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/model/SendModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/model/SendModel.kt
index 9e82a35a76..9aa5fe4c78 100644
--- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/model/SendModel.kt
+++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/model/SendModel.kt
@@ -37,6 +37,7 @@ import com.tangem.domain.wallets.models.isMultiCurrency
import com.tangem.domain.wallets.models.requireColdWallet
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.features.send.v2.api.SendComponent
+import com.tangem.features.send.v2.api.SendFeatureToggles
import com.tangem.features.send.v2.common.CommonSendRoute
import com.tangem.features.send.v2.common.PredefinedValues
import com.tangem.features.send.v2.common.SendConfirmAlertFactory
@@ -87,6 +88,7 @@ internal class SendModel @Inject constructor(
private val createTransferTransactionUseCase: CreateTransferTransactionUseCase,
private val getFeeUseCase: GetFeeUseCase,
private val sendAmountUpdateQRTrigger: SendAmountUpdateQRTrigger,
+ private val sendFeatureToggles: SendFeatureToggles,
) : Model(), SendComponentCallback {
private val params: SendComponent.Params = paramsContainer.require()
@@ -357,6 +359,7 @@ internal class SendModel @Inject constructor(
amountUM = AmountState.Empty(),
destinationUM = SendDestinationInitialStateTransformer(
cryptoCurrency = cryptoCurrency,
+ isRedesignEnabled = sendFeatureToggles.isSendRedesignEnabled,
).transform(DestinationUM.Empty()),
feeUM = FeeUM.Empty(),
confirmUM = ConfirmUM.Empty,
diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/model/SendDestinationModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/model/SendDestinationModel.kt
index 8ccf0bd907..6bd184f1fc 100644
--- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/model/SendDestinationModel.kt
+++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/model/SendDestinationModel.kt
@@ -23,6 +23,7 @@ import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.models.isLocked
import com.tangem.domain.wallets.models.isMultiCurrency
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
+import com.tangem.features.send.v2.api.SendFeatureToggles
import com.tangem.features.send.v2.common.PredefinedValues
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents.SendScreenSource
@@ -65,6 +66,7 @@ internal class SendDestinationModel @Inject constructor(
private val listenToQrScanningUseCase: ListenToQrScanningUseCase,
private val parseQrCodeUseCase: ParseQrCodeUseCase,
private val analyticsEventHandler: AnalyticsEventHandler,
+ private val sendFeatureToggles: SendFeatureToggles,
) : Model(), SendDestinationClickIntents {
private val params: SendDestinationComponentParams = paramsContainer.require()
@@ -90,6 +92,7 @@ internal class SendDestinationModel @Inject constructor(
_uiState.update(
SendDestinationInitialStateTransformer(
cryptoCurrency = cryptoCurrency,
+ isRedesignEnabled = sendFeatureToggles.isSendRedesignEnabled,
isInitialized = true,
),
)
@@ -297,6 +300,7 @@ internal class SendDestinationModel @Inject constructor(
flow2 = params.currentRoute,
transform = { state, route -> state to route },
).onEach { (state, route) ->
+ val isRedesignEnabled = sendFeatureToggles.isSendRedesignEnabled
params.callback.onNavigationResult(
NavigationUM.Content(
title = params.title,
@@ -319,8 +323,16 @@ internal class SendDestinationModel @Inject constructor(
}
params.onBackClick()
},
- additionalIconRes = R.drawable.ic_qrcode_scan_24,
- additionalIconClick = ::onQrCodeScanClick,
+ additionalIconRes = if (isRedesignEnabled) {
+ null
+ } else {
+ R.drawable.ic_qrcode_scan_24
+ },
+ additionalIconClick = if (isRedesignEnabled) {
+ null
+ } else {
+ ::onQrCodeScanClick
+ },
primaryButton = ButtonsUM.PrimaryButtonUM(
text = if (route.isEditMode) {
resourceReference(R.string.common_continue)
diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/model/transformers/SendDestinationInitialStateTransformer.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/model/transformers/SendDestinationInitialStateTransformer.kt
index 76de538ac5..8ad0687969 100644
--- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/model/transformers/SendDestinationInitialStateTransformer.kt
+++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/model/transformers/SendDestinationInitialStateTransformer.kt
@@ -13,6 +13,7 @@ import com.tangem.utils.transformer.Transformer
internal class SendDestinationInitialStateTransformer(
val cryptoCurrency: CryptoCurrency,
+ val isRedesignEnabled: Boolean,
val isInitialized: Boolean = false,
) : Transformer {
override fun transform(prevState: DestinationUM): DestinationUM {
@@ -54,6 +55,7 @@ internal class SendDestinationInitialStateTransformer(
recent = loadingListState(RECENT_KEY_TAG, RECENT_DEFAULT_COUNT),
networkName = cryptoCurrency.network.name,
isValidating = false,
+ isRedesignEnabled = isRedesignEnabled,
)
}
}
\ No newline at end of file
diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/ui/SendDestinationContent.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/ui/SendDestinationContent.kt
index 4caf6be2e2..1014976ae1 100644
--- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/ui/SendDestinationContent.kt
+++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/ui/SendDestinationContent.kt
@@ -16,6 +16,10 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
+import androidx.compose.ui.text.SpanStyle
+import androidx.compose.ui.text.buildAnnotatedString
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.containers.FooterContainer
import com.tangem.core.ui.components.inputrow.InputRowRecipient
@@ -60,10 +64,13 @@ internal fun SendDestinationContent(
isError = isError,
isValidating = isValidating,
onAddressChange = clickIntents::onRecipientAddressValueChange,
+ onQrCodeClick = clickIntents::onQrCodeScanClick,
+ isRedesignEnabled = state.isRedesignEnabled,
)
memoField(
memoField = memoField,
onMemoChange = clickIntents::onRecipientMemoValueChange,
+ isRedesignEnabled = state.isRedesignEnabled,
)
listHeaderItem(
titleRes = R.string.send_recipient_wallets_title,
@@ -100,16 +107,23 @@ internal fun SendDestinationContent(
}
}
+@Suppress("LongParameterList")
private fun LazyListScope.addressItem(
address: DestinationTextFieldUM.RecipientAddress,
networkName: String,
isError: Boolean,
isValidating: Boolean,
onAddressChange: (String, EnterAddressSource) -> Unit,
+ onQrCodeClick: () -> Unit,
+ isRedesignEnabled: Boolean,
) {
item(key = ADDRESS_FIELD_KEY) {
FooterContainer(
- footer = resourceReference(R.string.send_recipient_address_footer, wrappedList(networkName)),
+ footer = if (isRedesignEnabled) {
+ buildHighlightedFooterText(networkName)
+ } else {
+ resourceReference(R.string.send_recipient_address_footer, wrappedList(networkName))
+ },
) {
InputRowRecipient(
value = address.value,
@@ -117,6 +131,8 @@ private fun LazyListScope.addressItem(
placeholder = address.placeholder,
onValueChange = { onAddressChange(it, EnterAddressSource.InputField) },
onPasteClick = { onAddressChange(it, EnterAddressSource.PasteButton) },
+ onQrCodeClick = onQrCodeClick,
+ isRedesignEnabled = isRedesignEnabled,
isError = isError,
isLoading = isValidating,
error = address.error,
@@ -131,9 +147,37 @@ private fun LazyListScope.addressItem(
}
}
+@Composable
+private fun buildHighlightedFooterText(networkName: String): TextReference {
+ return annotatedReference(
+ buildAnnotatedString {
+ val styledText = stringResourceSafe(
+ R.string.send_recipient_address_footer_highlighted_part,
+ networkName,
+ )
+ val styledColor = TangemTheme.colors.text.secondary
+ appendWithStyledPlaceholder(
+ template = stringResourceSafe(
+ R.string.send_recipient_address_footer_v2,
+ networkName,
+ ),
+ placeholder = networkName,
+ ) {
+ withStyle(SpanStyle(fontWeight = FontWeight.Medium)) {
+ appendColored(
+ text = styledText,
+ color = styledColor,
+ )
+ }
+ }
+ },
+ )
+}
+
private fun LazyListScope.memoField(
memoField: DestinationTextFieldUM.RecipientMemo?,
onMemoChange: (String, Boolean) -> Unit,
+ isRedesignEnabled: Boolean,
) {
if (memoField != null) {
item(key = MEMO_FIELD_KEY) {
@@ -142,7 +186,24 @@ private fun LazyListScope.memoField(
value = memoField.value,
label = memoField.label,
placeholder = placeholder,
- footer = resourceReference(R.string.send_recipient_memo_footer),
+ footer = if (isRedesignEnabled) {
+ annotatedReference(
+ buildAnnotatedString {
+ append(stringResourceSafe(R.string.send_recipient_memo_footer_v2))
+ append("\n")
+ withStyle(SpanStyle(fontWeight = FontWeight.Medium)) {
+ appendColored(
+ text = stringResourceSafe(
+ R.string.send_recipient_memo_footer_v2_highlighted,
+ ),
+ color = TangemTheme.colors.text.secondary,
+ )
+ }
+ },
+ )
+ } else {
+ resourceReference(R.string.send_recipient_memo_footer)
+ },
onValueChange = { onMemoChange(it, false) },
onPasteClick = { onMemoChange(it, true) },
modifier = Modifier.padding(top = 20.dp),
@@ -151,6 +212,7 @@ private fun LazyListScope.memoField(
error = memoField.error,
isReadOnly = !memoField.isEnabled,
isValuePasted = memoField.isValuePasted,
+ isRedesignEnabled = isRedesignEnabled,
)
}
}
diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/ui/TextFieldWithPaste.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/ui/TextFieldWithPaste.kt
index 162ab6bf7b..2c2fe6de6a 100644
--- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/ui/TextFieldWithPaste.kt
+++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/ui/TextFieldWithPaste.kt
@@ -20,6 +20,7 @@ import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.components.containers.FooterContainer
+@Suppress("LongMethod", "LongParameterList")
@Composable
internal fun TextFieldWithPaste(
value: String,
@@ -27,6 +28,7 @@ internal fun TextFieldWithPaste(
label: TextReference,
onValueChange: (String) -> Unit,
onPasteClick: (String) -> Unit,
+ isRedesignEnabled: Boolean,
modifier: Modifier = Modifier,
footer: TextReference? = null,
labelStyle: TextStyle = TangemTheme.typography.body2,
@@ -96,6 +98,18 @@ internal fun TextFieldWithPaste(
PasteButton(
isPasteButtonVisible = value.isBlank(),
onClick = onPasteClick,
+ backgroundColorEnabled = if (isRedesignEnabled) {
+ TangemTheme.colors.button.secondary
+ } else {
+ TangemTheme.colors.button.primary
+ },
+ textColor = if (isRedesignEnabled) {
+ TangemTheme.colors.text.primary1
+ } else {
+ TangemTheme.colors.text.primary2
+ },
+ modifier = Modifier
+ .padding(start = TangemTheme.dimens.spacing8),
)
}
}
diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/ui/state/DestinationUM.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/ui/state/DestinationUM.kt
index 06935a8368..8a73b412f0 100644
--- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/ui/state/DestinationUM.kt
+++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/subcomponents/destination/ui/state/DestinationUM.kt
@@ -17,6 +17,7 @@ internal sealed class DestinationUM {
val networkName: String,
val isValidating: Boolean = false,
val isInitialized: Boolean = false,
+ val isRedesignEnabled: Boolean = false,
) : DestinationUM()
data class Empty(