Updated on 2026-08-14
This commit is contained in:
parent
f57a7ecac9
commit
f6b0bf8dd5
24 changed files with 80 additions and 124 deletions
|
|
@ -1,8 +1,10 @@
|
|||
package com.tangem.common.ui.navigationButtons
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
|
||||
@Immutable
|
||||
sealed class NavigationButtonsState {
|
||||
data object Empty : NavigationButtonsState()
|
||||
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ import com.tangem.data.staking.store.StakeKitBalancesStore
|
|||
import com.tangem.datasource.api.ethpool.models.response.P2PEthPoolAccountResponse
|
||||
import com.tangem.datasource.api.stakekit.models.response.model.YieldBalanceWrapperDTO
|
||||
import com.tangem.datasource.local.datastore.RuntimeSharedStore
|
||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
||||
import com.tangem.domain.staking.multi.MultiStakingBalanceProducer
|
||||
import com.tangem.domain.staking.multi.MultiStakingBalanceSupplier
|
||||
import com.tangem.domain.staking.single.SingleStakingBalanceProducer
|
||||
import com.tangem.domain.staking.single.SingleStakingBalanceSupplier
|
||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -54,7 +54,7 @@ internal object StakingBalanceSupplierModule {
|
|||
fun provideSingleStakingBalanceSupplier(
|
||||
factory: SingleStakingBalanceProducer.Factory,
|
||||
): SingleStakingBalanceSupplier {
|
||||
return object : SingleStakingBalanceSupplier(
|
||||
return SingleStakingBalanceSupplier(
|
||||
factory = factory,
|
||||
keyCreator = { params ->
|
||||
listOf(
|
||||
|
|
@ -65,15 +65,15 @@ internal object StakingBalanceSupplierModule {
|
|||
)
|
||||
.joinToString(separator = "_")
|
||||
},
|
||||
) {}
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideMultiStakingBalanceSupplier(factory: MultiStakingBalanceProducer.Factory): MultiStakingBalanceSupplier {
|
||||
return object : MultiStakingBalanceSupplier(
|
||||
return MultiStakingBalanceSupplier(
|
||||
factory = factory,
|
||||
keyCreator = { "multi_staking_balances_${it.userWalletId.stringValue}" },
|
||||
) {}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<?xml version="1.0" ?>
|
||||
<SmellBaseline>
|
||||
<ManuallySuppressedIssues/>
|
||||
<CurrentIssues>
|
||||
<ID>MultilineLambdaItParameter:FetchStakingYieldBalanceUseCase.kt$FetchStakingYieldBalanceUseCase${ when (it) { is StakingIdFactory.Error.UnableToGetAddress -> raise(StakingError.DomainError("$it")) StakingIdFactory.Error.UnsupportedCurrency -> Unit.right() } return@either }</ID>
|
||||
<ID>MultilineLambdaItParameter:InvalidatePendingTransactionsUseCase.kt$InvalidatePendingTransactionsUseCase${ !it.isPending && action.amount < it.amount && it.type == BalanceType.STAKED && it.validatorAddress == action.validatorAddress }</ID>
|
||||
<ID>NamedArguments:GetConstructedStakingTransactionUseCase.kt$GetConstructedStakingTransactionUseCase$constructTransaction(networkId, fee, amount, transactionId)</ID>
|
||||
<ID>UnnecessaryAbstractClass:MultiStakingBalanceSupplier.kt$MultiStakingBalanceSupplier$MultiStakingBalanceSupplier</ID>
|
||||
<ID>UnnecessaryAbstractClass:SingleStakingBalanceSupplier.kt$SingleStakingBalanceSupplier$SingleStakingBalanceSupplier</ID>
|
||||
<ID>UseEmptyCounterpart:StakingAnalyticsEvent.kt$StakingAnalyticsEvent$mapOf()</ID>
|
||||
<ID>UseOrEmpty:InvalidatePendingTransactionsUseCase.kt$InvalidatePendingTransactionsUseCase$action.validatorAddress ?: action.validatorAddresses?.getOrNull(0) ?: ""</ID>
|
||||
</CurrentIssues>
|
||||
</SmellBaseline>
|
||||
|
|
@ -23,9 +23,9 @@ class FetchStakingYieldBalanceUseCase(
|
|||
currencyId = cryptoCurrency.id,
|
||||
network = cryptoCurrency.network,
|
||||
)
|
||||
.getOrElse {
|
||||
when (it) {
|
||||
is StakingIdFactory.Error.UnableToGetAddress -> raise(StakingError.DomainError("$it"))
|
||||
.getOrElse { error ->
|
||||
when (error) {
|
||||
is StakingIdFactory.Error.UnableToGetAddress -> raise(StakingError.DomainError("$error"))
|
||||
StakingIdFactory.Error.UnsupportedCurrency -> Unit.right()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,12 @@ class GetConstructedStakingTransactionUseCase(
|
|||
amount: Amount,
|
||||
transactionId: String,
|
||||
): Either<StakingError, Pair<StakingTransaction, TransactionData.Compiled>> = Either.catch {
|
||||
stakeKitRepository.constructTransaction(networkId, fee, amount, transactionId)
|
||||
stakeKitRepository.constructTransaction(
|
||||
networkId = networkId,
|
||||
fee = fee,
|
||||
amount = amount,
|
||||
transactionId = transactionId,
|
||||
)
|
||||
}.mapLeft {
|
||||
stakingErrorResolver.resolve(it)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ class InvalidatePendingTransactionsUseCase(
|
|||
type = BalanceType.STAKED,
|
||||
amount = action.amount,
|
||||
rawCurrencyId = null,
|
||||
validatorAddress = action.validatorAddress ?: action.validatorAddresses?.getOrNull(0) ?: "",
|
||||
validatorAddress = action.validatorAddress ?: action.validatorAddresses?.getOrNull(0).orEmpty(),
|
||||
date = null,
|
||||
pendingActions = emptyList(),
|
||||
pendingActionsConstraints = emptyList(),
|
||||
|
|
@ -149,10 +149,10 @@ class InvalidatePendingTransactionsUseCase(
|
|||
}
|
||||
|
||||
private fun findPartialUnstake(balances: MutableList<BalanceItem>, action: StakingAction): Pair<Int, BigDecimal> {
|
||||
val index = balances.indexOfFirst {
|
||||
!it.isPending && action.amount < it.amount &&
|
||||
it.type == BalanceType.STAKED &&
|
||||
it.validatorAddress == action.validatorAddress
|
||||
val index = balances.indexOfFirst { balance ->
|
||||
!balance.isPending && action.amount < balance.amount &&
|
||||
balance.type == BalanceType.STAKED &&
|
||||
balance.validatorAddress == action.validatorAddress
|
||||
}
|
||||
return index to action.amount
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import com.tangem.domain.models.staking.action.StakingActionType
|
|||
|
||||
sealed class StakingAnalyticsEvent(
|
||||
event: String,
|
||||
params: Map<String, String> = mapOf(),
|
||||
params: Map<String, String> = emptyMap(),
|
||||
) : AnalyticsEvent(
|
||||
category = "Staking",
|
||||
event = event,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import com.tangem.domain.models.staking.StakingBalance
|
|||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
abstract class MultiStakingBalanceSupplier(
|
||||
open class MultiStakingBalanceSupplier(
|
||||
override val factory: FlowProducer.Factory<MultiStakingBalanceProducer.Params, MultiStakingBalanceProducer>,
|
||||
override val keyCreator: (MultiStakingBalanceProducer.Params) -> String,
|
||||
) : FlowCachingSupplier<MultiStakingBalanceProducer, MultiStakingBalanceProducer.Params, Set<StakingBalance>>()
|
||||
|
|
@ -12,7 +12,7 @@ import com.tangem.domain.models.staking.StakingBalance
|
|||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
abstract class SingleStakingBalanceSupplier(
|
||||
open class SingleStakingBalanceSupplier(
|
||||
override val factory: FlowProducer.Factory<SingleStakingBalanceProducer.Params, SingleStakingBalanceProducer>,
|
||||
override val keyCreator: (SingleStakingBalanceProducer.Params) -> String,
|
||||
) : FlowCachingSupplier<SingleStakingBalanceProducer, SingleStakingBalanceProducer.Params, StakingBalance>()
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
<?xml version="1.0" ?>
|
||||
<SmellBaseline>
|
||||
<ManuallySuppressedIssues/>
|
||||
<CurrentIssues>
|
||||
<ID>BooleanPropertyNaming:AddStakingNotificationsTransformer.kt$AddStakingNotificationsTransformer$val showNotification = sendingAmount + feeAmount > balance</ID>
|
||||
<ID>BooleanPropertyNaming:AmountCurrencyChangeStateTransformer.kt$AmountCurrencyChangeStateTransformer$private val value: Boolean</ID>
|
||||
<ID>BooleanPropertyNaming:StakingUiState.kt$StakingStates.InitialInfoState.Data$val showBanner: Boolean</ID>
|
||||
<ID>BooleanPropertyNaming:StakingUiState.kt$StakingUiState$val showColdWalletInteractionIcon: Boolean</ID>
|
||||
<ID>CastNullableToNonNullableType:SetApprovalBottomSheetInProgressTransformer.kt$SetApprovalBottomSheetInProgressTransformer$as</ID>
|
||||
<ID>CastNullableToNonNullableType:SetApprovalBottomSheetTypeChangeTransformer.kt$SetApprovalBottomSheetTypeChangeTransformer$as</ID>
|
||||
<ID>MultilineLambdaItParameter:AddStakingNotificationsTransformer.kt$AddStakingNotificationsTransformer${ it is StakingNotification.Error || it is NotificationUM.Error || it is NotificationUM.Warning.NetworkFeeUnreachable || it is StakingNotification.Warning.TransactionInProgress || it is StakingNotification.Warning.InitializeTonAccount }</ID>
|
||||
<ID>MultilineLambdaItParameter:DefaultStakingDeepLinkHandler.kt$DefaultStakingDeepLinkHandler${ val isNetwork = it.network.backendId.equals(networkId, ignoreCase = true) val isCurrency = it.id.rawCurrencyId?.value?.equals(tokenId, ignoreCase = true) == true isNetwork && isCurrency }</ID>
|
||||
<ID>MultilineLambdaItParameter:StakingFeeBlock.kt${ if (it == FeeState.Error) { Text( text = DASH_SIGN, color = TangemTheme.colors.text.primary1, style = TangemTheme.typography.body1, ) } }</ID>
|
||||
<ID>MultilineLambdaItParameter:StakingFeeBlock.kt${ if (it == FeeState.Loading) { RectangleShimmer( radius = TangemTheme.dimens.radius3, modifier = Modifier.size( height = TangemTheme.dimens.size24, width = TangemTheme.dimens.size90, ), ) } }</ID>
|
||||
<ID>MultilineLambdaItParameter:StakingInfoNotificationsFactory.kt$StakingInfoNotificationsFactory${ it.type == BalanceType.PREPARING || it.type == BalanceType.STAKED || it.type == BalanceType.LOCKED }</ID>
|
||||
<ID>MultilineLambdaItParameter:StakingStateController.kt$StakingStateController${ it.copy( showColdWalletInteractionIcon = userWallet is UserWallet.Cold, ) }</ID>
|
||||
<ID>NullableToStringCall:DefaultStakingDeepLinkHandler.kt$DefaultStakingDeepLinkHandler$$networkId</ID>
|
||||
<ID>NullableToStringCall:DefaultStakingDeepLinkHandler.kt$DefaultStakingDeepLinkHandler$$tokenId</ID>
|
||||
<ID>PropertyUsedBeforeDeclaration:StakingFeeBlock.kt$FeeBlockPreviewProvider$contentState</ID>
|
||||
<ID>PropertyUsedBeforeDeclaration:StakingStateController.kt$StakingStateController$uiState</ID>
|
||||
<ID>UnnecessaryEventHandlerParameter:StakingInitialInfoContent.kt$onClick: (BalanceState) -> Unit</ID>
|
||||
<ID>UnnecessaryLet:StakingTosText.kt$let { onTextClick(PRIVACY_POLICY_URL) }</ID>
|
||||
<ID>UnnecessaryLet:StakingTosText.kt$let { onTextClick(TERMS_OF_USE_URL) }</ID>
|
||||
</CurrentIssues>
|
||||
</SmellBaseline>
|
||||
|
|
@ -53,9 +53,9 @@ internal class DefaultStakingDeepLinkHandler @AssistedInject constructor(
|
|||
params = MultiWalletCryptoCurrenciesProducer.Params(selectedUserWalletId),
|
||||
)
|
||||
.orEmpty()
|
||||
.firstOrNull {
|
||||
val isNetwork = it.network.backendId.equals(networkId, ignoreCase = true)
|
||||
val isCurrency = it.id.rawCurrencyId?.value?.equals(tokenId, ignoreCase = true) == true
|
||||
.firstOrNull { currency ->
|
||||
val isNetwork = currency.network.backendId.equals(networkId, ignoreCase = true)
|
||||
val isCurrency = currency.id.rawCurrencyId?.value?.equals(tokenId, ignoreCase = true) == true
|
||||
isNetwork && isCurrency
|
||||
}
|
||||
|
||||
|
|
@ -63,8 +63,8 @@ internal class DefaultStakingDeepLinkHandler @AssistedInject constructor(
|
|||
TangemLogger.e(
|
||||
"""
|
||||
Could not get crypto currency for
|
||||
|- $NETWORK_ID_KEY: $networkId
|
||||
|- $TOKEN_ID_KEY: $tokenId
|
||||
|- $NETWORK_ID_KEY: ${networkId.orEmpty()}
|
||||
|- $TOKEN_ID_KEY: ${tokenId.orEmpty()}
|
||||
""".trimIndent(),
|
||||
)
|
||||
return@launch
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.features.staking.impl.presentation.model
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.common.ui.amountScreen.AmountScreenClickIntents
|
||||
import com.tangem.common.ui.bottomsheet.permission.state.ApproveType
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
|
|
@ -11,6 +12,7 @@ import java.math.BigDecimal
|
|||
|
||||
// TODO split this interface to click intents and other interaction events
|
||||
@Suppress("TooManyFunctions")
|
||||
@Immutable
|
||||
internal interface StakingClickIntents : AmountScreenClickIntents {
|
||||
|
||||
fun onBackClick()
|
||||
|
|
|
|||
|
|
@ -26,19 +26,19 @@ internal class StakingStateController @Inject constructor(
|
|||
private val holdToConfirmButtonFeatureToggles: HoldToConfirmButtonFeatureToggles,
|
||||
) {
|
||||
|
||||
val value: StakingUiState get() = uiState.value
|
||||
|
||||
private val mutableUiState: MutableStateFlow<StakingUiState> = MutableStateFlow(value = getInitialState())
|
||||
|
||||
val uiState: StateFlow<StakingUiState> get() = mutableUiState.asStateFlow()
|
||||
|
||||
val value: StakingUiState get() = uiState.value
|
||||
|
||||
private val buttonsTransformer = SetButtonsStateTransformer(urlOpener)
|
||||
private val titleTransformer = SetTitleTransformer
|
||||
|
||||
fun initializeWithUserWallet(userWallet: UserWallet) {
|
||||
mutableUiState.update { state ->
|
||||
state.copy(
|
||||
showColdWalletInteractionIcon = userWallet.isColdWallet,
|
||||
isColdWalletInteractionIconVisible = userWallet.isColdWallet,
|
||||
shouldShowHoldToConfirmButton = holdToConfirmButtonFeatureToggles.isHoldToConfirmEnabled &&
|
||||
userWallet.isHotWallet,
|
||||
)
|
||||
|
|
@ -89,7 +89,7 @@ internal class StakingStateController @Inject constructor(
|
|||
actionType = StakingActionCommonType.Enter(skipEnterAmount = false),
|
||||
buttonsState = NavigationButtonsState.Empty,
|
||||
balanceState = null,
|
||||
showColdWalletInteractionIcon = true,
|
||||
isColdWalletInteractionIconVisible = true,
|
||||
shouldShowHoldToConfirmButton = false,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,22 +39,9 @@ internal data class StakingUiState(
|
|||
val actionType: StakingActionCommonType,
|
||||
val buttonsState: NavigationButtonsState,
|
||||
val balanceState: BalanceState?,
|
||||
val showColdWalletInteractionIcon: Boolean,
|
||||
val isColdWalletInteractionIconVisible: Boolean,
|
||||
val shouldShowHoldToConfirmButton: Boolean,
|
||||
) {
|
||||
|
||||
fun copyWrapped(
|
||||
initialInfoState: StakingStates.InitialInfoState = this.initialInfoState,
|
||||
amountState: AmountState = this.amountState,
|
||||
confirmationState: StakingStates.ConfirmationState = this.confirmationState,
|
||||
validatorState: StakingStates.ValidatorState = this.validatorState,
|
||||
): StakingUiState = copy(
|
||||
initialInfoState = initialInfoState,
|
||||
amountState = amountState,
|
||||
confirmationState = confirmationState,
|
||||
validatorState = validatorState,
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
internal sealed class StakingStates {
|
||||
|
||||
|
|
@ -64,7 +51,7 @@ internal sealed class StakingStates {
|
|||
sealed class InitialInfoState : StakingStates() {
|
||||
data class Data(
|
||||
override val isPrimaryButtonEnabled: Boolean,
|
||||
val showBanner: Boolean,
|
||||
val isBannerVisible: Boolean,
|
||||
val infoItems: ImmutableList<RoundedListWithDividersItemData>,
|
||||
val onInfoClick: (InfoType) -> Unit,
|
||||
val yieldBalance: InnerYieldBalanceState,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import kotlinx.collections.immutable.persistentListOf
|
|||
internal object InitialStakingStatePreview {
|
||||
val defaultState = StakingStates.InitialInfoState.Data(
|
||||
isPrimaryButtonEnabled = true,
|
||||
showBanner = true,
|
||||
isBannerVisible = true,
|
||||
infoItems = persistentListOf(
|
||||
RoundedListWithDividersItemData(
|
||||
id = R.string.staking_details_available,
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ internal class SetButtonsStateTransformer(
|
|||
return prevState.copy(buttonsState = buttonsState)
|
||||
}
|
||||
|
||||
private fun getPrimaryButton(prevState: StakingUiState): NavigationButton? {
|
||||
private fun getPrimaryButton(prevState: StakingUiState): NavigationButton {
|
||||
val confirmState = prevState.confirmationState as? StakingStates.ConfirmationState.Data
|
||||
val innerConfirmState = confirmState?.innerState
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ internal class SetButtonsStateTransformer(
|
|||
val isPrimaryButtonDisabled = prevState.isPrimaryButtonDisabled()
|
||||
return NavigationButton(
|
||||
textReference = prevState.getButtonText(),
|
||||
iconRes = R.drawable.ic_tangem_24.takeIf { prevState.showColdWalletInteractionIcon },
|
||||
iconRes = R.drawable.ic_tangem_24.takeIf { prevState.isColdWalletInteractionIconVisible },
|
||||
isDimmed = isPrimaryButtonDisabled,
|
||||
isIconVisible = isIconVisible,
|
||||
shouldShowProgress = isInProgress,
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ internal class SetInitialDataStateTransformer(
|
|||
isPrimaryButtonEnabled = with(status) {
|
||||
!amount.isNullOrZero() && sources.stakingBalanceSource.isActual() && sources.networkSource.isActual()
|
||||
},
|
||||
showBanner = !isAnyTokenStaked && yieldBalance == InnerYieldBalanceState.Empty,
|
||||
isBannerVisible = !isAnyTokenStaked && yieldBalance == InnerYieldBalanceState.Empty,
|
||||
infoItems = getInfoItems(),
|
||||
onInfoClick = clickIntents::onInfoClick,
|
||||
yieldBalance = yieldBalance,
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ import com.tangem.utils.transformer.Transformer
|
|||
|
||||
internal class AmountCurrencyChangeStateTransformer(
|
||||
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
private val value: Boolean,
|
||||
private val isFiatValue: Boolean,
|
||||
) : Transformer<StakingUiState> {
|
||||
override fun transform(prevState: StakingUiState): StakingUiState {
|
||||
return prevState.copy(
|
||||
amountState = AmountCurrencyTransformer(cryptoCurrencyStatus, value).transform(prevState.amountState),
|
||||
amountState = AmountCurrencyTransformer(cryptoCurrencyStatus, isFiatValue).transform(prevState.amountState),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ internal class SetApprovalBottomSheetInProgressTransformer(
|
|||
),
|
||||
onCancel = onDismiss,
|
||||
)
|
||||
} as TangemBottomSheetConfigContent,
|
||||
} as? TangemBottomSheetConfigContent ?: return prevState,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ internal class SetApprovalBottomSheetTypeChangeTransformer(
|
|||
bottomSheetConfig = prevState.bottomSheetConfig?.copy(
|
||||
content = approvalBottomSheetConfig?.copy(
|
||||
data = approvalBottomSheetConfig.data.copy(approveType = approveType),
|
||||
) as TangemBottomSheetConfigContent,
|
||||
) as? TangemBottomSheetConfigContent ?: return prevState,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,12 +177,12 @@ internal class AddStakingNotificationsTransformer(
|
|||
}
|
||||
|
||||
private fun isPrimaryButtonEnabled(notifications: ImmutableList<NotificationUM>, isActualSources: Boolean) =
|
||||
notifications.none {
|
||||
it is StakingNotification.Error ||
|
||||
it is NotificationUM.Error ||
|
||||
it is NotificationUM.Warning.NetworkFeeUnreachable ||
|
||||
it is StakingNotification.Warning.TransactionInProgress ||
|
||||
it is StakingNotification.Warning.InitializeTonAccount
|
||||
notifications.none { notification ->
|
||||
notification is StakingNotification.Error ||
|
||||
notification is NotificationUM.Error ||
|
||||
notification is NotificationUM.Warning.NetworkFeeUnreachable ||
|
||||
notification is StakingNotification.Warning.TransactionInProgress ||
|
||||
notification is StakingNotification.Warning.InitializeTonAccount
|
||||
} && isActualSources
|
||||
|
||||
private fun MutableList<NotificationUM>.addStakingErrorNotifications(
|
||||
|
|
@ -302,8 +302,8 @@ internal class AddStakingNotificationsTransformer(
|
|||
val balance = cryptoCurrencyStatus.value.amount.orZero()
|
||||
if (!isSubtractionAvailable) return
|
||||
|
||||
val showNotification = sendingAmount + feeAmount > balance
|
||||
if (showNotification) {
|
||||
val isExceedsBalance = sendingAmount + feeAmount > balance
|
||||
if (isExceedsBalance) {
|
||||
onNotEnoughFeeNotificationShow()
|
||||
val notification = if (actionType is StakingActionCommonType.Enter) {
|
||||
NotificationUM.Error.TotalExceedsBalance
|
||||
|
|
|
|||
|
|
@ -150,10 +150,10 @@ internal class StakingInfoNotificationsFactory(
|
|||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
val isTron = isTron(cryptoCurrencyStatus.currency.network.rawId)
|
||||
val hasStakedBalance = (cryptoCurrencyStatus.value.stakingBalance as? StakingBalance.Data.StakeKit)?.balance
|
||||
?.items?.any {
|
||||
it.type == BalanceType.PREPARING ||
|
||||
it.type == BalanceType.STAKED ||
|
||||
it.type == BalanceType.LOCKED
|
||||
?.items?.any { item ->
|
||||
item.type == BalanceType.PREPARING ||
|
||||
item.type == BalanceType.STAKED ||
|
||||
item.type == BalanceType.LOCKED
|
||||
} == true
|
||||
if (isTron && hasStakedBalance) {
|
||||
add(
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ internal fun StakingInitialInfoContent(
|
|||
.background(TangemTheme.colors.background.secondary)
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16),
|
||||
) {
|
||||
if (state.showBanner) {
|
||||
if (state.isBannerVisible) {
|
||||
item(key = BANNER_BLOCK_KEY) {
|
||||
Column(
|
||||
modifier = Modifier.animateItem(),
|
||||
|
|
@ -175,7 +175,7 @@ private fun LazyListScope.activeStakingBlock(
|
|||
ActiveStakingBlock(
|
||||
balance = balance,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
onClick = clickIntents::onActiveStake,
|
||||
onClick = { clickIntents.onActiveStake(balance) },
|
||||
onAnalytic = clickIntents::onActiveStakeAnalytic,
|
||||
modifier = Modifier
|
||||
.animateItem()
|
||||
|
|
@ -288,7 +288,7 @@ private fun StakingRewardBlock(
|
|||
private fun ActiveStakingBlock(
|
||||
balance: BalanceState,
|
||||
isBalanceHidden: Boolean,
|
||||
onClick: (BalanceState) -> Unit,
|
||||
onClick: () -> Unit,
|
||||
onAnalytic: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
|
|
@ -304,7 +304,7 @@ private fun ActiveStakingBlock(
|
|||
enabled = balance.isClickable,
|
||||
onClick = {
|
||||
onAnalytic()
|
||||
onClick(balance)
|
||||
onClick()
|
||||
},
|
||||
)
|
||||
.padding(TangemTheme.dimens.spacing12),
|
||||
|
|
@ -351,7 +351,6 @@ private fun ActiveStakingBlock(
|
|||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
if (balance.formattedCryptoAmount != null) {
|
||||
Text(
|
||||
text = balance.formattedCryptoAmount.orMaskWithStars(isBalanceHidden).resolveReference(),
|
||||
style = TangemTheme.typography.caption2,
|
||||
|
|
@ -360,11 +359,10 @@ private fun ActiveStakingBlock(
|
|||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RowScope.StakingBalanceIcon(balance: BalanceState, icon: Int?, iconTint: Color) {
|
||||
private fun StakingBalanceIcon(balance: BalanceState, icon: Int?, iconTint: Color) {
|
||||
if (balance.hasImage() || icon != null) {
|
||||
StakingTargetIcon(
|
||||
image = if (balance.hasImage()) balance.target?.image.toImageReference() else null,
|
||||
|
|
|
|||
|
|
@ -109,8 +109,8 @@ private fun BoxScope.FeeLoading(feeState: FeeState) {
|
|||
targetState = feeState,
|
||||
label = "Fee Loading State Change",
|
||||
modifier = Modifier.align(Alignment.CenterEnd),
|
||||
) {
|
||||
if (it == FeeState.Loading) {
|
||||
) { state ->
|
||||
if (state == FeeState.Loading) {
|
||||
RectangleShimmer(
|
||||
radius = TangemTheme.dimens.radius3,
|
||||
modifier = Modifier.size(
|
||||
|
|
@ -128,8 +128,8 @@ private fun BoxScope.FeeError(feeState: FeeState) {
|
|||
targetState = feeState,
|
||||
label = "Fee Error State Change",
|
||||
modifier = Modifier.align(Alignment.CenterEnd),
|
||||
) {
|
||||
if (it == FeeState.Error) {
|
||||
) { state ->
|
||||
if (state == FeeState.Error) {
|
||||
Text(
|
||||
text = DASH_SIGN,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
|
|
@ -151,13 +151,6 @@ private fun FeeBlockPreview(@PreviewParameter(FeeBlockPreviewProvider::class) va
|
|||
|
||||
private class FeeBlockPreviewProvider : PreviewParameterProvider<FeeState> {
|
||||
|
||||
override val values: Sequence<FeeState>
|
||||
get() = sequenceOf(
|
||||
contentState,
|
||||
FeeState.Loading,
|
||||
FeeState.Error,
|
||||
)
|
||||
|
||||
private val fee = Fee.Common(
|
||||
amount = Amount(
|
||||
currencySymbol = "MATIC",
|
||||
|
|
@ -174,6 +167,13 @@ private class FeeBlockPreviewProvider : PreviewParameterProvider<FeeState> {
|
|||
isFeeApproximate = false,
|
||||
isFeeConvertibleToFiat = true,
|
||||
)
|
||||
|
||||
override val values: Sequence<FeeState>
|
||||
get() = sequenceOf(
|
||||
contentState,
|
||||
FeeState.Loading,
|
||||
FeeState.Error,
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
Loading…
Add table
Add a link
Reference in a new issue