Updated on 2026-08-14

This commit is contained in:
Tangem 2025-09-19 14:18:28 +05:00
commit 1456166220
14 changed files with 421 additions and 77 deletions

View file

@ -13,6 +13,8 @@ internal sealed class YieldSupplyFeeUM {
data class Content(
val transactionDataList: ImmutableList<TransactionData.Uncompiled>,
val feeValue: TextReference,
val currentNetworkFeeValue: TextReference,
val maxNetworkFeeValue: TextReference,
) : YieldSupplyFeeUM()
}
@ -20,6 +22,7 @@ internal data class YieldSupplyActionUM(
val title: TextReference,
val subtitle: TextReference,
val footer: TextReference,
val footerLink: TextReference,
val currencyIconState: CurrencyIconState,
val yieldSupplyFeeUM: YieldSupplyFeeUM,
val isPrimaryButtonEnabled: Boolean,

View file

@ -3,18 +3,19 @@ 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.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
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.*
import com.tangem.core.ui.components.SpacerH24
import com.tangem.core.ui.components.SpacerH8
import com.tangem.core.ui.components.containers.FooterContainer
import com.tangem.core.ui.components.currency.icon.CurrencyIcon
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
@ -30,6 +31,7 @@ import kotlinx.collections.immutable.persistentListOf
@Composable
internal fun YieldSupplyActionContent(
yieldSupplyActionUM: YieldSupplyActionUM,
onFooterClick: () -> Unit,
modifier: Modifier = Modifier,
iconContent: @Composable ColumnScope.() -> Unit,
) {
@ -54,47 +56,31 @@ internal fun YieldSupplyActionContent(
)
SpacerH24()
FooterContainer(
footer = yieldSupplyActionUM.footer,
footer = annotatedReference {
append(yieldSupplyActionUM.footer.resolveReference())
appendSpace()
withLink(link = LinkAnnotation.Clickable("LINK_TAG") { onFooterClick() }) {
appendColored(
text = yieldSupplyActionUM.footerLink.resolveReference(),
color = TangemTheme.colors.icon.accent,
)
}
},
paddingValues = PaddingValues(
start = 12.dp,
end = 12.dp,
top = 8.dp,
),
) {
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),
) {
Text(
text = stringResourceSafe(R.string.common_network_fee_title),
style = TangemTheme.typography.body1,
color = TangemTheme.colors.text.primary1,
)
SpacerWMax()
when (val fee = yieldSupplyActionUM.yieldSupplyFeeUM) {
is YieldSupplyFeeUM.Content -> Text(
text = fee.feeValue.resolveReference(),
style = TangemTheme.typography.body1,
color = TangemTheme.colors.text.tertiary,
)
YieldSupplyFeeUM.Error -> Text(
text = stringResourceSafe(R.string.common_fee_error),
style = TangemTheme.typography.body1,
color = TangemTheme.colors.text.attention,
)
YieldSupplyFeeUM.Loading -> {
TextShimmer(
style = TangemTheme.typography.body1,
text = stringResourceSafe(R.string.common_fee_error),
)
}
}
val fee = when (val yieldSupplyFeeUM = yieldSupplyActionUM.yieldSupplyFeeUM) {
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.feeValue
YieldSupplyFeeUM.Error -> stringReference(StringsSigns.DASH_SIGN)
YieldSupplyFeeUM.Loading -> null
}
YieldSupplyFeeRow(
title = resourceReference(R.string.common_network_fee_title),
value = fee,
)
}
}
}
@ -109,6 +95,7 @@ private fun YieldSupplyActionContent_Preview(
TangemThemePreview {
YieldSupplyActionContent(
yieldSupplyActionUM = params,
onFooterClick = {},
modifier = Modifier.background(TangemTheme.colors.background.tertiary),
) {
CurrencyIcon(
@ -130,15 +117,14 @@ private class YieldSupplyActionContentPreviewProvider : PreviewParameterProvider
R.string.yield_module_start_earning_sheet_description,
wrappedList("USDT"),
),
footer = combinedReference(
resourceReference(R.string.yield_module_start_earning_sheet_next_deposits),
stringReference(StringsSigns.WHITE_SPACE),
resourceReference(R.string.yield_module_start_earning_sheet_fee_policy),
),
footer = resourceReference(R.string.yield_module_start_earning_sheet_next_deposits),
footerLink = resourceReference(R.string.yield_module_start_earning_sheet_fee_policy),
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"),
),
isPrimaryButtonEnabled = false,
),

View file

@ -0,0 +1,58 @@
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.unit.dp
import com.tangem.core.ui.components.SpacerWMax
import com.tangem.core.ui.components.TextShimmer
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.yield.supply.impl.R
@Composable
internal fun YieldSupplyFeeRow(title: TextReference, value: TextReference?) {
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),
) {
Text(
text = title.resolveReference(),
style = TangemTheme.typography.body1,
color = TangemTheme.colors.text.primary1,
)
SpacerWMax()
AnimatedContent(
targetState = value,
) { targetValue ->
if (targetValue != null) {
Text(
text = targetValue.resolveReference(),
style = TangemTheme.typography.body1,
color = TangemTheme.colors.text.tertiary,
)
} else {
TextShimmer(
style = TangemTheme.typography.body1,
text = stringResourceSafe(R.string.common_fee_error),
)
}
}
}
}

View file

@ -7,4 +7,5 @@ internal data class YieldSupplyActiveContentUM(
val availableBalance: TextReference,
val providerTitle: TextReference,
val subtitle: TextReference,
val subtitleLink: TextReference,
)

View file

@ -3,7 +3,6 @@ package com.tangem.features.yield.supply.impl.subcomponents.active.model
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
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
@ -38,13 +37,11 @@ internal class YieldSupplyActiveModel @Inject constructor(
},
),
providerTitle = resourceReference(R.string.yield_module_provider),
subtitle = combinedReference(
resourceReference(
id = R.string.yield_module_earn_sheet_provider_description,
formatArgs = wrappedList(cryptoCurrency.symbol, cryptoCurrency.symbol),
),
resourceReference(R.string.common_read_more),
subtitle = resourceReference(
id = R.string.yield_module_earn_sheet_provider_description,
formatArgs = wrappedList(cryptoCurrency.symbol, cryptoCurrency.symbol),
),
subtitleLink = resourceReference(R.string.common_read_more),
),
)
}

View file

@ -13,6 +13,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.LinkAnnotation
import androidx.compose.ui.text.withLink
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
@ -90,11 +92,7 @@ private fun YieldSupplyActiveMyFunds(state: YieldSupplyActiveContentUM) {
)
}
SpacerH8()
Text(
text = state.subtitle.resolveReference(),
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
)
DescriptionText(state = state)
SpacerH8()
HorizontalDivider(
thickness = 0.5.dp,
@ -115,6 +113,31 @@ private fun YieldSupplyActiveMyFunds(state: YieldSupplyActiveContentUM) {
}
}
@Composable
private fun DescriptionText(state: YieldSupplyActiveContentUM) {
val subtitle = annotatedReference {
append(state.subtitle.resolveReference())
appendSpace()
withLink(
LinkAnnotation.Clickable(
tag = "LINK_TAG",
linkInteractionListener = {},
),
{
appendColored(
text = state.subtitleLink.resolveReference(),
color = TangemTheme.colors.icon.accent,
)
},
)
}
Text(
text = subtitle.resolveAnnotatedReference(),
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
)
}
@Composable
private fun InfoRow(title: TextReference, info: TextReference) {
Row(
@ -158,6 +181,7 @@ private class YieldSupplyActiveBottomSheetPreviewProvider : PreviewParameterProv
R.string.yield_module_earn_sheet_provider_description,
wrappedList("USDT", "USDT"),
),
subtitleLink = resourceReference(R.string.common_read_more),
),
)
}

View file

@ -0,0 +1,67 @@
package com.tangem.features.yield.supply.impl.subcomponents.feepolicy
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.ui.components.SecondaryButton
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
import com.tangem.core.ui.decompose.ComposableModularContentComponent
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWalletId
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.subcomponents.feepolicy.ui.YieldSupplyFeePolicyContent
import kotlinx.coroutines.flow.StateFlow
internal class YieldSupplyFeePolicyComponent(
private val appComponentContext: AppComponentContext,
private val params: Params,
) : ComposableModularContentComponent, AppComponentContext by appComponentContext {
@Composable
override fun Title() {
TangemModalBottomSheetTitle(
startIconRes = R.drawable.ic_back_24,
onStartClick = params.callback::onBackClick,
)
}
@Composable
override fun Content(modifier: Modifier) {
val uiState by params.yieldSupplyActionUMFlow.collectAsStateWithLifecycle()
YieldSupplyFeePolicyContent(
yieldSupplyFeeUM = uiState.yieldSupplyFeeUM,
tokenSymbol = params.cryptoCurrency.symbol,
networkName = params.cryptoCurrency.network.name,
modifier = modifier,
)
}
@Composable
override fun Footer() {
SecondaryButton(
text = stringResourceSafe(R.string.common_got_it),
onClick = params.callback::onBackClick,
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
)
}
data class Params(
val userWalletId: UserWalletId,
val cryptoCurrency: CryptoCurrency,
val yieldSupplyActionUMFlow: StateFlow<YieldSupplyActionUM>,
val callback: ModelCallback,
)
interface ModelCallback {
fun onBackClick()
}
}

View file

@ -0,0 +1,127 @@
package com.tangem.features.yield.supply.impl.subcomponents.feepolicy.ui
import android.content.res.Configuration
import androidx.compose.foundation.background
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.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.SpacerH16
import com.tangem.core.ui.components.SpacerH24
import com.tangem.core.ui.components.SpacerH8
import com.tangem.core.ui.components.containers.FooterContainer
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.yield.supply.impl.R
import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyFeeUM
import com.tangem.features.yield.supply.impl.common.ui.YieldSupplyFeeRow
import com.tangem.utils.StringsSigns
import kotlinx.collections.immutable.persistentListOf
@Composable
internal fun YieldSupplyFeePolicyContent(
yieldSupplyFeeUM: YieldSupplyFeeUM,
tokenSymbol: String,
networkName: String,
modifier: Modifier = Modifier,
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier
.fillMaxWidth()
.padding(
start = 16.dp,
end = 16.dp,
top = 16.dp,
bottom = 8.dp,
),
) {
Text(
text = stringResourceSafe(R.string.yield_module_fee_policy_sheet_title),
style = TangemTheme.typography.h3,
color = TangemTheme.colors.text.primary1,
)
SpacerH8()
Text(
text = stringResourceSafe(R.string.yield_module_fee_policy_sheet_description, tokenSymbol),
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.secondary,
textAlign = TextAlign.Center,
modifier = Modifier.padding(horizontal = 16.dp),
)
SpacerH24()
FooterContainer(
footer = resourceReference(
id = R.string.yield_module_fee_policy_sheet_current_fee_note,
formatArgs = wrappedList(networkName),
),
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
}
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,
)
}
}
}
// region Preview
@Composable
@Preview(showBackground = true, widthDp = 360)
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun YieldSupplyFeePolicyContent_Preview() {
TangemThemePreview {
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"),
),
tokenSymbol = "USDT",
networkName = "Ethereum",
modifier = Modifier.background(TangemTheme.colors.background.primary),
)
}
}
// endregion

View file

@ -24,8 +24,11 @@ import com.tangem.core.ui.res.TangemTheme
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWalletId
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.ui.YieldSupplyActionContent
import com.tangem.features.yield.supply.impl.subcomponents.startearning.model.YieldSupplyStartEarningModel
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
internal class YieldSupplyStartEarningComponent(
private val appComponentContext: AppComponentContext,
@ -34,6 +37,10 @@ internal class YieldSupplyStartEarningComponent(
private val model: YieldSupplyStartEarningModel = getOrCreateModel(params = params)
init {
model.uiState.onEach(params.callback::onResult).launchIn(componentScope)
}
@Composable
override fun Title() {
TangemModalBottomSheetTitle(
@ -49,6 +56,7 @@ internal class YieldSupplyStartEarningComponent(
YieldSupplyActionContent(
yieldSupplyActionUM = state,
onFooterClick = params.callback::onFeePolicyClick,
modifier = modifier,
) {
Box(
@ -96,10 +104,12 @@ internal class YieldSupplyStartEarningComponent(
data class Params(
val userWalletId: UserWalletId,
val cryptoCurrency: CryptoCurrency,
val yieldSupplyActionUM: YieldSupplyActionUM,
val callback: ModelCallback,
)
interface ModelCallback {
fun onResult(yieldSupplyActionUM: YieldSupplyActionUM)
fun onBackClick()
fun onFeePolicyClick()
fun onTransactionSent()

View file

@ -12,9 +12,9 @@ import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.decompose.navigation.inner.InnerRouter
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.core.ui.decompose.ComposableModularContentComponent
import com.tangem.core.ui.decompose.getEmptyComposableModularContentComponent
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.features.yield.supply.impl.subcomponents.feepolicy.YieldSupplyFeePolicyComponent
import com.tangem.features.yield.supply.impl.subcomponents.startearning.model.YieldSupplyStartEarningEntryModel
import com.tangem.features.yield.supply.impl.subcomponents.startearning.ui.YieldSupplyStartEarningBottomSheet
@ -67,12 +67,21 @@ internal class YieldSupplyStartEarningEntryComponent(
route: YieldSupplyStartEarningRoute,
factoryContext: AppComponentContext,
): ComposableModularContentComponent = when (route) {
YieldSupplyStartEarningRoute.FeePolicy -> getEmptyComposableModularContentComponent() // todo fee policy
YieldSupplyStartEarningRoute.FeePolicy -> YieldSupplyFeePolicyComponent(
appComponentContext = factoryContext,
params = YieldSupplyFeePolicyComponent.Params(
userWalletId = params.userWalletId,
cryptoCurrency = params.cryptoCurrency,
yieldSupplyActionUMFlow = model.uiState,
callback = model,
),
)
YieldSupplyStartEarningRoute.Action -> YieldSupplyStartEarningComponent(
appComponentContext = factoryContext,
params = YieldSupplyStartEarningComponent.Params(
userWalletId = params.userWalletId,
cryptoCurrency = params.cryptoCurrency,
yieldSupplyActionUM = model.uiState.value,
callback = model,
),
)

View file

@ -4,10 +4,20 @@ import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
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.subcomponents.feepolicy.YieldSupplyFeePolicyComponent
import com.tangem.features.yield.supply.impl.subcomponents.startearning.YieldSupplyStartEarningComponent
import com.tangem.features.yield.supply.impl.subcomponents.startearning.YieldSupplyStartEarningEntryComponent
import com.tangem.features.yield.supply.impl.subcomponents.startearning.YieldSupplyStartEarningRoute
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import javax.inject.Inject
@ModelScoped
@ -15,10 +25,30 @@ internal class YieldSupplyStartEarningEntryModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
private val router: Router,
paramsContainer: ParamsContainer,
) : Model(), YieldSupplyStartEarningComponent.ModelCallback {
) : Model(), YieldSupplyStartEarningComponent.ModelCallback, YieldSupplyFeePolicyComponent.ModelCallback {
private val params = paramsContainer.require<YieldSupplyStartEarningEntryComponent.Params>()
val uiState: StateFlow<YieldSupplyActionUM>
field: MutableStateFlow<YieldSupplyActionUM> = MutableStateFlow(
YieldSupplyActionUM(
title = resourceReference(R.string.yield_module_start_earning),
subtitle = resourceReference(
R.string.yield_module_start_earning_sheet_description,
wrappedList(params.cryptoCurrency.symbol),
),
footer = resourceReference(R.string.yield_module_start_earning_sheet_next_deposits),
footerLink = resourceReference(R.string.yield_module_start_earning_sheet_fee_policy),
currencyIconState = CryptoCurrencyToIconStateConverter().convert(params.cryptoCurrency),
yieldSupplyFeeUM = YieldSupplyFeeUM.Loading,
isPrimaryButtonEnabled = false,
),
)
override fun onResult(yieldSupplyActionUM: YieldSupplyActionUM) {
uiState.update { yieldSupplyActionUM }
}
override fun onBackClick() {
router.pop()
}

View file

@ -34,6 +34,7 @@ import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import timber.log.Timber
import java.math.BigDecimal
import java.math.RoundingMode
import javax.inject.Inject
import kotlin.properties.Delegates
@ -79,10 +80,8 @@ internal class YieldSupplyStartEarningModel @Inject constructor(
R.string.yield_module_start_earning_sheet_description,
wrappedList(cryptoCurrency.symbol),
),
footer = combinedReference(
resourceReference(R.string.yield_module_start_earning_sheet_next_deposits),
resourceReference(R.string.yield_module_start_earning_sheet_fee_policy),
),
footer = resourceReference(R.string.yield_module_start_earning_sheet_next_deposits),
footerLink = resourceReference(R.string.yield_module_start_earning_sheet_fee_policy),
currencyIconState = CryptoCurrencyToIconStateConverter().convert(params.cryptoCurrency),
yieldSupplyFeeUM = YieldSupplyFeeUM.Loading,
isPrimaryButtonEnabled = false,
@ -120,12 +119,23 @@ internal class YieldSupplyStartEarningModel @Inject constructor(
}
val crypto = feeSum.format { crypto(feeCryptoCurrencyStatusFlow.value.currency) }
val fiatFeeValue = cryptoCurrencyStatus.value.fiatRate?.let { rate ->
val fiatFeeValue = feeCryptoCurrencyStatusFlow.value.value.fiatRate?.let { rate ->
feeSum.multiply(rate)
}
val fiat = fiatFeeValue.format { fiat(appCurrency.code, appCurrency.symbol) }
val tokenCryptoFeeValue = cryptoCurrencyStatus.value.fiatRate?.let { rate ->
fiatFeeValue?.divide(rate, cryptoCurrency.decimals, RoundingMode.HALF_UP)
}
val tokenCryptoFee = tokenCryptoFeeValue.format { crypto(cryptoCurrency) }
val maxCryptoFee = MAX_NETWORK_FEE.format { crypto(cryptoCurrency) }
val maxFiatFeeValue = cryptoCurrencyStatus.value.fiatRate?.let { rate ->
MAX_NETWORK_FEE.divide(rate, cryptoCurrency.decimals, RoundingMode.HALF_UP)
}
val maxFiatFee = maxFiatFeeValue.format { fiat(appCurrency.code, appCurrency.symbol) }
uiState.update {
if (cryptoCurrencyStatus.value is CryptoCurrencyStatus.Loading) {
it.copy(yieldSupplyFeeUM = YieldSupplyFeeUM.Loading)
@ -139,6 +149,16 @@ internal class YieldSupplyStartEarningModel @Inject constructor(
stringReference(" $DOT "),
stringReference(fiat),
),
currentNetworkFeeValue = combinedReference(
stringReference(tokenCryptoFee),
stringReference(" $DOT "),
stringReference(fiat),
),
maxNetworkFeeValue = combinedReference(
stringReference(maxCryptoFee),
stringReference(" $DOT "),
stringReference(maxFiatFee),
),
),
)
}

View file

@ -49,6 +49,7 @@ internal class YieldSupplyStopEarningComponent(
val state by model.uiState.collectAsStateWithLifecycle()
YieldSupplyActionContent(
yieldSupplyActionUM = state,
onFooterClick = model::onReadMoreClick,
modifier = modifier,
) {
Box(

View file

@ -4,11 +4,9 @@ import arrow.core.getOrElse
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
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.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.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
@ -43,6 +41,7 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
private val getFeePaidCryptoCurrencyStatusSyncUseCase: GetFeePaidCryptoCurrencyStatusSyncUseCase,
private val sendTransactionUseCase: SendTransactionUseCase,
private val yieldSupplyStopEarningUseCase: YieldSupplyStopEarningUseCase,
private val urlOpener: UrlOpener,
) : Model() {
private val params: YieldSupplyStopEarningComponent.Params = paramsContainer.require()
@ -60,6 +59,9 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
),
)
private val feeCryptoCurrencyStatus: CryptoCurrencyStatus
get() = feeCryptoCurrencyStatusFlow.value
private var appCurrency = AppCurrency.Default
val uiState: StateFlow<YieldSupplyActionUM>
@ -70,10 +72,8 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
id = R.string.yield_module_stop_earning_sheet_description,
formatArgs = wrappedList(cryptoCurrency.symbol),
),
footer = combinedReference(
resourceReference(R.string.yield_module_stop_earning_sheet_fee_note),
resourceReference(R.string.common_read_more),
),
footer = resourceReference(R.string.yield_module_stop_earning_sheet_fee_note),
footerLink = resourceReference(R.string.common_read_more),
currencyIconState = CryptoCurrencyToIconStateConverter().convert(cryptoCurrency),
yieldSupplyFeeUM = YieldSupplyFeeUM.Loading,
isPrimaryButtonEnabled = false,
@ -87,6 +87,10 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
}
}
fun onReadMoreClick() {
urlOpener.openUrl(READ_MORE_URL)
}
fun onClick() {
val yieldSupplyFeeUM = uiState.value.yieldSupplyFeeUM as? YieldSupplyFeeUM.Content ?: return
uiState.update { it.copy(isPrimaryButtonEnabled = false) }
@ -132,12 +136,13 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
network = cryptoCurrency.network,
).getOrNull() ?: return
val crypto = fee.normal.amount.value.format { crypto(feeCryptoCurrencyStatusFlow.value.currency) }
val fiatFeeValue = cryptoCurrencyStatus.value.fiatRate?.let { rate ->
fee.normal.amount.value?.multiply(rate)
}
val feeCryptoValue = fee.normal.amount.value
val fiat = fiatFeeValue.format { fiat(appCurrency.code, appCurrency.symbol) }
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 {
if (cryptoCurrencyStatus.value is CryptoCurrencyStatus.Loading) {
@ -148,13 +153,19 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
yieldSupplyFeeUM = YieldSupplyFeeUM.Content(
transactionDataList = persistentListOf(exitTransitionData.copy(fee = fee.normal)),
feeValue = combinedReference(
stringReference(crypto),
stringReference(cryptoFee),
stringReference(" $DOT "),
stringReference(fiat),
stringReference(fiatFee),
),
currentNetworkFeeValue = TextReference.EMPTY,
maxNetworkFeeValue = TextReference.EMPTY,
),
)
}
}
}
private companion object {
const val READ_MORE_URL = "https://tangem.com" // todo yield supply replace with real link
}
}