From 8f69b1dce30d0b80216481c4718d32acdaf81645 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 31 Jul 2025 12:40:48 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../tangem/common/ui/footers/SendingText.kt | 4 +- .../java/com/tangem/utils/StringsSigns.kt | 1 + .../send/v2/api}/utils/ConfirmFooterUtils.kt | 8 +- ...endConfirmationNotificationsTransformer.kt | 4 +- ...dConfirmationNotificationsTransformerV2.kt | 4 +- ...endConfirmationNotificationsTransformer.kt | 4 +- .../swap/v2/impl/common/entity/ConfirmUM.kt | 13 ++- .../confirm/SendWithSwapConfirmComponent.kt | 3 + ...dWithSwapConfirmInitialStateTransformer.kt | 1 + ...wapConfirmationNotificationsTransformer.kt | 52 +++++++---- .../confirm/ui/SendWithSwapConfirmContent.kt | 90 +++++++++++++++++-- .../sendviaswap/ui/SendWithSwapContent.kt | 8 +- 12 files changed, 157 insertions(+), 35 deletions(-) rename features/send-v2/{impl/src/main/java/com/tangem/features/send/v2/common => api/src/main/java/com/tangem/features/send/v2/api}/utils/ConfirmFooterUtils.kt (89%) diff --git a/common/ui/src/main/java/com/tangem/common/ui/footers/SendingText.kt b/common/ui/src/main/java/com/tangem/common/ui/footers/SendingText.kt index 3f880fa882..b2c89117fe 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/footers/SendingText.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/footers/SendingText.kt @@ -49,10 +49,10 @@ fun SendingText(footerText: TextReference, modifier: Modifier = Modifier) { text = footerText.resolveAnnotatedReference(), textAlign = TextAlign.Center, style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.primary1, + color = TangemTheme.colors.text.tertiary, modifier = Modifier .fillMaxWidth() - .padding(12.dp), + .padding(16.dp), ) } } \ No newline at end of file diff --git a/core/utils/src/main/java/com/tangem/utils/StringsSigns.kt b/core/utils/src/main/java/com/tangem/utils/StringsSigns.kt index 534b602d2c..98ba454b64 100644 --- a/core/utils/src/main/java/com/tangem/utils/StringsSigns.kt +++ b/core/utils/src/main/java/com/tangem/utils/StringsSigns.kt @@ -9,6 +9,7 @@ object StringsSigns { const val LOWER_SIGN = "<" const val TILDE_SIGN = "~" const val COMA_SIGN = "," + const val POINT_SIGN = "." const val INFINITY_SIGN = "∞" const val NON_BREAKING_SPACE = '\u00A0' const val PERCENT = "%" diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/common/utils/ConfirmFooterUtils.kt b/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/utils/ConfirmFooterUtils.kt similarity index 89% rename from features/send-v2/impl/src/main/java/com/tangem/features/send/v2/common/utils/ConfirmFooterUtils.kt rename to features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/utils/ConfirmFooterUtils.kt index 3c13220638..4b0d95ede3 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/common/utils/ConfirmFooterUtils.kt +++ b/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/utils/ConfirmFooterUtils.kt @@ -1,4 +1,4 @@ -package com.tangem.features.send.v2.common.utils +package com.tangem.features.send.v2.api.utils import com.tangem.blockchain.common.Amount import com.tangem.blockchain.common.transaction.Fee @@ -8,10 +8,10 @@ import com.tangem.core.ui.format.bigdecimal.fee import com.tangem.core.ui.format.bigdecimal.fiat import com.tangem.core.ui.format.bigdecimal.format import com.tangem.domain.appcurrency.model.AppCurrency -import com.tangem.features.send.v2.impl.R +import com.tangem.features.send.v2.api.R import com.tangem.utils.StringsSigns.COMA_SIGN -internal fun getTronTokenFeeSendingText(fee: Fee.Tron, fiatFee: String, fiatSending: TextReference): TextReference { +fun getTronTokenFeeSendingText(fee: Fee.Tron, fiatFee: String, fiatSending: TextReference): TextReference { val suffix = when { fee.remainingEnergy == 0L -> { resourceReference( @@ -40,7 +40,7 @@ internal fun getTronTokenFeeSendingText(fee: Fee.Tron, fiatFee: String, fiatSend return combinedReference(prefix, stringReference("$COMA_SIGN "), suffix) } -internal fun formatFooterFiatFee( +fun formatFooterFiatFee( amount: Amount?, isFeeConvertibleToFiat: Boolean, isFeeApproximate: Boolean, diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/transformers/SendConfirmationNotificationsTransformer.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/transformers/SendConfirmationNotificationsTransformer.kt index 906f76bb91..8e8987f2f8 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/transformers/SendConfirmationNotificationsTransformer.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/transformers/SendConfirmationNotificationsTransformer.kt @@ -16,8 +16,8 @@ import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents import com.tangem.features.send.v2.common.ui.state.ConfirmUM -import com.tangem.features.send.v2.common.utils.formatFooterFiatFee -import com.tangem.features.send.v2.common.utils.getTronTokenFeeSendingText +import com.tangem.features.send.v2.api.utils.formatFooterFiatFee +import com.tangem.features.send.v2.api.utils.getTronTokenFeeSendingText import com.tangem.features.send.v2.impl.R import com.tangem.features.send.v2.subcomponents.fee.model.checkIfFeeTooHigh import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeSelectorUM diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/transformers/SendConfirmationNotificationsTransformerV2.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/transformers/SendConfirmationNotificationsTransformerV2.kt index 7252942833..a5935435c3 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/transformers/SendConfirmationNotificationsTransformerV2.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/model/transformers/SendConfirmationNotificationsTransformerV2.kt @@ -16,8 +16,8 @@ import com.tangem.features.send.v2.api.entity.FeeSelectorUM import com.tangem.features.send.v2.api.subcomponents.feeSelector.utils.FeeCalculationUtils import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents import com.tangem.features.send.v2.common.ui.state.ConfirmUM -import com.tangem.features.send.v2.common.utils.formatFooterFiatFee -import com.tangem.features.send.v2.common.utils.getTronTokenFeeSendingText +import com.tangem.features.send.v2.api.utils.formatFooterFiatFee +import com.tangem.features.send.v2.api.utils.getTronTokenFeeSendingText import com.tangem.features.send.v2.impl.R import com.tangem.utils.transformer.Transformer import kotlinx.collections.immutable.toPersistentList diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/confirm/model/transformers/NFTSendConfirmationNotificationsTransformer.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/confirm/model/transformers/NFTSendConfirmationNotificationsTransformer.kt index 561816abe5..fda1601aa9 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/confirm/model/transformers/NFTSendConfirmationNotificationsTransformer.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/confirm/model/transformers/NFTSendConfirmationNotificationsTransformer.kt @@ -12,8 +12,8 @@ import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.features.send.v2.common.analytics.CommonSendAnalyticEvents import com.tangem.features.send.v2.common.ui.state.ConfirmUM -import com.tangem.features.send.v2.common.utils.formatFooterFiatFee -import com.tangem.features.send.v2.common.utils.getTronTokenFeeSendingText +import com.tangem.features.send.v2.api.utils.formatFooterFiatFee +import com.tangem.features.send.v2.api.utils.getTronTokenFeeSendingText import com.tangem.features.send.v2.impl.R import com.tangem.features.send.v2.subcomponents.fee.model.checkIfFeeTooHigh import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeSelectorUM diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/common/entity/ConfirmUM.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/common/entity/ConfirmUM.kt index 701181e121..b105bed8a1 100644 --- a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/common/entity/ConfirmUM.kt +++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/common/entity/ConfirmUM.kt @@ -18,7 +18,18 @@ internal sealed class ConfirmUM { val showTapHelp: Boolean, val sendingFooter: TextReference, val notifications: ImmutableList, - ) : ConfirmUM() + val tosUM: TosUM?, + ) : ConfirmUM() { + data class TosUM( + val tosLink: LegalUM?, + val policyLink: LegalUM?, + ) + + data class LegalUM( + val title: TextReference, + val link: String, + ) + } data class Success( override val isPrimaryButtonEnabled: Boolean = true, diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/SendWithSwapConfirmComponent.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/SendWithSwapConfirmComponent.kt index 47b374269f..d3cb5651c8 100644 --- a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/SendWithSwapConfirmComponent.kt +++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/SendWithSwapConfirmComponent.kt @@ -8,6 +8,7 @@ import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.decompose.context.child import com.tangem.core.decompose.context.childByContext import com.tangem.core.decompose.model.getOrCreateModel +import com.tangem.core.navigation.url.UrlOpener import com.tangem.core.ui.decompose.ComposableContentComponent import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.models.currency.CryptoCurrencyStatus @@ -41,6 +42,7 @@ internal class SendWithSwapConfirmComponent @AssistedInject constructor( sendDestinationBlockComponent: SendDestinationBlockComponent.Factory, feeSelectorBlockComponentFactory: FeeSelectorBlockComponent.Factory, sendNotificationsComponentFactory: SendNotificationsComponent.Factory, + private val urlOpener: UrlOpener, ) : ComposableContentComponent, AppComponentContext by appComponentContext { private val model: SendWithSwapConfirmModel = getOrCreateModel(params = params) @@ -151,6 +153,7 @@ internal class SendWithSwapConfirmComponent @AssistedInject constructor( sendNotificationsUM = sendNotificationsUM, swapNotificationsComponent = swapNotificationsComponent, swapNotificationsUM = swapNotificationsUM, + onLinkClick = urlOpener::openUrl, modifier = modifier, ) } diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/transformers/SendWithSwapConfirmInitialStateTransformer.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/transformers/SendWithSwapConfirmInitialStateTransformer.kt index 4be5c0b56a..64e34d1673 100644 --- a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/transformers/SendWithSwapConfirmInitialStateTransformer.kt +++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/transformers/SendWithSwapConfirmInitialStateTransformer.kt @@ -15,6 +15,7 @@ internal class SendWithSwapConfirmInitialStateTransformer( showTapHelp = isShowTapHelp, sendingFooter = TextReference.EMPTY, notifications = persistentListOf(), + tosUM = null, ) } } \ No newline at end of file diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/transformers/SendWithSwapConfirmationNotificationsTransformer.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/transformers/SendWithSwapConfirmationNotificationsTransformer.kt index 014e57650d..3176e70a6c 100644 --- a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/transformers/SendWithSwapConfirmationNotificationsTransformer.kt +++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/transformers/SendWithSwapConfirmationNotificationsTransformer.kt @@ -5,6 +5,7 @@ import com.tangem.common.ui.amountScreen.models.AmountState import com.tangem.common.ui.notifications.NotificationUM import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resourceReference +import com.tangem.core.ui.extensions.stringReference import com.tangem.core.ui.extensions.wrappedList import com.tangem.core.ui.format.bigdecimal.fiat import com.tangem.core.ui.format.bigdecimal.format @@ -12,6 +13,8 @@ import com.tangem.domain.swap.models.SwapDirection.Companion.withSwapDirection import com.tangem.features.send.v2.api.entity.FeeSelectorUM import com.tangem.features.send.v2.api.subcomponents.feeSelector.utils.FeeCalculationUtils.checkIfCustomFeeTooHigh import com.tangem.features.send.v2.api.subcomponents.feeSelector.utils.FeeCalculationUtils.checkIfCustomFeeTooLow +import com.tangem.features.send.v2.api.utils.formatFooterFiatFee +import com.tangem.features.send.v2.api.utils.getTronTokenFeeSendingText import com.tangem.features.swap.v2.impl.R import com.tangem.features.swap.v2.impl.amount.entity.SwapAmountUM import com.tangem.features.swap.v2.impl.common.entity.ConfirmUM @@ -27,6 +30,7 @@ internal class SendWithSwapConfirmationNotificationsTransformer : Transformer, swapNotificationsComponent: SwapNotificationsComponent, swapNotificationsUM: ImmutableList, + onLinkClick: (String) -> Unit, modifier: Modifier = Modifier, ) { val confirmUM = sendWithSwapUM.confirmUM as? ConfirmUM.Content Column(modifier = modifier) { LazyColumn( - modifier = Modifier.padding(horizontal = 12.dp), + modifier = Modifier + .weight(1f) + .padding(horizontal = 12.dp), ) { item(key = "SendWithSwapBlocks") { Column( @@ -71,7 +78,80 @@ internal fun SendWithSwapConfirmContent( ) } } - SpacerHMax() - SendingText(footerText = confirmUM?.sendingFooter ?: TextReference.EMPTY) + val sendFooter = confirmUM?.sendingFooter ?: TextReference.EMPTY + val legalFooter = getAnnotatedStringForLegals(confirmUM?.tosUM, onClick = onLinkClick) + SendingText( + footerText = if (sendFooter != TextReference.EMPTY || legalFooter != TextReference.EMPTY) { + combinedReference(sendFooter, legalFooter) + } else { + TextReference.EMPTY + }, + ) + } +} + +@Composable +private fun getAnnotatedStringForLegals(tosUM: ConfirmUM.Content.TosUM?, onClick: (String) -> Unit): TextReference { + if (tosUM == null) return TextReference.EMPTY + val tos = tosUM.tosLink + val policy = tosUM.policyLink + return if (tos != null && policy != null) { + val tosTitle = tos.title.resolveReference() + val policyTitle = policy.title.resolveReference() + val fullString = stringResourceSafe(id = R.string.express_legal_two_placeholders, tosTitle, policyTitle) + val tosIndex = fullString.indexOf(tosTitle) + val policyIndex = fullString.indexOf(policyTitle) + + annotatedReference { + append(StringsSigns.POINT_SIGN) + appendSpace() + append(fullString.substring(0, tosIndex)) + withLink( + link = LinkAnnotation.Clickable( + tag = "TOS_TAG", + linkInteractionListener = { onClick(tos.link) }, + ), + block = { + appendColored( + text = fullString.substring(tosIndex, tosIndex + tosTitle.length), + color = TangemTheme.colors.text.accent, + ) + }, + ) + append(fullString.substring(tosIndex + tosTitle.length, policyIndex)) + withLink( + link = LinkAnnotation.Clickable( + tag = "POLICY_TAG", + linkInteractionListener = { onClick(policy.link) }, + ), + block = { + appendColored( + text = fullString.substring(policyIndex, policyIndex + policyTitle.length), + color = TangemTheme.colors.text.accent, + ) + }, + ) + } + } else { + val legal = requireNotNull(tos ?: policy) { "tos or policy must not be null" } + val legalTitle = legal.title.resolveReference() + val fullString = stringResourceSafe(id = R.string.express_legal_one_placeholder, legalTitle) + val legalIndex = fullString.indexOf(legalTitle) + + annotatedReference { + append(fullString.substring(0, legalIndex)) + withLink( + link = LinkAnnotation.Clickable( + tag = "LEGAL_TAG", + linkInteractionListener = { onClick(legal.link) }, + ), + block = { + appendColored( + text = fullString.substring(legalIndex, legalIndex + legalTitle.length), + color = TangemTheme.colors.text.accent, + ) + }, + ) + } } } \ No newline at end of file diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/ui/SendWithSwapContent.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/ui/SendWithSwapContent.kt index 17355d4aa4..e9d03433d4 100644 --- a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/ui/SendWithSwapContent.kt +++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/ui/SendWithSwapContent.kt @@ -59,7 +59,13 @@ internal fun SendWithSwapContent( } // TODO refactor [REDACTED_TASK_KEY] val primaryButton = navigationUM.primaryButton - Row(modifier = Modifier.padding(16.dp)) { + Row( + modifier = Modifier.padding( + start = 16.dp, + end = 16.dp, + bottom = 16.dp, + ), + ) { TangemButton( modifier = Modifier.fillMaxWidth(), text = primaryButton.textReference.resolveReference(),