Updated on 2026-08-14
This commit is contained in:
parent
f9369de36a
commit
448a472832
7 changed files with 164 additions and 40 deletions
|
|
@ -189,4 +189,14 @@ internal object YieldSupplyDomainModule {
|
|||
dispatcherProvider = dispatcherProvider,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideYieldSupplyEnterStatusUseCase(
|
||||
yieldSupplyRepository: YieldSupplyRepository,
|
||||
): YieldSupplyEnterStatusUseCase {
|
||||
return YieldSupplyEnterStatusUseCase(
|
||||
yieldSupplyRepository = yieldSupplyRepository,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -48,11 +48,14 @@ class TokenItemStateConverter(
|
|||
private val iconStateProvider: (CryptoCurrencyStatus) -> CurrencyIconState = {
|
||||
CryptoCurrencyToIconStateConverter().convert(it)
|
||||
},
|
||||
private val onApyLabelClick: ((CryptoCurrencyStatus) -> Unit)? = null,
|
||||
private val titleStateProvider: (CryptoCurrencyStatus) -> TokenItemState.TitleState = {
|
||||
createTitleState(it, yieldModuleApyMap, stakingApyMap, {
|
||||
onApyLabelClick?.invoke(it)
|
||||
})
|
||||
private val onApyLabelClick: ((CryptoCurrencyStatus, String) -> Unit)? = null,
|
||||
private val titleStateProvider: (CryptoCurrencyStatus) -> TokenItemState.TitleState = { currencyStatus ->
|
||||
createTitleState(
|
||||
currencyStatus = currencyStatus,
|
||||
yieldModuleApyMap = yieldModuleApyMap,
|
||||
stakingApyMap = stakingApyMap,
|
||||
onApyLabelClick = onApyLabelClick,
|
||||
)
|
||||
},
|
||||
private val subtitleStateProvider: (CryptoCurrencyStatus) -> TokenItemState.SubtitleState? = {
|
||||
createSubtitleState(it, appCurrency)
|
||||
|
|
@ -105,9 +108,6 @@ class TokenItemStateConverter(
|
|||
onItemLongClick = onItemLongClick?.let { onItemLongClick ->
|
||||
{ onItemLongClick(it, this) }
|
||||
},
|
||||
onApyLabelClick = onApyLabelClick?.let { onApyLabelClick ->
|
||||
{ onApyLabelClick(this) }
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -166,7 +166,7 @@ class TokenItemStateConverter(
|
|||
currencyStatus: CryptoCurrencyStatus,
|
||||
yieldModuleApyMap: Map<String, String>,
|
||||
stakingApyMap: Map<String, List<Yield.Validator>>,
|
||||
onApyLabelClick: () -> Unit,
|
||||
onApyLabelClick: ((CryptoCurrencyStatus, String) -> Unit)?,
|
||||
): TokenItemState.TitleState {
|
||||
return when (val value = currencyStatus.value) {
|
||||
is CryptoCurrencyStatus.Loading,
|
||||
|
|
@ -181,7 +181,7 @@ class TokenItemStateConverter(
|
|||
is CryptoCurrencyStatus.NoQuote,
|
||||
is CryptoCurrencyStatus.NoAccount,
|
||||
-> {
|
||||
val (earnApyText, isActive) = resolveEarnApy(
|
||||
val apyInfo = resolveEarnApy(
|
||||
cryptoCurrencyStatus = currencyStatus,
|
||||
yieldModuleApyMap = yieldModuleApyMap,
|
||||
stakingApyMap = stakingApyMap,
|
||||
|
|
@ -189,9 +189,13 @@ class TokenItemStateConverter(
|
|||
TokenItemState.TitleState.Content(
|
||||
text = stringReference(currencyStatus.currency.name),
|
||||
hasPending = value.hasCurrentNetworkTransactions,
|
||||
earnApy = earnApyText,
|
||||
earnApyIsActive = isActive,
|
||||
onApyLabelClick = onApyLabelClick,
|
||||
earnApy = apyInfo?.text,
|
||||
earnApyIsActive = apyInfo?.isActive == true,
|
||||
onApyLabelClick = if (apyInfo?.apy != null && onApyLabelClick != null) {
|
||||
{ onApyLabelClick.invoke(currencyStatus, apyInfo.apy) }
|
||||
} else {
|
||||
null
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -202,7 +206,7 @@ class TokenItemStateConverter(
|
|||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
yieldModuleApyMap: Map<String, String>,
|
||||
stakingApyMap: Map<String, List<Yield.Validator>>,
|
||||
): Pair<TextReference?, Boolean> {
|
||||
): EarnApyInfo? {
|
||||
val token = cryptoCurrencyStatus.currency as? CryptoCurrency.Token
|
||||
if (token != null && yieldModuleApyMap.isNotEmpty()) {
|
||||
val yieldSupplyApy = yieldModuleApyMap.entries.firstOrNull {
|
||||
|
|
@ -213,10 +217,14 @@ class TokenItemStateConverter(
|
|||
}?.value
|
||||
if (yieldSupplyApy != null) {
|
||||
val isActive = cryptoCurrencyStatus.value.yieldSupplyStatus?.isActive ?: false
|
||||
return resourceReference(
|
||||
R.string.yield_module_earn_badge,
|
||||
wrappedList(yieldSupplyApy),
|
||||
) to isActive
|
||||
return EarnApyInfo(
|
||||
text = resourceReference(
|
||||
R.string.yield_module_earn_badge,
|
||||
wrappedList(yieldSupplyApy),
|
||||
),
|
||||
isActive = isActive,
|
||||
apy = yieldSupplyApy,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -233,14 +241,19 @@ class TokenItemStateConverter(
|
|||
-> R.string.yield_module_earn_badge
|
||||
}
|
||||
if (stakingInfo.rate != null) {
|
||||
return resourceReference(
|
||||
rewardTypeRes,
|
||||
wrappedList(stakingInfo.rate.format { percent(withPercentSign = false) }),
|
||||
) to stakingInfo.isActive
|
||||
val apyString = stakingInfo.rate.format { percent(withPercentSign = false) }
|
||||
return EarnApyInfo(
|
||||
text = resourceReference(
|
||||
rewardTypeRes,
|
||||
wrappedList(apyString),
|
||||
),
|
||||
isActive = stakingInfo.isActive,
|
||||
apy = apyString,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return null to false
|
||||
return null
|
||||
}
|
||||
|
||||
private fun findStakingRate(
|
||||
|
|
@ -412,4 +425,10 @@ class TokenItemStateConverter(
|
|||
val isActive: Boolean,
|
||||
val rewardType: Yield.RewardType?,
|
||||
)
|
||||
|
||||
private data class EarnApyInfo(
|
||||
val text: TextReference?,
|
||||
val isActive: Boolean,
|
||||
val apy: String?,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.tangem.domain.yield.supply.usecase
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.yield.supply.YieldSupplyRepository
|
||||
import com.tangem.domain.yield.supply.models.YieldSupplyEnterStatus
|
||||
|
||||
class YieldSupplyEnterStatusUseCase(
|
||||
private val yieldSupplyRepository: YieldSupplyRepository,
|
||||
) {
|
||||
|
||||
operator fun invoke(
|
||||
userWalletId: UserWalletId,
|
||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
): Either<Throwable, YieldSupplyEnterStatus?> {
|
||||
return Either.catch {
|
||||
yieldSupplyRepository.getTokenProtocolStatus(
|
||||
userWalletId,
|
||||
cryptoCurrencyStatus.currency,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ import com.tangem.domain.tokens.model.TokenActionsState
|
|||
import com.tangem.domain.tokens.model.details.NavigationAction
|
||||
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyEnterStatusUseCase
|
||||
import com.tangem.feature.wallet.presentation.account.AccountDependencies
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.OnrampStatusFactory
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.unwrap
|
||||
|
|
@ -49,7 +50,7 @@ internal interface WalletContentClickIntents {
|
|||
|
||||
fun onTokenItemLongClick(userWalletId: UserWalletId, cryptoCurrencyStatus: CryptoCurrencyStatus)
|
||||
|
||||
fun onApyLabelClick(userWalletId: UserWalletId, currencyStatus: CryptoCurrencyStatus)
|
||||
fun onApyLabelClick(userWalletId: UserWalletId, currencyStatus: CryptoCurrencyStatus, apy: String)
|
||||
|
||||
fun onAccountExpandClick(account: Account)
|
||||
|
||||
|
|
@ -87,6 +88,7 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
|
|||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val accountDependencies: AccountDependencies,
|
||||
private val yieldSupplyEnterStatusUseCase: YieldSupplyEnterStatusUseCase,
|
||||
) : BaseWalletClickIntents(), WalletContentClickIntents {
|
||||
|
||||
override fun onDetailsClick() {
|
||||
|
|
@ -160,12 +162,65 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun onApyLabelClick(userWalletId: UserWalletId, currencyStatus: CryptoCurrencyStatus) {
|
||||
override fun onApyLabelClick(userWalletId: UserWalletId, currencyStatus: CryptoCurrencyStatus, apy: String) {
|
||||
val navigationAction = if (currencyStatus.currency is CryptoCurrency.Token) {
|
||||
NavigationAction.YieldSupply(currencyStatus.value.yieldSupplyStatus?.isActive == true)
|
||||
} else {
|
||||
NavigationAction.Staking
|
||||
}
|
||||
|
||||
sendApyLabelClickAnalytics(navigationAction, currencyStatus)
|
||||
|
||||
when (navigationAction) {
|
||||
is NavigationAction.Staking -> router.openTokenDetails(userWalletId, currencyStatus, navigationAction)
|
||||
is NavigationAction.YieldSupply -> openYieldSupply(
|
||||
userWalletId = userWalletId,
|
||||
cryptoCurrencyStatus = currencyStatus,
|
||||
navigationAction = navigationAction,
|
||||
apy = apy,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAccountExpandClick(account: Account) {
|
||||
val userWalletId = stateHolder.getSelectedWalletId()
|
||||
accountDependencies.expandedAccountsHolder.expandAccount(userWalletId, account.accountId)
|
||||
}
|
||||
|
||||
override fun onAccountCollapseClick(account: Account) {
|
||||
val userWalletId = stateHolder.getSelectedWalletId()
|
||||
accountDependencies.expandedAccountsHolder.collapseAccount(userWalletId, account.accountId)
|
||||
}
|
||||
|
||||
private fun openYieldSupply(
|
||||
userWalletId: UserWalletId,
|
||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
navigationAction: NavigationAction.YieldSupply,
|
||||
apy: String,
|
||||
) {
|
||||
modelScope.launch {
|
||||
val tokenEnterStatus = yieldSupplyEnterStatusUseCase(userWalletId, cryptoCurrencyStatus).getOrNull()
|
||||
when {
|
||||
tokenEnterStatus != null -> router.openTokenDetails(
|
||||
userWalletId = userWalletId,
|
||||
currencyStatus = cryptoCurrencyStatus,
|
||||
navigationAction = navigationAction,
|
||||
)
|
||||
navigationAction.isActive -> router.openYieldSupplyActiveScreen(
|
||||
userWalletId = userWalletId,
|
||||
cryptoCurrency = cryptoCurrencyStatus.currency,
|
||||
apy = apy,
|
||||
)
|
||||
else -> router.openYieldSupplyPromoScreen(
|
||||
userWalletId = userWalletId,
|
||||
cryptoCurrency = cryptoCurrencyStatus.currency,
|
||||
apy = apy,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendApyLabelClickAnalytics(navigationAction: NavigationAction, currencyStatus: CryptoCurrencyStatus) {
|
||||
val event = when (navigationAction) {
|
||||
is NavigationAction.YieldSupply -> {
|
||||
MainScreenAnalyticsEvent.ApyClicked(
|
||||
|
|
@ -193,17 +248,6 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
|
|||
}
|
||||
}
|
||||
analyticsEventHandler.send(event)
|
||||
router.openTokenDetails(userWalletId, currencyStatus, navigationAction)
|
||||
}
|
||||
|
||||
override fun onAccountExpandClick(account: Account) {
|
||||
val userWalletId = stateHolder.getSelectedWalletId()
|
||||
accountDependencies.expandedAccountsHolder.expandAccount(userWalletId, account.accountId)
|
||||
}
|
||||
|
||||
override fun onAccountCollapseClick(account: Account) {
|
||||
val userWalletId = stateHolder.getSelectedWalletId()
|
||||
accountDependencies.expandedAccountsHolder.collapseAccount(userWalletId, account.accountId)
|
||||
}
|
||||
|
||||
private fun showActionsBottomSheet(tokenActionsState: TokenActionsState, userWallet: UserWallet) {
|
||||
|
|
|
|||
|
|
@ -132,4 +132,24 @@ internal class DefaultWalletRouter @Inject constructor(
|
|||
),
|
||||
)
|
||||
}
|
||||
|
||||
override fun openYieldSupplyActiveScreen(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency, apy: String) {
|
||||
router.push(
|
||||
AppRoute.YieldSupplyActive(
|
||||
userWalletId = userWalletId,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
apy = apy,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
override fun openYieldSupplyPromoScreen(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency, apy: String) {
|
||||
router.push(
|
||||
AppRoute.YieldSupplyPromo(
|
||||
userWalletId = userWalletId,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
apy = apy,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -73,4 +73,10 @@ internal interface InnerWalletRouter {
|
|||
tokenAction: TokenAction,
|
||||
onWarningAcknowledged: (TokenAction) -> Unit,
|
||||
)
|
||||
|
||||
/** Open yield supply active screen */
|
||||
fun openYieldSupplyActiveScreen(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency, apy: String)
|
||||
|
||||
/** Open yield supply promo screen */
|
||||
fun openYieldSupplyPromoScreen(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency, apy: String)
|
||||
}
|
||||
|
|
@ -49,9 +49,10 @@ internal class TokenListStateConverter(
|
|||
clickIntents.onTokenItemLongClick(selectedWallet.walletId, currencyStatus)
|
||||
}
|
||||
|
||||
private val onApyLabelClick: (currencyStatus: CryptoCurrencyStatus) -> Unit = { currencyStatus ->
|
||||
clickIntents.onApyLabelClick(selectedWallet.walletId, currencyStatus)
|
||||
}
|
||||
private val onApyLabelClick: (currencyStatus: CryptoCurrencyStatus, apy: String) -> Unit =
|
||||
{ currencyStatus, apy ->
|
||||
clickIntents.onApyLabelClick(selectedWallet.walletId, currencyStatus, apy)
|
||||
}
|
||||
|
||||
private fun tokenStatusConverter(accountId: AccountId? = null) = TokenItemStateConverter(
|
||||
appCurrency = appCurrency,
|
||||
|
|
@ -59,7 +60,7 @@ internal class TokenListStateConverter(
|
|||
stakingApyMap = stakingApyMap,
|
||||
onItemClick = { _, status -> onTokenClick(accountId, status) },
|
||||
onItemLongClick = { _, status -> onTokenLongClick(accountId, status) },
|
||||
onApyLabelClick = { status -> onApyLabelClick(status) },
|
||||
onApyLabelClick = { status, apy -> onApyLabelClick(status, apy) },
|
||||
)
|
||||
|
||||
override fun convert(value: WalletTokensListState): WalletTokensListState {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue