Updated on 2026-08-14
This commit is contained in:
parent
1aee51dc3b
commit
8167dab4f0
16 changed files with 223 additions and 101 deletions
|
|
@ -296,7 +296,7 @@ internal class ChildFactory @Inject constructor(
|
|||
context = context,
|
||||
params = StakingComponent.Params(
|
||||
userWalletId = route.userWalletId,
|
||||
cryptoCurrencyId = route.cryptoCurrencyId,
|
||||
cryptoCurrency = route.cryptoCurrency,
|
||||
yieldId = route.yieldId,
|
||||
),
|
||||
componentFactory = stakingComponentFactory,
|
||||
|
|
|
|||
|
|
@ -192,9 +192,9 @@ sealed class AppRoute(val path: String) : Route {
|
|||
@Serializable
|
||||
data class Staking(
|
||||
val userWalletId: UserWalletId,
|
||||
val cryptoCurrencyId: CryptoCurrency.ID,
|
||||
val cryptoCurrency: CryptoCurrency,
|
||||
val yieldId: String,
|
||||
) : AppRoute(path = "/staking/${userWalletId.stringValue}/${cryptoCurrencyId.value}/$yieldId")
|
||||
) : AppRoute(path = "/staking/${userWalletId.stringValue}/${cryptoCurrency.id.value}/$yieldId")
|
||||
|
||||
@Serializable
|
||||
data class PushNotification(
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import com.tangem.core.ui.utils.getGreyScaleColorFilter
|
|||
* @param onImageError composable to show if image loading failed
|
||||
*/
|
||||
@Composable
|
||||
internal fun InputRowAsyncImage(
|
||||
fun InputRowAsyncImage(
|
||||
imageUrl: String,
|
||||
modifier: Modifier = Modifier,
|
||||
isGrayscale: Boolean = false,
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ fun SelectorRowItem(
|
|||
val textStyle = if (isSelected && showSelectedAppearance) {
|
||||
TangemTheme.typography.subtitle2
|
||||
} else {
|
||||
TangemTheme.typography.body2
|
||||
TangemTheme.typography.body1
|
||||
}
|
||||
Box(
|
||||
modifier = modifier
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ internal class TokenActionsHandler @AssistedInject constructor(
|
|||
router.push(
|
||||
AppRoute.Staking(
|
||||
userWalletId = cryptoCurrencyData.userWallet.walletId,
|
||||
cryptoCurrencyId = cryptoCurrencyData.status.currency.id,
|
||||
cryptoCurrency = cryptoCurrencyData.status.currency,
|
||||
yieldId = yield.id,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ interface StakingComponent : ComposableContentComponent {
|
|||
|
||||
data class Params(
|
||||
val userWalletId: UserWalletId,
|
||||
val cryptoCurrencyId: CryptoCurrency.ID,
|
||||
val cryptoCurrency: CryptoCurrency,
|
||||
val yieldId: String,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@ dependencies {
|
|||
implementation(projects.domain.feedback)
|
||||
implementation(projects.domain.feedback.models)
|
||||
implementation(projects.domain.notifications.models)
|
||||
implementation(projects.domain.account)
|
||||
implementation(projects.domain.account.status)
|
||||
|
||||
/** Common */
|
||||
implementation(projects.common.ui)
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ internal class DefaultStakingDeepLinkHandler @AssistedInject constructor(
|
|||
appRouter.push(
|
||||
AppRoute.Staking(
|
||||
userWalletId = selectedUserWalletId,
|
||||
cryptoCurrencyId = cryptoCurrency.id,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
yieldId = yield.id,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ import com.tangem.core.ui.format.bigdecimal.crypto
|
|||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.core.ui.haptic.TangemHapticEffect
|
||||
import com.tangem.core.ui.haptic.VibratorHapticManager
|
||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
||||
import com.tangem.domain.account.status.usecase.GetAccountCurrencyStatusUseCase
|
||||
import com.tangem.domain.account.usecase.IsAccountsModeEnabledUseCase
|
||||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.features.staking.impl.R
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
|
|
@ -34,6 +37,7 @@ import com.tangem.domain.feedback.SaveBlockchainErrorUseCase
|
|||
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
||||
import com.tangem.domain.feedback.models.BlockchainErrorInfo
|
||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.domain.models.account.Account
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.staking.*
|
||||
|
|
@ -52,11 +56,7 @@ import com.tangem.domain.staking.model.stakekit.transaction.StakingTransaction
|
|||
import com.tangem.domain.staking.utils.getValidatorsCount
|
||||
import com.tangem.domain.tokens.*
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
import com.tangem.domain.transaction.usecase.CreateApprovalTransactionUseCase
|
||||
import com.tangem.domain.transaction.usecase.CreateTransferTransactionUseCase
|
||||
import com.tangem.domain.transaction.usecase.GetAllowanceUseCase
|
||||
import com.tangem.domain.transaction.usecase.GetFeeUseCase
|
||||
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
|
||||
import com.tangem.domain.transaction.usecase.*
|
||||
import com.tangem.domain.utils.convertToSdkAmount
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.features.staking.api.StakingComponent
|
||||
|
|
@ -78,9 +78,9 @@ import com.tangem.features.staking.impl.presentation.state.transformers.confirma
|
|||
import com.tangem.features.staking.impl.presentation.state.transformers.notifications.AddStakingNotificationsTransformer
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.notifications.DismissStakingNotificationsStateTransformer
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.ton.CompleteInitializeBottomSheetTransformer
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.ton.SetFeeErrorToTonInitializeBottomSheetTransformer
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.ton.SetFeeToTonInitializeBottomSheetTransformer
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.ton.ShowTonInitializeBottomSheetTransformer
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.ton.SetFeeErrorToTonInitializeBottomSheetTransformer
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.validator.ValidatorSelectChangeTransformer
|
||||
import com.tangem.features.staking.impl.presentation.state.utils.checkAndCalculateSubtractedAmount
|
||||
import com.tangem.features.staking.impl.presentation.state.utils.isSingleAction
|
||||
|
|
@ -139,12 +139,15 @@ internal class StakingModel @Inject constructor(
|
|||
private val getFeeUseCase: GetFeeUseCase,
|
||||
private val getNetworkAddressesUseCase: GetNetworkAddressesUseCase,
|
||||
private val getActionRequirementAmountUseCase: GetActionRequirementAmountUseCase,
|
||||
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
|
||||
private val getAccountCurrencyStatusUseCase: GetAccountCurrencyStatusUseCase,
|
||||
private val paramsInterceptorHolder: ParamsInterceptorHolder,
|
||||
private val shareManager: ShareManager,
|
||||
private val urlOpener: UrlOpener,
|
||||
@DelayedWork private val coroutineScope: CoroutineScope,
|
||||
private val innerRouter: InnerStakingRouter,
|
||||
private val messageSender: UiMessageSender,
|
||||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
||||
appRouter: AppRouter,
|
||||
) : Model(), StakingClickIntents {
|
||||
|
||||
|
|
@ -159,7 +162,7 @@ internal class StakingModel @Inject constructor(
|
|||
analyticsEventsHandler = analyticsEventHandler,
|
||||
)
|
||||
|
||||
private val cryptoCurrencyId: CryptoCurrency.ID = params.cryptoCurrencyId
|
||||
private val cryptoCurrencyId: CryptoCurrency.ID = params.cryptoCurrency.id
|
||||
private val userWalletId: UserWalletId = params.userWalletId
|
||||
private val yield: Yield = runBlocking {
|
||||
getYieldUseCase(params.yieldId).getOrElse {
|
||||
|
|
@ -172,6 +175,8 @@ internal class StakingModel @Inject constructor(
|
|||
private var stakingActions: List<StakingAction> = emptyList()
|
||||
private var feeCryptoCurrencyStatus: CryptoCurrencyStatus? = null
|
||||
private var minimumTransactionAmount: EnterAmountBoundary? = null
|
||||
private val isBalanceHiddenFlow: StateFlow<Boolean>
|
||||
field = MutableStateFlow(false)
|
||||
|
||||
private var tonAccountInitializeTransaction: TransactionData.Uncompiled? = null
|
||||
|
||||
|
|
@ -237,6 +242,9 @@ internal class StakingModel @Inject constructor(
|
|||
private var isAnyTokenStaked: Boolean = false
|
||||
private val allowanceTaskScheduler = SingleTaskScheduler<BigDecimal>()
|
||||
|
||||
private var isAccountsModeEnabled: Boolean = true
|
||||
private var account: Account.CryptoPortfolio? = null
|
||||
|
||||
private val transactionsInProgress: CopyOnWriteArrayList<StakingTransaction> = CopyOnWriteArrayList()
|
||||
|
||||
private var actionsJobHolder: JobHolder = JobHolder()
|
||||
|
|
@ -247,7 +255,6 @@ internal class StakingModel @Inject constructor(
|
|||
|
||||
init {
|
||||
subscribeOnSelectedAppCurrency()
|
||||
subscribeOnBalanceHiding()
|
||||
subscribeOnCurrencyStatusUpdates()
|
||||
stateController.initializeWithUserWallet(userWallet)
|
||||
}
|
||||
|
|
@ -297,6 +304,9 @@ internal class StakingModel @Inject constructor(
|
|||
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
|
||||
userWalletProvider = Provider { userWallet },
|
||||
appCurrencyProvider = Provider { appCurrency },
|
||||
isBalanceHidden = isBalanceHiddenFlow.value,
|
||||
isAccountsModeEnabled = isAccountsModeEnabled,
|
||||
account = account,
|
||||
).let(::add)
|
||||
AmountMaxValueStateTransformer(
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
|
|
@ -1012,10 +1022,12 @@ internal class StakingModel @Inject constructor(
|
|||
)
|
||||
},
|
||||
ifRight = {
|
||||
stateController.update(CompleteInitializeBottomSheetTransformer(
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
minimumTransactionAmount = minimumTransactionAmount,
|
||||
))
|
||||
stateController.update(
|
||||
CompleteInitializeBottomSheetTransformer(
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
minimumTransactionAmount = minimumTransactionAmount,
|
||||
),
|
||||
)
|
||||
|
||||
balanceUpdater.partialUpdateWithDelay()
|
||||
stateController.update(DismissBottomSheetStateTransformer)
|
||||
|
|
@ -1045,72 +1057,89 @@ internal class StakingModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun subscribeOnCurrencyStatusUpdates() {
|
||||
getSingleCryptoCurrencyStatusUseCase.invokeMultiWallet(
|
||||
userWalletId = userWalletId,
|
||||
currencyId = cryptoCurrencyId,
|
||||
isSingleWalletWithTokens = false,
|
||||
)
|
||||
.conflate()
|
||||
.distinctUntilChanged()
|
||||
.filter {
|
||||
value.currentStep == StakingStep.InitialInfo || isCaseWithUnitializedTonAccount()
|
||||
}
|
||||
.onEach { maybeStatus ->
|
||||
maybeStatus.fold(
|
||||
ifRight = { status ->
|
||||
if (!isInitialInfoAnalyticSent) {
|
||||
isInitialInfoAnalyticSent = true
|
||||
val balances = status.value.yieldBalance as? YieldBalance.Data
|
||||
paramsInterceptorHolder.addParamsInterceptor(
|
||||
interceptor = StakingParamsInterceptor(status.currency.symbol),
|
||||
if (accountsFeatureToggles.isFeatureEnabled) {
|
||||
getAccountCurrencyStatusUseCase(
|
||||
userWalletId = params.userWalletId,
|
||||
currency = params.cryptoCurrency,
|
||||
).conflate().distinctUntilChanged()
|
||||
.filter {
|
||||
value.currentStep == StakingStep.InitialInfo || isCaseWithUnitializedTonAccount()
|
||||
}.onEach { (maybeAccount, maybeStatus) ->
|
||||
isAccountsModeEnabled = isAccountsModeEnabledUseCase.invokeSync()
|
||||
account = maybeAccount
|
||||
onDataLoaded(maybeStatus)
|
||||
}.flowOn(dispatchers.main)
|
||||
.launchIn(modelScope)
|
||||
} else {
|
||||
getSingleCryptoCurrencyStatusUseCase.invokeMultiWallet(
|
||||
userWalletId = userWalletId,
|
||||
currencyId = cryptoCurrencyId,
|
||||
isSingleWalletWithTokens = false,
|
||||
).conflate().distinctUntilChanged()
|
||||
.filter {
|
||||
value.currentStep == StakingStep.InitialInfo || isCaseWithUnitializedTonAccount()
|
||||
}
|
||||
.onEach { maybeStatus ->
|
||||
maybeStatus.fold(
|
||||
ifRight = { onDataLoaded(it) },
|
||||
ifLeft = { error ->
|
||||
stakingEventFactory.createGenericErrorAlert(error.toString())
|
||||
stateController.update(
|
||||
SetConfirmationStateResetAssentTransformer(cryptoCurrencyStatus = cryptoCurrencyStatus),
|
||||
)
|
||||
analyticsEventHandler.send(
|
||||
StakingAnalyticsEvent.StakingInfoScreenOpened(
|
||||
validatorsCount = balances?.getValidatorsCount() ?: 0,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}.flowOn(dispatchers.main)
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
}
|
||||
|
||||
feeCryptoCurrencyStatus =
|
||||
getFeePaidCryptoCurrencyStatusSyncUseCase(userWalletId, status).getOrNull()
|
||||
minimumTransactionAmount =
|
||||
getMinimumTransactionAmountSyncUseCase(userWalletId, status).getOrNull()?.let {
|
||||
EnterAmountBoundary(
|
||||
amount = it,
|
||||
fiatRate = status.value.fiatRate.orZero(),
|
||||
)
|
||||
}
|
||||
cryptoCurrencyStatus = status
|
||||
private suspend fun onDataLoaded(status: CryptoCurrencyStatus) {
|
||||
if (value.currentStep != StakingStep.InitialInfo) return
|
||||
|
||||
val isAccountInitializedNew = checkAccountInitializedUseCase.invoke(
|
||||
userWalletId = userWalletId,
|
||||
network = cryptoCurrencyStatus.currency.network,
|
||||
).getOrElse {
|
||||
Timber.e(it)
|
||||
false
|
||||
}
|
||||
if (isAccountInitializedNew && !isAccountInitialized) {
|
||||
isAccountInitialized = true
|
||||
updateNotifications()
|
||||
}
|
||||
isAccountInitialized = isAccountInitializedNew
|
||||
if (!isInitialInfoAnalyticSent) {
|
||||
isInitialInfoAnalyticSent = true
|
||||
val balances = status.value.yieldBalance as? YieldBalance.Data
|
||||
paramsInterceptorHolder.addParamsInterceptor(
|
||||
interceptor = StakingParamsInterceptor(status.currency.symbol),
|
||||
)
|
||||
analyticsEventHandler.send(
|
||||
StakingAnalyticsEvent.StakingInfoScreenOpened(
|
||||
validatorsCount = balances?.getValidatorsCount() ?: 0,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
setupApprovalNeeded()
|
||||
setupIsAnyTokenStaked()
|
||||
checkIfSubtractAvailable()
|
||||
subscribeOnActionsUpdates(status)
|
||||
subscribeOnStepChanges(status)
|
||||
},
|
||||
ifLeft = { error ->
|
||||
stakingEventFactory.createGenericErrorAlert(error.toString())
|
||||
stateController.update(
|
||||
SetConfirmationStateResetAssentTransformer(cryptoCurrencyStatus = cryptoCurrencyStatus),
|
||||
)
|
||||
},
|
||||
feeCryptoCurrencyStatus =
|
||||
getFeePaidCryptoCurrencyStatusSyncUseCase(userWalletId, status).getOrNull()
|
||||
minimumTransactionAmount =
|
||||
getMinimumTransactionAmountSyncUseCase(userWalletId, status).getOrNull()?.let {
|
||||
EnterAmountBoundary(
|
||||
amount = it,
|
||||
fiatRate = status.value.fiatRate.orZero(),
|
||||
)
|
||||
}
|
||||
.flowOn(dispatchers.main)
|
||||
.launchIn(modelScope)
|
||||
cryptoCurrencyStatus = status
|
||||
|
||||
val isAccountInitializedNew = checkAccountInitializedUseCase.invoke(
|
||||
userWalletId = userWalletId,
|
||||
network = cryptoCurrencyStatus.currency.network,
|
||||
).getOrElse {
|
||||
Timber.e(it)
|
||||
false
|
||||
}
|
||||
if (isAccountInitializedNew && !isAccountInitialized) {
|
||||
isAccountInitialized = true
|
||||
updateNotifications()
|
||||
}
|
||||
isAccountInitialized = isAccountInitializedNew
|
||||
|
||||
setupApprovalNeeded()
|
||||
setupIsAnyTokenStaked()
|
||||
checkIfSubtractAvailable()
|
||||
subscribeOnActionsUpdates(status)
|
||||
subscribeOnStepChanges(status)
|
||||
subscribeOnBalanceHiding()
|
||||
}
|
||||
|
||||
private fun subscribeOnBalanceHiding() {
|
||||
|
|
@ -1118,7 +1147,14 @@ internal class StakingModel @Inject constructor(
|
|||
.conflate()
|
||||
.distinctUntilChanged()
|
||||
.onEach {
|
||||
stateController.update(transformer = HideBalanceStateTransformer(it.isBalanceHidden))
|
||||
isBalanceHiddenFlow.value = it.isBalanceHidden
|
||||
stateController.update(
|
||||
transformer = HideBalanceStateTransformer(
|
||||
isBalanceHidden = it.isBalanceHidden,
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
appCurrency = appCurrency,
|
||||
),
|
||||
)
|
||||
}
|
||||
.flowOn(dispatchers.main)
|
||||
.launchIn(modelScope)
|
||||
|
|
@ -1193,6 +1229,9 @@ internal class StakingModel @Inject constructor(
|
|||
userWalletProvider = Provider { userWallet },
|
||||
appCurrencyProvider = Provider { appCurrency },
|
||||
balancesToShowProvider = Provider { balancesToShow },
|
||||
isAccountsModeEnabled = isAccountsModeEnabled,
|
||||
account = account,
|
||||
isBalanceHidden = isBalanceHiddenFlow.value,
|
||||
),
|
||||
SetConfirmationStateEmptyTransformer,
|
||||
)
|
||||
|
|
@ -1227,6 +1266,9 @@ internal class StakingModel @Inject constructor(
|
|||
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
|
||||
userWalletProvider = Provider { userWallet },
|
||||
appCurrencyProvider = Provider { appCurrency },
|
||||
isAccountsModeEnabled = isAccountsModeEnabled,
|
||||
isBalanceHidden = isBalanceHiddenFlow.value,
|
||||
account = account,
|
||||
),
|
||||
AmountChangeStateTransformer(
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
|
|
|
|||
|
|
@ -1,13 +1,40 @@
|
|||
package com.tangem.features.staking.impl.presentation.state.transformers
|
||||
|
||||
import com.tangem.common.ui.amountScreen.converters.field.AmountBoundaryUpdateTransformer
|
||||
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingUiState
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
|
||||
internal class HideBalanceStateTransformer(
|
||||
private val isBalanceHidden: Boolean,
|
||||
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
private val appCurrency: AppCurrency,
|
||||
) : Transformer<StakingUiState> {
|
||||
|
||||
override fun transform(prevState: StakingUiState): StakingUiState {
|
||||
return prevState.copy(isBalanceHidden = isBalanceHidden)
|
||||
val cryptoBalanceValue = cryptoCurrencyStatus.value
|
||||
val (amount, fiatAmount) = if (prevState.actionType !is StakingActionCommonType.Enter) {
|
||||
prevState.balanceState?.cryptoAmount to prevState.balanceState?.fiatAmount
|
||||
} else {
|
||||
cryptoBalanceValue.amount to cryptoBalanceValue.fiatAmount
|
||||
}
|
||||
val maxEnterAmount = EnterAmountBoundary(
|
||||
amount = amount,
|
||||
fiatAmount = fiatAmount,
|
||||
fiatRate = cryptoBalanceValue.fiatRate,
|
||||
)
|
||||
|
||||
return prevState.copy(
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
amountState = AmountBoundaryUpdateTransformer(
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
maxEnterAmount = maxEnterAmount,
|
||||
appCurrency = appCurrency,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
).transform(prevState.amountState),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.features.staking.impl.presentation.state.transformers
|
||||
|
||||
import com.tangem.common.ui.account.AccountTitleUM
|
||||
import com.tangem.common.ui.amountScreen.converters.AmountAccountConverter
|
||||
import com.tangem.common.ui.amountScreen.converters.AmountStateConverter
|
||||
import com.tangem.common.ui.amountScreen.models.AmountParameters
|
||||
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
|
||||
|
|
@ -8,6 +9,7 @@ import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIco
|
|||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.account.Account
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.staking.model.stakekit.action.StakingActionCommonType
|
||||
|
|
@ -17,20 +19,28 @@ import com.tangem.features.staking.impl.presentation.state.StakingUiState
|
|||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class SetAmountDataTransformer(
|
||||
private val clickIntents: StakingClickIntents,
|
||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||
private val userWalletProvider: Provider<UserWallet>,
|
||||
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||
private val isBalanceHidden: Boolean,
|
||||
private val isAccountsModeEnabled: Boolean,
|
||||
private val account: Account.CryptoPortfolio?,
|
||||
) : Transformer<StakingUiState> {
|
||||
|
||||
private val iconStateConverter by lazy(::CryptoCurrencyToIconStateConverter)
|
||||
|
||||
override fun transform(prevState: StakingUiState): StakingUiState {
|
||||
val title = if (prevState.actionType is StakingActionCommonType.Exit) {
|
||||
resourceReference(R.string.staking_staked_amount)
|
||||
} else {
|
||||
stringReference(userWalletProvider().name)
|
||||
val accountTitleUM = when (prevState.actionType) {
|
||||
is StakingActionCommonType.Exit -> AccountTitleUM.Text(resourceReference(R.string.staking_staked_amount))
|
||||
is StakingActionCommonType.Enter -> AmountAccountConverter(
|
||||
isAccountsMode = isAccountsModeEnabled,
|
||||
walletTitle = stringReference(userWalletProvider().name),
|
||||
prefixText = resourceReference(R.string.common_from),
|
||||
).convert(account)
|
||||
else -> AccountTitleUM.Text(resourceReference(R.string.common_amount))
|
||||
}
|
||||
val cryptoBalanceValue = cryptoCurrencyStatusProvider().value
|
||||
val (amount, fiatAmount) = if (prevState.actionType !is StakingActionCommonType.Enter) {
|
||||
|
|
@ -51,11 +61,11 @@ internal class SetAmountDataTransformer(
|
|||
maxEnterAmount = maxEnterAmount,
|
||||
appCurrency = appCurrencyProvider(),
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatusProvider(),
|
||||
isBalanceHidden = false,
|
||||
accountTitleUM = AccountTitleUM.Text(title),
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
accountTitleUM = accountTitleUM,
|
||||
).convert(
|
||||
AmountParameters(
|
||||
title = title,
|
||||
title = stringReference(userWalletProvider().name),
|
||||
value = "",
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package com.tangem.features.staking.impl.presentation.state.transformers
|
|||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.common.extensions.remove
|
||||
import com.tangem.common.ui.account.AccountTitleUM
|
||||
import com.tangem.common.ui.amountScreen.converters.AmountAccountConverter
|
||||
import com.tangem.common.ui.amountScreen.converters.AmountStateConverter
|
||||
import com.tangem.common.ui.amountScreen.models.AmountParameters
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
|
|
@ -15,6 +15,7 @@ import com.tangem.core.ui.format.bigdecimal.crypto
|
|||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.core.ui.format.bigdecimal.percent
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.account.Account
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.staking.BalanceItem
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
|
|
@ -46,6 +47,9 @@ internal class SetInitialDataStateTransformer(
|
|||
private val userWalletProvider: Provider<UserWallet>,
|
||||
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||
private val balancesToShowProvider: Provider<List<BalanceItem>>,
|
||||
private val isAccountsModeEnabled: Boolean,
|
||||
private val account: Account.CryptoPortfolio?,
|
||||
private val isBalanceHidden: Boolean,
|
||||
) : Transformer<StakingUiState> {
|
||||
|
||||
private val iconStateConverter by lazy(::CryptoCurrencyToIconStateConverter)
|
||||
|
|
@ -234,8 +238,12 @@ internal class SetInitialDataStateTransformer(
|
|||
appCurrency = appCurrencyProvider(),
|
||||
iconStateConverter = iconStateConverter,
|
||||
maxEnterAmount = maxEnterAmount,
|
||||
isBalanceHidden = false,
|
||||
accountTitleUM = AccountTitleUM.Text(stringReference(userWalletProvider().name)),
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
accountTitleUM = AmountAccountConverter(
|
||||
isAccountsMode = isAccountsModeEnabled,
|
||||
walletTitle = stringReference(userWalletProvider().name),
|
||||
prefixText = resourceReference(R.string.common_from),
|
||||
).convert(account),
|
||||
).convert(
|
||||
AmountParameters(
|
||||
title = stringReference(userWalletProvider().name),
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ internal fun StakingFeeBlock(feeState: FeeState) {
|
|||
text = stringResourceSafe(R.string.common_network_fee_title),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing4),
|
||||
)
|
||||
|
||||
Box(modifier = Modifier.padding(top = TangemTheme.dimens.spacing8)) {
|
||||
|
|
|
|||
|
|
@ -3,15 +3,23 @@ package com.tangem.features.staking.impl.presentation.ui.block
|
|||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.ripple
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import com.tangem.core.ui.components.inputrow.InputRowImageInfo
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.SpacerWMax
|
||||
import com.tangem.core.ui.components.inputrow.inner.InputRowAsyncImage
|
||||
import com.tangem.core.ui.extensions.*
|
||||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.core.ui.format.bigdecimal.percent
|
||||
|
|
@ -42,13 +50,37 @@ internal fun ValidatorBlock(validatorState: StakingStates.ValidatorState, isClic
|
|||
)
|
||||
.testTag(StakingSendDetailsScreenTestTags.VALIDATOR_BLOCK),
|
||||
) {
|
||||
InputRowImageInfo(
|
||||
title = resourceReference(R.string.staking_validator),
|
||||
subtitle = stringReference(state.chosenValidator.name),
|
||||
infoTitle = state.getInfoTitleNeutral(),
|
||||
imageUrl = state.chosenValidator.image.orEmpty(),
|
||||
onImageError = { ValidatorImagePlaceholder() },
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.staking_validator),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
modifier = Modifier.padding(start = 12.dp, top = 12.dp, end = 12.dp, bottom = 4.dp),
|
||||
)
|
||||
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
modifier = Modifier.padding(12.dp),
|
||||
) {
|
||||
InputRowAsyncImage(
|
||||
imageUrl = validatorState.chosenValidator.image.orEmpty(),
|
||||
onImageError = { ValidatorImagePlaceholder() },
|
||||
modifier = Modifier
|
||||
.size(24.dp)
|
||||
.clip(TangemTheme.shapes.roundedCornersXLarge),
|
||||
)
|
||||
Text(
|
||||
text = validatorState.chosenValidator.name,
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
SpacerWMax()
|
||||
Text(
|
||||
text = validatorState.getInfoTitleNeutral().resolveReference(),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ internal class DefaultTokenDetailsRouter @Inject constructor(
|
|||
router.push(
|
||||
AppRoute.Staking(
|
||||
userWalletId = userWalletId,
|
||||
cryptoCurrencyId = cryptoCurrency.id,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
yieldId = yieldId,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -507,7 +507,7 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
appRouter.push(
|
||||
AppRoute.Staking(
|
||||
userWalletId = userWalletId,
|
||||
cryptoCurrencyId = cryptoCurrency.id,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
yieldId = yield?.id ?: return@launch,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue