Updated on 2026-08-14
This commit is contained in:
commit
1456166220
14 changed files with 421 additions and 77 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,4 +7,5 @@ internal data class YieldSupplyActiveContentUM(
|
|||
val availableBalance: TextReference,
|
||||
val providerTitle: TextReference,
|
||||
val subtitle: TextReference,
|
||||
val subtitleLink: TextReference,
|
||||
)
|
||||
|
|
@ -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),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -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),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ internal class YieldSupplyStopEarningComponent(
|
|||
val state by model.uiState.collectAsStateWithLifecycle()
|
||||
YieldSupplyActionContent(
|
||||
yieldSupplyActionUM = state,
|
||||
onFooterClick = model::onReadMoreClick,
|
||||
modifier = modifier,
|
||||
) {
|
||||
Box(
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue