From eee3b57fe5eadbc36063d09b08877f1298babba5 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 15 May 2025 18:03:07 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../java/com/tangem/utils/StringsSigns.kt | 1 + .../features/send/v2/common/ui/SendingText.kt | 51 ++++++++++++++ .../v2/common/utils/ConfirmFooterUtils.kt | 66 ++++++++++++++++++ ...endConfirmationNotificationsTransformer.kt | 69 +++---------------- .../v2/send/confirm/ui/SendConfirmContent.kt | 43 +----------- .../confirm/model/NFTSendConfirmModel.kt | 14 ++-- ...endConfirmationNotificationsTransformer.kt | 42 +++++++++++ .../confirm/ui/NFTSendConfirmContent.kt | 5 ++ 8 files changed, 183 insertions(+), 108 deletions(-) create mode 100644 features/send-v2/impl/src/main/java/com/tangem/features/send/v2/common/ui/SendingText.kt create mode 100644 features/send-v2/impl/src/main/java/com/tangem/features/send/v2/common/utils/ConfirmFooterUtils.kt 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 17a02be930..7d53361c16 100644 --- a/core/utils/src/main/java/com/tangem/utils/StringsSigns.kt +++ b/core/utils/src/main/java/com/tangem/utils/StringsSigns.kt @@ -8,6 +8,7 @@ object StringsSigns { const val DASH_SIGN = "—" const val LOWER_SIGN = "<" const val TILDE_SIGN = "~" + const val COMA_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/ui/SendingText.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/common/ui/SendingText.kt new file mode 100644 index 0000000000..da368be38b --- /dev/null +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/common/ui/SendingText.kt @@ -0,0 +1,51 @@ +package com.tangem.features.send.v2.common.ui + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.core.tween +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.slideInVertically +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.* +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import com.tangem.core.ui.components.Keyboard +import com.tangem.core.ui.components.keyboardAsState +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.resolveAnnotatedReference +import com.tangem.core.ui.res.TangemTheme + +@Composable +internal fun SendingText(footerText: TextReference, modifier: Modifier = Modifier) { + var isVisibleProxy by remember { mutableStateOf(footerText != TextReference.EMPTY) } + val keyboard by keyboardAsState() + + // the text should appear when the keyboard is closed + LaunchedEffect(footerText != TextReference.EMPTY, keyboard) { + if (footerText != TextReference.EMPTY && keyboard is Keyboard.Opened) { + return@LaunchedEffect + } + isVisibleProxy = footerText != TextReference.EMPTY + } + + AnimatedVisibility( + visible = isVisibleProxy, + modifier = modifier, + enter = slideInVertically(initialOffsetY = { it / 2 }) + fadeIn(), + exit = fadeOut(tween(durationMillis = 300)), + label = "Animate show sending state text", + ) { + Text( + text = footerText.resolveAnnotatedReference(), + textAlign = TextAlign.Center, + style = TangemTheme.typography.caption2, + color = TangemTheme.colors.text.primary1, + modifier = Modifier + .fillMaxWidth() + .padding(12.dp), + ) + } +} \ No newline at end of file diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/common/utils/ConfirmFooterUtils.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/common/utils/ConfirmFooterUtils.kt new file mode 100644 index 0000000000..3c13220638 --- /dev/null +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/common/utils/ConfirmFooterUtils.kt @@ -0,0 +1,66 @@ +package com.tangem.features.send.v2.common.utils + +import com.tangem.blockchain.common.Amount +import com.tangem.blockchain.common.transaction.Fee +import com.tangem.core.ui.extensions.* +import com.tangem.core.ui.format.bigdecimal.crypto +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.utils.StringsSigns.COMA_SIGN + +internal fun getTronTokenFeeSendingText(fee: Fee.Tron, fiatFee: String, fiatSending: TextReference): TextReference { + val suffix = when { + fee.remainingEnergy == 0L -> { + resourceReference( + R.string.send_summary_transaction_description_suffix_including, + wrappedList(fiatFee), + ) + } + fee.feeEnergy <= fee.remainingEnergy -> { + resourceReference( + R.string.send_summary_transaction_description_suffix_fee_covered, + wrappedList(fee.feeEnergy), + ) + } + else -> { + resourceReference( + R.string.send_summary_transaction_description_suffix_fee_reduced, + wrappedList(fee.remainingEnergy), + ) + } + } + val prefix = resourceReference( + R.string.send_summary_transaction_description_prefix, + wrappedList(fiatSending), + ) + + return combinedReference(prefix, stringReference("$COMA_SIGN "), suffix) +} + +internal fun formatFooterFiatFee( + amount: Amount?, + isFeeConvertibleToFiat: Boolean, + isFeeApproximate: Boolean, + appCurrency: AppCurrency, +): String { + return if (isFeeConvertibleToFiat) { + amount?.value.format { + fiat( + fiatCurrencyCode = appCurrency.code, + fiatCurrencySymbol = appCurrency.symbol, + ) + } + } else { + amount?.value.format { + crypto( + decimals = amount?.decimals ?: 0, + symbol = amount?.currencySymbol.orEmpty(), + ).fee( + canBeLower = isFeeApproximate, + ) + } + } +} \ No newline at end of file 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 dc73d36994..5167eb5122 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 @@ -1,13 +1,14 @@ package com.tangem.features.send.v2.send.confirm.model.transformers -import com.tangem.blockchain.common.Amount import com.tangem.blockchain.common.transaction.Fee import com.tangem.blockchain.common.transaction.TransactionFee import com.tangem.common.ui.amountScreen.models.AmountState import com.tangem.common.ui.notifications.NotificationUM import com.tangem.core.analytics.api.AnalyticsEventHandler -import com.tangem.core.ui.extensions.* -import com.tangem.core.ui.format.bigdecimal.crypto +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.fee import com.tangem.core.ui.format.bigdecimal.fiat import com.tangem.core.ui.format.bigdecimal.format @@ -16,6 +17,8 @@ import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.tokens.model.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.impl.R import com.tangem.features.send.v2.subcomponents.fee.model.checkIfFeeTooHigh import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeSelectorUM @@ -92,17 +95,18 @@ internal class SendConfirmationNotificationsTransformer( fiatCurrencySymbol = appCurrency.symbol, ) } - val fiatFee = formatFiatFee( + val fiatFee = formatFooterFiatFee( amount = fee.amount, isFeeConvertibleToFiat = feeUM.isFeeConvertibleToFiat, isFeeApproximate = feeUM.isFeeApproximate, + appCurrency = appCurrency, ) return if (feeUM.isTronToken && fee is Fee.Tron) { - getTokenFeeSendingText( + getTronTokenFeeSendingText( fee = fee, fiatFee = fiatFee, - fiatSending = fiatSending, + fiatSending = stringReference(fiatSending), ) } else { resourceReference( @@ -115,57 +119,4 @@ internal class SendConfirmationNotificationsTransformer( ) } } - - private fun formatFiatFee(amount: Amount?, isFeeConvertibleToFiat: Boolean, isFeeApproximate: Boolean): String { - return if (isFeeConvertibleToFiat) { - amount?.value.format { - fiat( - fiatCurrencyCode = appCurrency.code, - fiatCurrencySymbol = appCurrency.symbol, - ) - } - } else { - amount?.value.format { - crypto( - decimals = amount?.decimals ?: 0, - symbol = amount?.currencySymbol.orEmpty(), - ).fee( - canBeLower = isFeeApproximate, - ) - } - } - } - - private fun getTokenFeeSendingText(fee: Fee.Tron, fiatFee: String, fiatSending: String): TextReference { - val suffix = when { - fee.remainingEnergy == 0L -> { - resourceReference( - R.string.send_summary_transaction_description_suffix_including, - wrappedList(fiatFee), - ) - } - fee.feeEnergy <= fee.remainingEnergy -> { - resourceReference( - R.string.send_summary_transaction_description_suffix_fee_covered, - wrappedList(fee.feeEnergy), - ) - } - else -> { - resourceReference( - R.string.send_summary_transaction_description_suffix_fee_reduced, - wrappedList(fee.remainingEnergy), - ) - } - } - val prefix = resourceReference( - R.string.send_summary_transaction_description_prefix, - wrappedList(fiatSending), - ) - - return combinedReference(prefix, COMMA_SEPARATOR, suffix) - } - - companion object { - private val COMMA_SEPARATOR = stringReference(", ") - } } \ No newline at end of file diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/ui/SendConfirmContent.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/ui/SendConfirmContent.kt index bcf7d3283a..4f13d834a7 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/ui/SendConfirmContent.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/send/confirm/ui/SendConfirmContent.kt @@ -1,33 +1,24 @@ package com.tangem.features.send.v2.send.confirm.ui import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.core.tween -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.animation.slideInVertically import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListScope -import androidx.compose.material3.Text import androidx.compose.runtime.* import androidx.compose.ui.Modifier -import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.tangem.common.ui.notifications.NotificationUM -import com.tangem.core.ui.components.Keyboard import com.tangem.core.ui.components.SpacerHMax -import com.tangem.core.ui.components.keyboardAsState import com.tangem.core.ui.components.transactions.TransactionDoneTitle import com.tangem.core.ui.extensions.TextReference -import com.tangem.core.ui.extensions.resolveAnnotatedReference import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.wrappedList import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.utils.DateTimeFormatters import com.tangem.core.ui.utils.toTimeFormat +import com.tangem.features.send.v2.common.ui.SendingText import com.tangem.features.send.v2.common.ui.state.ConfirmUM import com.tangem.features.send.v2.common.ui.tapHelp import com.tangem.features.send.v2.impl.R @@ -82,38 +73,6 @@ internal fun SendConfirmContent( } } -@Composable -private fun SendingText(footerText: TextReference, modifier: Modifier = Modifier) { - var isVisibleProxy by remember { mutableStateOf(footerText != TextReference.EMPTY) } - val keyboard by keyboardAsState() - - // the text should appear when the keyboard is closed - LaunchedEffect(footerText != TextReference.EMPTY, keyboard) { - if (footerText != TextReference.EMPTY && keyboard is Keyboard.Opened) { - return@LaunchedEffect - } - isVisibleProxy = footerText != TextReference.EMPTY - } - - AnimatedVisibility( - visible = isVisibleProxy, - modifier = modifier, - enter = slideInVertically() + fadeIn(), - exit = fadeOut(tween(durationMillis = 300)), - label = "Animate show sending state text", - ) { - Text( - text = footerText.resolveAnnotatedReference(), - textAlign = TextAlign.Center, - style = TangemTheme.typography.caption2, - color = TangemTheme.colors.text.primary1, - modifier = Modifier - .fillMaxWidth() - .padding(12.dp), - ) - } -} - private fun LazyListScope.blocks( uiState: SendUM, destinationBlockComponent: SendDestinationBlockComponent, diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/confirm/model/NFTSendConfirmModel.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/confirm/model/NFTSendConfirmModel.kt index aafd0448ea..1cc52b7256 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/confirm/model/NFTSendConfirmModel.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/confirm/model/NFTSendConfirmModel.kt @@ -12,7 +12,7 @@ import com.tangem.core.decompose.navigation.Router import com.tangem.core.navigation.share.ShareManager import com.tangem.core.navigation.url.UrlOpener import com.tangem.core.ui.extensions.resourceReference -import com.tangem.core.ui.extensions.wrappedList +import com.tangem.core.ui.extensions.stringReference import com.tangem.datasource.local.nft.converter.NFTSdkAssetConverter import com.tangem.domain.feedback.GetCardInfoUseCase import com.tangem.domain.feedback.SaveBlockchainErrorUseCase @@ -228,6 +228,7 @@ internal class NFTSendConfirmModel @Inject constructor( it.copy( confirmUM = NFTSendConfirmInitialStateTransformer( isShowTapHelp = isShowTapHelp, + walletName = stringReference(userWallet.name), ).transform(uiState.value.confirmUM), ) } @@ -357,6 +358,7 @@ internal class NFTSendConfirmModel @Inject constructor( analyticsEventHandler = analyticsEventHandler, cryptoCurrency = cryptoCurrencyStatus.currency, analyticsCategoryName = analyticsCategoryName, + appCurrency = params.appCurrency, ).transform(uiState.value.confirmUM), ) } @@ -369,15 +371,13 @@ internal class NFTSendConfirmModel @Inject constructor( transform = { state, route -> state to route }, ).onEach { (state, _) -> val confirmUM = state.confirmUM - val isReadyToSend = confirmUM is ConfirmUM.Content && !confirmUM.isSending + val confirmUMContent = confirmUM as? ConfirmUM.Content + val isReadyToSend = confirmUMContent != null && !confirmUM.isSending params.callback.onResult( state.copy( navigationUM = NavigationUM.Content( - title = resourceReference( - id = R.string.send_summary_title, - formatArgs = wrappedList(params.cryptoCurrencyStatus.currency.name), - ), - subtitle = null, + title = resourceReference(R.string.nft_send), + subtitle = confirmUMContent?.walletName, backIconRes = R.drawable.ic_close_24, backIconClick = { analyticsEventHandler.send( 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 f5b2ba2744..742dcea1cf 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 @@ -1,12 +1,20 @@ package com.tangem.features.send.v2.sendnft.confirm.model.transformers +import com.tangem.blockchain.common.transaction.Fee import com.tangem.blockchain.common.transaction.TransactionFee import com.tangem.common.ui.notifications.NotificationUM import com.tangem.core.analytics.api.AnalyticsEventHandler +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.resourceReference +import com.tangem.core.ui.extensions.wrappedList import com.tangem.core.ui.utils.parseToBigDecimal +import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.tokens.model.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.impl.R import com.tangem.features.send.v2.subcomponents.fee.model.checkIfFeeTooHigh import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeSelectorUM import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeType @@ -19,11 +27,13 @@ internal class NFTSendConfirmationNotificationsTransformer( private val analyticsEventHandler: AnalyticsEventHandler, private val cryptoCurrency: CryptoCurrency, private val analyticsCategoryName: String, + private val appCurrency: AppCurrency, ) : Transformer { override fun transform(prevState: ConfirmUM): ConfirmUM { val state = prevState as? ConfirmUM.Content ?: return prevState val feeUM = feeUM as? FeeUM.Content ?: return prevState return state.copy( + sendingFooter = getSendingFooterText(), notifications = buildList { addTooHighNotification(feeUM.feeSelectorUM) addTooLowNotification(feeUM) @@ -48,6 +58,38 @@ internal class NFTSendConfirmationNotificationsTransformer( } } + private fun getSendingFooterText(): TextReference { + val feeUM = feeUM as? FeeUM.Content + val fee = (feeUM?.feeSelectorUM as? FeeSelectorUM.Content)?.selectedFee ?: return TextReference.EMPTY + + val fiatFee = formatFooterFiatFee( + amount = fee.amount, + isFeeConvertibleToFiat = feeUM.isFeeConvertibleToFiat, + isFeeApproximate = feeUM.isFeeApproximate, + appCurrency = appCurrency, + ) + + return if (feeUM.isTronToken && fee is Fee.Tron) { + getTronTokenFeeSendingText( + fee = fee, + fiatFee = fiatFee, + fiatSending = resourceReference(R.string.common_nft), + ) + } else { + resourceReference( + id = if (feeUM.isFeeConvertibleToFiat) { + R.string.send_summary_transaction_description + } else { + R.string.send_summary_transaction_description_no_fiat_fee + }, + formatArgs = wrappedList( + resourceReference(R.string.common_nft), + fiatFee, + ), + ) + } + } + private fun MutableList.addTooHighNotification(feeSelectorUM: FeeSelectorUM) { if (feeSelectorUM !is FeeSelectorUM.Content) return diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/confirm/ui/NFTSendConfirmContent.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/confirm/ui/NFTSendConfirmContent.kt index 735f3ecaf0..2d41666e61 100644 --- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/confirm/ui/NFTSendConfirmContent.kt +++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/sendnft/confirm/ui/NFTSendConfirmContent.kt @@ -11,13 +11,16 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.tangem.common.ui.notifications.NotificationUM +import com.tangem.core.ui.components.SpacerHMax import com.tangem.core.ui.components.transactions.TransactionDoneTitle +import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.wrappedList import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.utils.DateTimeFormatters import com.tangem.core.ui.utils.toTimeFormat import com.tangem.features.nft.component.NFTDetailsBlockComponent +import com.tangem.features.send.v2.common.ui.SendingText import com.tangem.features.send.v2.common.ui.state.ConfirmUM import com.tangem.features.send.v2.common.ui.tapHelp import com.tangem.features.send.v2.impl.R @@ -66,6 +69,8 @@ internal fun NFTSendConfirmContent( ) } } + SpacerHMax() + SendingText(footerText = confirmUM?.sendingFooter ?: TextReference.EMPTY) } }