Updated on 2026-08-14

This commit is contained in:
Tangem 2025-10-01 16:55:53 +05:00
parent 59a6a4cb69
commit 8d6992ad24
14 changed files with 251 additions and 82 deletions

View file

@ -13,6 +13,8 @@ internal sealed class YieldSupplyUM {
data object Loading : YieldSupplyUM()
data object Unavailable : YieldSupplyUM()
data class Content(
val rewardsBalance: TextReference,
val rewardsApy: TextReference,

View file

@ -11,12 +11,14 @@ import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.network.TxInfo
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.tokens.FetchCurrencyStatusUseCase
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetTokenStatusUseCase
import com.tangem.features.yield.supply.api.YieldSupplyComponent
import com.tangem.features.yield.supply.impl.R
import com.tangem.features.yield.supply.impl.main.entity.YieldSupplyUM
@ -41,6 +43,7 @@ internal class YieldSupplyModel @Inject constructor(
private val fetchCurrencyStatusUseCase: FetchCurrencyStatusUseCase,
@DelayedWork private val coroutineScope: CoroutineScope,
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
private val yieldSupplyGetTokenStatusUseCase: YieldSupplyGetTokenStatusUseCase,
) : Model(), YieldSupplyClickIntents {
private val params = paramsContainer.require<YieldSupplyComponent.Params>()
@ -99,6 +102,28 @@ internal class YieldSupplyModel @Inject constructor(
}
}
private fun loadTokenStatus(cryptoCurrency: CryptoCurrency.Token) {
modelScope.launch(dispatchers.default) {
yieldSupplyGetTokenStatusUseCase(cryptoCurrency)
.onRight { tokenStatus ->
val newState = if (tokenStatus.isActive) {
YieldSupplyUM.Initial(
title = resourceReference(
id = R.string.yield_module_token_details_earn_notification_title,
formatArgs = wrappedList("5.1"),
),
onClick = ::onStartEarningClick,
)
} else {
YieldSupplyUM.Unavailable
}
uiState.update { newState }
}.onLeft {
uiState.update { YieldSupplyUM.Unavailable }
}
}
}
override fun onStartEarningClick() {
appRouter.push(
YieldSupplyPromo(
@ -148,16 +173,12 @@ internal class YieldSupplyModel @Inject constructor(
onClick = ::onActiveClick,
isAllowedToSpend = yieldSupplyStatus.isAllowedToSpend,
)
else -> YieldSupplyUM.Initial(
title = resourceReference(
id = R.string.yield_module_token_details_earn_notification_title,
formatArgs = wrappedList("5.1"),
),
onClick = ::onStartEarningClick,
)
else -> YieldSupplyUM.Loading
}
uiState.update { yieldSupplyUM }
(cryptoCurrency as? CryptoCurrency.Token)?.let(::loadTokenStatus)
}
private companion object {

View file

@ -15,6 +15,7 @@ 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.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.Preview
@ -52,55 +53,36 @@ internal fun YieldSupplyBlockContent(
YieldSupplyUM.Processing.Exit -> SupplyProcessing(
resourceReference(R.string.yield_module_stop_earning),
)
YieldSupplyUM.Unavailable -> SupplyUnavailable()
}
}
}
@Composable
private fun SupplyInitial(supplyUM: YieldSupplyUM.Initial) {
Column(
verticalArrangement = Arrangement.spacedBy(12.dp),
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.clip(RoundedCornerShape(16.dp))
.background(TangemTheme.colors.background.primary)
.padding(12.dp),
) {
Row(
horizontalArrangement = Arrangement.spacedBy(10.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
imageVector = ImageVector.vectorResource(R.drawable.ic_analytics_up_24),
contentDescription = null,
tint = TangemTheme.colors.icon.accent,
modifier = Modifier
.background(TangemTheme.colors.icon.accent.copy(alpha = 0.1f), CircleShape)
.padding(6.dp)
.size(24.dp),
SupplyInfo(
title = supplyUM.title,
subtitle = resourceReference(R.string.yield_module_token_details_earn_notification_description),
iconTint = TangemTheme.colors.icon.accent,
button = {
SecondaryButton(
text = stringResourceSafe(R.string.common_learn_more),
onClick = supplyUM.onClick,
size = TangemButtonSize.WideAction,
modifier = Modifier.fillMaxWidth(),
)
Column(
verticalArrangement = Arrangement.spacedBy(2.dp),
) {
Text(
text = supplyUM.title.resolveReference(),
style = TangemTheme.typography.button,
color = TangemTheme.colors.text.primary1,
)
Text(
text = stringResourceSafe(R.string.yield_module_token_details_earn_notification_description),
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
)
}
}
SecondaryButton(
text = stringResourceSafe(R.string.common_learn_more),
onClick = supplyUM.onClick,
size = TangemButtonSize.WideAction,
modifier = Modifier.fillMaxWidth(),
)
}
},
)
}
@Composable
private fun SupplyUnavailable() {
SupplyInfo(
title = resourceReference(R.string.yield_module_unavailable_title),
subtitle = resourceReference(R.string.yield_module_unavailable_subtitle),
iconTint = TangemTheme.colors.icon.inactive,
button = null,
)
}
@Composable
@ -199,29 +181,104 @@ private fun SupplyProcessing(text: TextReference) {
@Composable
private fun SupplyLoading() {
Column(
verticalArrangement = Arrangement.spacedBy(4.dp),
verticalArrangement = Arrangement.spacedBy(12.dp),
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(16.dp))
.background(TangemTheme.colors.background.primary)
.padding(12.dp),
) {
Text(
text = stringResourceSafe(
R.string.yield_module_token_details_earn_notification_earning_on_your_balance_title,
),
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.tertiary,
)
TextShimmer(
style = TangemTheme.typography.subtitle2,
text = stringResourceSafe(
R.string.yield_module_token_details_earn_notification_earning_on_your_balance_title,
),
Row(
horizontalArrangement = Arrangement.spacedBy(10.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
imageVector = ImageVector.vectorResource(R.drawable.ic_analytics_up_24),
contentDescription = null,
tint = TangemTheme.colors.icon.inactive,
modifier = Modifier
.background(TangemTheme.colors.icon.inactive.copy(alpha = 0.1f), CircleShape)
.padding(6.dp)
.size(24.dp),
)
Column(
verticalArrangement = Arrangement.spacedBy(2.dp),
) {
TextShimmer(
text = stringResourceSafe(R.string.yield_module_unavailable_title),
style = TangemTheme.typography.button,
)
TextShimmer(
modifier = Modifier.fillMaxWidth(),
text = stringResourceSafe(R.string.yield_module_unavailable_subtitle),
style = TangemTheme.typography.caption2,
)
TextShimmer(
modifier = Modifier.width(100.dp),
text = stringResourceSafe(R.string.yield_module_unavailable_subtitle),
style = TangemTheme.typography.caption2,
)
}
}
SecondaryButton(
text = stringResourceSafe(R.string.common_learn_more),
onClick = { },
showProgress = true,
enabled = false,
size = TangemButtonSize.WideAction,
modifier = Modifier.fillMaxWidth(),
)
}
}
@Composable
private fun SupplyInfo(
title: TextReference,
subtitle: TextReference,
iconTint: Color,
modifier: Modifier = Modifier,
button: (@Composable () -> Unit)? = null,
) {
Column(
verticalArrangement = Arrangement.spacedBy(12.dp),
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier
.clip(RoundedCornerShape(16.dp))
.background(TangemTheme.colors.background.primary)
.padding(12.dp),
) {
Row(
horizontalArrangement = Arrangement.spacedBy(10.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
imageVector = ImageVector.vectorResource(R.drawable.ic_analytics_up_24),
contentDescription = null,
tint = iconTint,
modifier = Modifier
.background(iconTint.copy(alpha = 0.1f), CircleShape)
.padding(6.dp)
.size(24.dp),
)
Column(
verticalArrangement = Arrangement.spacedBy(2.dp),
) {
Text(
text = title.resolveReference(),
style = TangemTheme.typography.button,
color = TangemTheme.colors.text.primary1,
)
Text(
text = subtitle.resolveReference(),
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
)
}
}
button?.invoke()
}
}
// region Preview
@Composable
@Preview(showBackground = true, widthDp = 360)
@ -257,6 +314,7 @@ private class PreviewProvider : PreviewParameterProvider<YieldSupplyUM> {
YieldSupplyUM.Loading,
YieldSupplyUM.Processing.Enter,
YieldSupplyUM.Processing.Exit,
YieldSupplyUM.Unavailable,
)
}
// endregion