From 07f63b47e4d7f276dce1aa309cd05804dbd92f99 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 20 Jun 2025 16:50:40 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../configs/feature_toggles_config.json | 4 + core/res/src/main/res/values/strings.xml | 6 +- .../components/containers/FooterContainer.kt | 4 +- .../components/inputrow/InputRowRecipient.kt | 87 +++++++++++++++---- .../components/inputrow/inner/PasteButton.kt | 16 +++- .../core/ui/extensions/MarkdownExtension.kt | 36 ++++++++ core/ui/src/main/res/drawable/ic_scan_16.xml | 10 +++ .../send/v2/api/SendFeatureToggles.kt | 5 +- .../send/v2/DefaultSendFeatureToggles.kt | 7 +- .../features/send/v2/send/model/SendModel.kt | 3 + .../destination/model/SendDestinationModel.kt | 16 +++- .../SendDestinationInitialStateTransformer.kt | 2 + .../destination/ui/SendDestinationContent.kt | 66 +++++++++++++- .../destination/ui/TextFieldWithPaste.kt | 14 +++ .../destination/ui/state/DestinationUM.kt | 1 + 15 files changed, 245 insertions(+), 32 deletions(-) create mode 100644 core/ui/src/main/res/drawable/ic_scan_16.xml 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(