Updated on 2026-08-14

This commit is contained in:
Tangem 2025-10-22 22:05:13 +05:00
parent 8c258d0b7c
commit aa6f185cd1
19 changed files with 343 additions and 205 deletions

View file

@ -13,10 +13,12 @@ internal sealed class YieldSupplyFeeUM {
data object Error : YieldSupplyFeeUM()
data class Content(
val transactionDataList: ImmutableList<TransactionData.Uncompiled>,
val feeValue: TextReference,
val currentNetworkFeeValue: TextReference,
val maxNetworkFeeValue: TextReference,
val minAmountFeeValue: TextReference,
val feeFiatValue: TextReference,
val tokenFeeFiatValue: TextReference,
val maxNetworkFeeFiatValue: TextReference,
val minTopUpFiatValue: TextReference,
val feeNoteValue: TextReference = TextReference.EMPTY,
val minFeeNoteValue: TextReference = TextReference.EMPTY,
) : YieldSupplyFeeUM()
}

View file

@ -3,11 +3,13 @@ package com.tangem.features.yield.supply.impl.common.ui
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.key
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.text.LinkAnnotation
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withLink
@ -85,13 +87,17 @@ internal fun YieldSupplyActionContent(
),
) {
val fee = when (val yieldSupplyFeeUM = yieldSupplyActionUM.yieldSupplyFeeUM) {
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.feeValue
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.feeFiatValue
YieldSupplyFeeUM.Error -> stringReference(StringsSigns.DASH_SIGN)
YieldSupplyFeeUM.Loading -> null
}
YieldSupplyFeeRow(
title = resourceReference(R.string.common_network_fee_title),
value = fee,
modifier = Modifier.fillMaxWidth()
.clip(RoundedCornerShape(14.dp))
.background(TangemTheme.colors.background.action)
.padding(horizontal = 16.dp, vertical = 12.dp),
)
}
}
@ -138,10 +144,11 @@ private class YieldSupplyActionContentPreviewProvider : PreviewParameterProvider
currencyIconState = CurrencyIconState.Loading,
yieldSupplyFeeUM = YieldSupplyFeeUM.Content(
transactionDataList = persistentListOf(),
feeValue = stringReference("0.00020 ETH • \$0.99"),
currentNetworkFeeValue = stringReference("1.45 USDT • \$1.45"),
maxNetworkFeeValue = stringReference("8.50 USDT • \$8.50"),
minAmountFeeValue = stringReference("50 USDT • \$50"),
feeFiatValue = stringReference("$0.99"),
tokenFeeFiatValue = stringReference("$1.45"),
maxNetworkFeeFiatValue = stringReference("$8.50"),
minTopUpFiatValue = stringReference("$50"),
feeNoteValue = TextReference.EMPTY,
),
isPrimaryButtonEnabled = false,
isTransactionSending = false,

View file

@ -1,17 +1,12 @@
package com.tangem.features.yield.supply.impl.common.ui
import androidx.compose.animation.AnimatedContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.SpacerWMax
@ -23,15 +18,11 @@ import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.yield.supply.impl.R
@Composable
internal fun YieldSupplyFeeRow(title: TextReference, value: TextReference?) {
internal fun YieldSupplyFeeRow(title: TextReference, value: TextReference?, modifier: Modifier = Modifier) {
Row(
horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(14.dp))
.background(TangemTheme.colors.background.action)
.padding(horizontal = 16.dp, vertical = 12.dp),
modifier = modifier,
) {
Text(
text = title.resolveReference(),

View file

@ -14,6 +14,7 @@ internal data class YieldSupplyActiveContentUM(
val minAmount: TextReference?,
val currentFee: TextReference?,
val feeDescription: TextReference?,
val minFeeDescription: TextReference?,
val apy: TextReference? = null,
val isHighFee: Boolean = false,
)

View file

@ -12,7 +12,6 @@ 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.crypto
import com.tangem.core.ui.format.bigdecimal.fiat
import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.model.AppCurrency
@ -25,11 +24,13 @@ import com.tangem.domain.yield.supply.usecase.YieldSupplyGetCurrentFeeUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetMaxFeeUseCase
import com.tangem.features.yield.supply.api.analytics.YieldSupplyAnalytics
import com.tangem.features.yield.supply.impl.R
import com.tangem.features.yield.supply.impl.common.formatter.YieldSupplyAmountFormatter
import com.tangem.features.yield.supply.impl.subcomponents.active.YieldSupplyActiveComponent
import com.tangem.features.yield.supply.impl.subcomponents.active.entity.YieldSupplyActiveContentUM
import com.tangem.features.yield.supply.impl.subcomponents.active.model.transformers.YieldSupplyActiveMinAmountTransformer
import com.tangem.features.yield.supply.impl.subcomponents.active.model.transformers.YieldSupplyActiveFeeContentTransformer
import com.tangem.utils.StringsSigns.DASH_SIGN
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.transformer.update
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList
@ -75,6 +76,7 @@ internal class YieldSupplyActiveModel @Inject constructor(
currentFee = null,
feeDescription = null,
isHighFee = false,
minFeeDescription = null,
),
)
@ -202,20 +204,19 @@ internal class YieldSupplyActiveModel @Inject constructor(
params.userWallet,
cryptoCurrencyStatusFlow.value,
).onRight { minAmount ->
val minAmountTextReference = YieldSupplyAmountFormatter(
cryptoCurrencyStatusFlow.value.currency,
appCurrency,
).invoke(
feeValue = minAmount,
fiatRate = cryptoCurrencyStatusFlow.value.value.fiatRate,
showCrypto = false,
uiState.update(
YieldSupplyActiveMinAmountTransformer(
cryptoCurrencyStatus = cryptoCurrencyStatusFlow.value,
appCurrency = appCurrency,
minAmount = minAmount,
),
)
uiState.update {
it.copy(minAmount = minAmountTextReference)
}
}.onLeft {
uiState.update {
it.copy(minAmount = TextReference.Str(DASH_SIGN))
it.copy(
minAmount = TextReference.Str(DASH_SIGN),
feeDescription = null,
)
}
}
}
@ -235,33 +236,23 @@ internal class YieldSupplyActiveModel @Inject constructor(
cryptoCurrencyStatus = cryptoStatus,
).getOrNull()
val currentFeeText = currentFee?.let {
YieldSupplyAmountFormatter(
cryptoStatus.currency,
appCurrency,
).invoke(
feeValue = it,
fiatRate = cryptoStatus.value.fiatRate,
showCrypto = false,
if (currentFee != null && maxFee != null) {
uiState.update(
YieldSupplyActiveFeeContentTransformer(
cryptoCurrencyStatus = cryptoStatus,
appCurrency = appCurrency,
feeValue = currentFee,
maxNetworkFee = maxFee,
),
)
}
val isHighFee = if (currentFee != null && maxFee != null) currentFee > maxFee else false
val maxFiatFee = maxFee?.multiply(cryptoStatus.value.fiatRate)
.format { fiat(appCurrency.code, appCurrency.symbol) }
val feeDescription = if (isHighFee) {
resourceReference(R.string.yield_module_earn_sheet_high_fee_description, wrappedList(maxFiatFee))
} else {
resourceReference(R.string.yield_module_earn_sheet_fee_description, wrappedList(maxFiatFee))
}
uiState.update {
it.copy(
currentFee = currentFeeText ?: stringReference(DASH_SIGN),
isHighFee = isHighFee,
feeDescription = feeDescription,
)
uiState.update {
it.copy(
currentFee = stringReference(DASH_SIGN),
feeDescription = null,
isHighFee = false,
)
}
}
}
}

View file

@ -0,0 +1,57 @@
package com.tangem.features.yield.supply.impl.subcomponents.active.model.transformers
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.crypto
import com.tangem.core.ui.format.bigdecimal.fiat
import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.core.ui.extensions.TextReference
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.features.yield.supply.impl.R
import com.tangem.features.yield.supply.impl.subcomponents.active.entity.YieldSupplyActiveContentUM
import com.tangem.utils.transformer.Transformer
import java.math.BigDecimal
/**
* Computes fee description and current fee values for Active screen based on token rates.
*/
internal class YieldSupplyActiveFeeContentTransformer(
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
private val appCurrency: AppCurrency,
private val feeValue: BigDecimal,
private val maxNetworkFee: BigDecimal,
) : Transformer<YieldSupplyActiveContentUM> {
override fun transform(prevState: YieldSupplyActiveContentUM): YieldSupplyActiveContentUM {
val cryptoCurrency = cryptoCurrencyStatus.currency
val tokenFiatRate = cryptoCurrencyStatus.value.fiatRate
val tokenCryptoFeeValueText = feeValue.format { crypto(cryptoCurrency) }
val tokenFiatFee = tokenFiatRate?.let(feeValue::multiply)
val tokenFiatFeeValueText = tokenFiatFee.format { fiat(appCurrency.code, appCurrency.symbol) }
val maxFeeCryptoValueText = maxNetworkFee.format { crypto(cryptoCurrency) }
val maxFiatFee = tokenFiatRate?.let { rate -> maxNetworkFee.multiply(rate) }
val maxFiatFeeValueText = maxFiatFee.format { fiat(appCurrency.code, appCurrency.symbol) }
val feeNoteValue: TextReference = resourceReference(
id = R.string.yield_module_fee_policy_sheet_fee_note,
formatArgs = wrappedList(
stringReference(tokenFiatFeeValueText),
stringReference(tokenCryptoFeeValueText),
stringReference(maxFiatFeeValueText),
stringReference(maxFeeCryptoValueText),
),
)
val isHighFee = feeValue > maxNetworkFee
return prevState.copy(
currentFee = stringReference(tokenFiatFeeValueText),
feeDescription = feeNoteValue,
isHighFee = isHighFee,
)
}
}

View file

@ -0,0 +1,46 @@
package com.tangem.features.yield.supply.impl.subcomponents.active.model.transformers
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.crypto
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.domain.models.currency.CryptoCurrencyStatus
import com.tangem.features.yield.supply.impl.R
import com.tangem.features.yield.supply.impl.subcomponents.active.entity.YieldSupplyActiveContentUM
import com.tangem.utils.transformer.Transformer
import java.math.BigDecimal
/**
* Computes and sets minimum amount (fiat) and fee description note
*/
internal class YieldSupplyActiveMinAmountTransformer(
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
private val appCurrency: AppCurrency,
private val minAmount: BigDecimal,
) : Transformer<YieldSupplyActiveContentUM> {
override fun transform(prevState: YieldSupplyActiveContentUM): YieldSupplyActiveContentUM {
val cryptoCurrency = cryptoCurrencyStatus.currency
val tokenFiatRate = cryptoCurrencyStatus.value.fiatRate
val minAmountCryptoText = minAmount.format { crypto(cryptoCurrency) }
val minAmountFiat = tokenFiatRate?.let(minAmount::multiply)
val minAmountFiatText = minAmountFiat.format { fiat(appCurrency.code, appCurrency.symbol) }
val minFeeNoteValue = resourceReference(
id = R.string.yield_module_fee_policy_sheet_min_amount_note,
formatArgs = wrappedList(
minAmountFiatText,
minAmountCryptoText,
),
)
return prevState.copy(
minAmount = stringReference(minAmountFiatText),
minFeeDescription = minFeeNoteValue,
)
}
}

View file

@ -91,12 +91,14 @@ internal fun YieldSupplyActiveContent(
)
}
Text(
modifier = Modifier.padding(horizontal = 12.dp),
text = stringResourceSafe(R.string.yield_module_fee_policy_sheet_min_amount_note),
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
)
AnimatedVisibility(state.minFeeDescription != null) {
Text(
modifier = Modifier.padding(horizontal = 12.dp),
text = state.minFeeDescription?.resolveReference().orEmpty(),
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
)
}
}
}
@ -376,6 +378,10 @@ private class YieldSupplyActiveBottomSheetPreviewProvider : PreviewParameterProv
),
apy = stringReference("5,14%"),
isHighFee = true,
minFeeDescription = stringReference(
"The network fee is currently too high to execute lending." +
"Funds will be supplied once it drops to \$12 or below. ",
),
),
)
}

View file

@ -10,7 +10,6 @@ import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
import com.tangem.core.ui.extensions.*
import com.tangem.core.ui.format.bigdecimal.crypto
import com.tangem.core.ui.format.bigdecimal.fiat
import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
@ -33,7 +32,7 @@ import com.tangem.features.yield.supply.impl.subcomponents.approve.YieldSupplyAp
import com.tangem.features.yield.supply.impl.subcomponents.notifications.YieldSupplyNotificationsComponent
import com.tangem.features.yield.supply.impl.subcomponents.notifications.YieldSupplyNotificationsUpdateTrigger
import com.tangem.features.yield.supply.impl.subcomponents.notifications.entity.YieldSupplyNotificationData
import com.tangem.utils.StringsSigns.DOT
import com.tangem.core.ui.extensions.TextReference
import com.tangem.utils.TangemBlogUrlBuilder
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.transformer.update
@ -220,7 +219,6 @@ internal class YieldSupplyApproveModel @Inject constructor(
val feeFiatValue = feeCryptoCurrencyStatus.value.fiatRate?.let { rate ->
feeCryptoValue?.multiply(rate)
}
val cryptoFee = feeCryptoValue.format { crypto(feeCryptoCurrencyStatus.currency) }
val fiatFee = feeFiatValue.format { fiat(appCurrency.code, appCurrency.symbol) }
uiState.update {
@ -233,14 +231,11 @@ internal class YieldSupplyApproveModel @Inject constructor(
transactionDataList = persistentListOf(
approvalTransitionData.copy(fee = transactionFee.normal),
),
feeValue = combinedReference(
stringReference(cryptoFee),
stringReference(" $DOT "),
stringReference(fiatFee),
),
currentNetworkFeeValue = TextReference.EMPTY,
maxNetworkFeeValue = TextReference.EMPTY,
minAmountFeeValue = TextReference.EMPTY,
feeFiatValue = stringReference(fiatFee),
tokenFeeFiatValue = TextReference.EMPTY,
maxNetworkFeeFiatValue = TextReference.EMPTY,
minTopUpFiatValue = TextReference.EMPTY,
feeNoteValue = TextReference.EMPTY,
),
)
}

View file

@ -38,7 +38,6 @@ internal class YieldSupplyFeePolicyComponent(
YieldSupplyFeePolicyContent(
yieldSupplyFeeUM = uiState.yieldSupplyFeeUM,
tokenSymbol = params.cryptoCurrency.symbol,
networkName = params.cryptoCurrency.network.name,
modifier = modifier,
)
}

View file

@ -6,10 +6,12 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@ -34,7 +36,6 @@ import kotlinx.collections.immutable.persistentListOf
internal fun YieldSupplyFeePolicyContent(
yieldSupplyFeeUM: YieldSupplyFeeUM,
tokenSymbol: String,
networkName: String,
modifier: Modifier = Modifier,
) {
Column(
@ -62,68 +63,51 @@ internal fun YieldSupplyFeePolicyContent(
modifier = Modifier.padding(horizontal = 16.dp),
)
SpacerH24()
FooterContainer(
footer = resourceReference(
id = R.string.yield_module_fee_policy_sheet_min_amount_note,
formatArgs = wrappedList(networkName),
),
paddingValues = PaddingValues(
top = 8.dp,
start = 12.dp,
end = 12.dp,
),
) {
val minAmount = when (yieldSupplyFeeUM) {
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.minAmountFeeValue
YieldSupplyFeeUM.Error -> stringReference(StringsSigns.DASH_SIGN)
YieldSupplyFeeUM.Loading -> null
}
YieldSupplyFeeRow(
title = resourceReference(R.string.yield_module_fee_policy_sheet_min_amount_title),
value = minAmount,
)
}
MinFeeNote(yieldSupplyFeeUM)
SpacerH16()
val feeNote = when (yieldSupplyFeeUM) {
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.feeNoteValue
YieldSupplyFeeUM.Error -> null
YieldSupplyFeeUM.Loading -> null
}
FooterContainer(
footer = resourceReference(
id = R.string.yield_module_fee_policy_sheet_current_fee_note,
formatArgs = wrappedList(networkName),
),
footer = feeNote,
paddingValues = PaddingValues(
top = 8.dp,
start = 12.dp,
end = 12.dp,
),
) {
val currentFee = when (yieldSupplyFeeUM) {
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.currentNetworkFeeValue
YieldSupplyFeeUM.Error -> stringReference(StringsSigns.DASH_SIGN)
YieldSupplyFeeUM.Loading -> null
Column(
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(14.dp))
.background(TangemTheme.colors.background.action)
.padding(horizontal = 16.dp),
) {
val currentFee = when (yieldSupplyFeeUM) {
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.tokenFeeFiatValue
YieldSupplyFeeUM.Error -> stringReference(StringsSigns.DASH_SIGN)
YieldSupplyFeeUM.Loading -> null
}
YieldSupplyFeeRow(
title = resourceReference(R.string.yield_module_fee_policy_sheet_current_fee_title),
value = currentFee,
modifier = Modifier.padding(vertical = 12.dp),
)
val maxFee = when (yieldSupplyFeeUM) {
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.maxNetworkFeeFiatValue
YieldSupplyFeeUM.Error -> stringReference(StringsSigns.DASH_SIGN)
YieldSupplyFeeUM.Loading -> null
}
YieldSupplyFeeRow(
title = resourceReference(R.string.yield_module_fee_policy_sheet_max_fee_title),
value = maxFee,
modifier = Modifier.padding(vertical = 12.dp),
)
}
YieldSupplyFeeRow(
title = resourceReference(R.string.yield_module_fee_policy_sheet_current_fee_title),
value = currentFee,
)
}
SpacerH16()
FooterContainer(
footer = resourceReference(R.string.yield_module_fee_policy_sheet_max_fee_note),
paddingValues = PaddingValues(
top = 8.dp,
start = 12.dp,
end = 12.dp,
),
) {
val maxFee = when (yieldSupplyFeeUM) {
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.maxNetworkFeeValue
YieldSupplyFeeUM.Error -> stringReference(StringsSigns.DASH_SIGN)
YieldSupplyFeeUM.Loading -> null
}
YieldSupplyFeeRow(
title = resourceReference(R.string.yield_module_fee_policy_sheet_max_fee_title),
value = maxFee,
)
}
SpacerH8()
Text(
text = stringResourceSafe(R.string.yield_module_fee_policy_tangem_service_fee_title),
style = TangemTheme.typography.caption2,
@ -139,6 +123,38 @@ internal fun YieldSupplyFeePolicyContent(
}
}
@Composable
private fun MinFeeNote(yieldSupplyFeeUM: YieldSupplyFeeUM) {
val minFeeNote = when (yieldSupplyFeeUM) {
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.feeNoteValue
YieldSupplyFeeUM.Error -> null
YieldSupplyFeeUM.Loading -> null
}
FooterContainer(
footer = minFeeNote,
paddingValues = PaddingValues(
top = 8.dp,
start = 12.dp,
end = 12.dp,
),
) {
val minAmount = when (yieldSupplyFeeUM) {
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.minTopUpFiatValue
YieldSupplyFeeUM.Error -> stringReference(StringsSigns.DASH_SIGN)
YieldSupplyFeeUM.Loading -> null
}
YieldSupplyFeeRow(
title = resourceReference(R.string.yield_module_fee_policy_sheet_min_amount_title),
value = minAmount,
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(14.dp))
.background(TangemTheme.colors.background.action)
.padding(horizontal = 16.dp, vertical = 12.dp),
)
}
}
// region Preview
@Composable
@Preview(showBackground = true, widthDp = 360)
@ -148,13 +164,21 @@ private fun YieldSupplyFeePolicyContent_Preview() {
YieldSupplyFeePolicyContent(
yieldSupplyFeeUM = YieldSupplyFeeUM.Content(
transactionDataList = persistentListOf(),
feeValue = stringReference("0.0001 ETH • \$1.45"),
maxNetworkFeeValue = stringReference("8.50 USDT • \$8.50"),
currentNetworkFeeValue = stringReference("1.45 USDT • \$1.45"),
minAmountFeeValue = stringReference("50 USDT • \$50"),
feeFiatValue = stringReference("$1.45"),
maxNetworkFeeFiatValue = stringReference("$8.50"),
tokenFeeFiatValue = stringReference("$1.45"),
minTopUpFiatValue = stringReference("$50"),
feeNoteValue = resourceReference(
id = R.string.yield_module_fee_policy_sheet_fee_note,
formatArgs = wrappedList(
stringReference("$1.45"),
stringReference("1.46 USDT"),
stringReference("$8.50"),
stringReference("8.50 USDT"),
),
),
),
tokenSymbol = "USDT",
networkName = "Ethereum",
modifier = Modifier.background(TangemTheme.colors.background.primary),
)
}

View file

@ -1,17 +1,17 @@
package com.tangem.features.yield.supply.impl.subcomponents.startearning.model.transformers
import com.tangem.blockchain.common.TransactionData
import com.tangem.core.ui.extensions.combinedReference
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.crypto
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.domain.models.currency.CryptoCurrencyStatus
import com.tangem.features.yield.supply.impl.R
import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyActionUM
import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyFeeUM
import com.tangem.features.yield.supply.impl.common.formatter.YieldSupplyAmountFormatter
import com.tangem.utils.StringsSigns.DOT
import com.tangem.utils.transformer.Transformer
import kotlinx.collections.immutable.toPersistentList
import java.math.BigDecimal
@ -29,30 +29,46 @@ internal class YieldSupplyStartEarningFeeContentTransformer(
) : Transformer<YieldSupplyActionUM> {
override fun transform(prevState: YieldSupplyActionUM): YieldSupplyActionUM {
val cryptoCurrency = cryptoCurrencyStatus.currency
val fiatRate = cryptoCurrencyStatus.value.fiatRate
val tokenFiatRate = cryptoCurrencyStatus.value.fiatRate
val feeFiatRate = feeCryptoCurrencyStatus.value.fiatRate
val crypto = feeValue.format { crypto(feeCryptoCurrencyStatus.currency) }
val fiatFeeValue = feeFiatRate?.let(feeValue::multiply)
val feeFiat = feeFiatRate?.let(feeValue::multiply)
val feeFiatValueText = feeFiat.format { fiat(appCurrency.code, appCurrency.symbol) }
val fiat = fiatFeeValue.format { fiat(appCurrency.code, appCurrency.symbol) }
val tokenCryptoFeeValue = fiatRate?.let { rate ->
fiatFeeValue?.divide(rate, cryptoCurrency.decimals, RoundingMode.HALF_UP)
val tokenCryptoFee = tokenFiatRate?.let { rate ->
feeFiat?.divide(rate, cryptoCurrency.decimals, RoundingMode.HALF_UP)
}
val tokenCryptoFeeValueText = tokenCryptoFee.format { crypto(cryptoCurrency) }
val tokenFiatFee = feeFiat // same fiat amount
val tokenFiatFeeValueText = tokenFiatFee.format { fiat(appCurrency.code, appCurrency.symbol) }
val tokenCryptoFee = tokenCryptoFeeValue.format { crypto(cryptoCurrency) }
val maxCryptoFee = maxNetworkFee.format { crypto(cryptoCurrency) }
val maxFiatFeeValue = fiatRate?.let { rate ->
maxNetworkFee.divide(rate, cryptoCurrency.decimals, RoundingMode.HALF_UP)
val maxFeeCryptoValueText = maxNetworkFee.format { crypto(cryptoCurrency) }
val maxFiatFee = tokenFiatRate?.let { rate ->
maxNetworkFee.multiply(rate)
}
val maxFiatFee = maxFiatFeeValue.format { fiat(appCurrency.code, appCurrency.symbol) }
val maxFiatFeeValueText = maxFiatFee.format { fiat(appCurrency.code, appCurrency.symbol) }
val minAmountTextReference = YieldSupplyAmountFormatter(
cryptoCurrency,
appCurrency,
).invoke(minAmount, cryptoCurrencyStatus.value.fiatRate)
val minAmountCryptoText = minAmount.format { crypto(cryptoCurrency) }
val minAmountFiat = tokenFiatRate?.let(minAmount::multiply)
val minAmountFiatText = minAmountFiat.format { fiat(appCurrency.code, appCurrency.symbol) }
val feeNoteValue = resourceReference(
id = R.string.yield_module_fee_policy_sheet_fee_note,
formatArgs = wrappedList(
tokenFiatFeeValueText,
tokenCryptoFeeValueText,
maxFiatFeeValueText,
maxFeeCryptoValueText,
),
)
val minFeeNoteValue = resourceReference(
id = R.string.yield_module_fee_policy_sheet_min_amount_note,
formatArgs = wrappedList(
minAmountFiatText,
minAmountCryptoText,
),
)
return if (cryptoCurrencyStatus.value is CryptoCurrencyStatus.Loading) {
prevState.copy(yieldSupplyFeeUM = YieldSupplyFeeUM.Loading)
@ -60,22 +76,12 @@ internal class YieldSupplyStartEarningFeeContentTransformer(
prevState.copy(
yieldSupplyFeeUM = YieldSupplyFeeUM.Content(
transactionDataList = updatedTransactionList.toPersistentList(),
feeValue = combinedReference(
stringReference(crypto),
stringReference(" $DOT "),
stringReference(fiat),
),
currentNetworkFeeValue = combinedReference(
stringReference(tokenCryptoFee),
stringReference(" $DOT "),
stringReference(fiat),
),
maxNetworkFeeValue = combinedReference(
stringReference(maxCryptoFee),
stringReference(" $DOT "),
stringReference(maxFiatFee),
),
minAmountFeeValue = minAmountTextReference,
feeFiatValue = stringReference(feeFiatValueText),
tokenFeeFiatValue = stringReference(tokenFiatFeeValueText),
maxNetworkFeeFiatValue = stringReference(maxFiatFeeValueText),
minTopUpFiatValue = stringReference(minAmountFiatText),
feeNoteValue = feeNoteValue,
minFeeNoteValue = minFeeNoteValue,
),
)
}

View file

@ -2,16 +2,13 @@ package com.tangem.features.yield.supply.impl.subcomponents.stopearning.model.tr
import com.tangem.blockchain.common.TransactionData
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.combinedReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.format.bigdecimal.crypto
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.domain.models.currency.CryptoCurrencyStatus
import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyActionUM
import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyFeeUM
import com.tangem.utils.StringsSigns.DOT
import com.tangem.utils.transformer.Transformer
import kotlinx.collections.immutable.toPersistentList
import java.math.BigDecimal
@ -24,11 +21,10 @@ internal class YieldSupplyStopEarningFeeContentTransformer(
private val feeValue: BigDecimal,
) : Transformer<YieldSupplyActionUM> {
override fun transform(prevState: YieldSupplyActionUM): YieldSupplyActionUM {
val feeFiatValue = feeCryptoCurrencyStatus.value.fiatRate?.let { rate ->
val feeFiatValueRaw = feeCryptoCurrencyStatus.value.fiatRate?.let { rate ->
feeValue.multiply(rate)
}
val cryptoFee = feeValue.format { crypto(feeCryptoCurrencyStatus.currency) }
val fiatFee = feeFiatValue.format { fiat(appCurrency.code, appCurrency.symbol) }
val fiatFeeText = feeFiatValueRaw.format { fiat(appCurrency.code, appCurrency.symbol) }
return if (cryptoCurrencyStatus.value is CryptoCurrencyStatus.Loading) {
prevState.copy(yieldSupplyFeeUM = YieldSupplyFeeUM.Loading)
@ -37,14 +33,11 @@ internal class YieldSupplyStopEarningFeeContentTransformer(
isPrimaryButtonEnabled = true,
yieldSupplyFeeUM = YieldSupplyFeeUM.Content(
transactionDataList = transactions.toPersistentList(),
feeValue = combinedReference(
stringReference(cryptoFee),
stringReference(" $DOT "),
stringReference(fiatFee),
),
currentNetworkFeeValue = TextReference.EMPTY,
maxNetworkFeeValue = TextReference.EMPTY,
minAmountFeeValue = TextReference.EMPTY,
feeFiatValue = stringReference(fiatFeeText),
tokenFeeFiatValue = TextReference.EMPTY,
maxNetworkFeeFiatValue = TextReference.EMPTY,
minTopUpFiatValue = TextReference.EMPTY,
feeNoteValue = TextReference.EMPTY,
),
)
}