Updated on 2026-08-14
This commit is contained in:
parent
d5da2a7f08
commit
eee3b57fe5
8 changed files with 183 additions and 108 deletions
|
|
@ -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 = "%"
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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(", ")
|
||||
}
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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<ConfirmUM> {
|
||||
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<NotificationUM>.addTooHighNotification(feeSelectorUM: FeeSelectorUM) {
|
||||
if (feeSelectorUM !is FeeSelectorUM.Content) return
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue