Updated on 2026-08-14
This commit is contained in:
parent
eec5a60676
commit
20dc8c9d90
19 changed files with 436 additions and 89 deletions
|
|
@ -0,0 +1,20 @@
|
|||
package com.tangem.features.staking.impl.presentation.state
|
||||
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import java.math.BigDecimal
|
||||
|
||||
sealed class FeeState {
|
||||
|
||||
data class Content(
|
||||
val fee: Fee?,
|
||||
val rate: BigDecimal?,
|
||||
val isFeeConvertibleToFiat: Boolean,
|
||||
val appCurrency: AppCurrency,
|
||||
val isFeeApproximate: Boolean,
|
||||
) : FeeState()
|
||||
|
||||
data object Loading : FeeState()
|
||||
|
||||
data object Error : FeeState()
|
||||
}
|
||||
|
|
@ -1,9 +1,7 @@
|
|||
package com.tangem.features.staking.impl.presentation.state
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
|
||||
@Immutable
|
||||
internal sealed class InnerFeeState {
|
||||
|
||||
data class Content(
|
||||
|
|
|
|||
|
|
@ -7,22 +7,20 @@ internal class StakingStateRouter(
|
|||
private val fragmentManager: WeakReference<FragmentManager>,
|
||||
private val stateController: StakingStateController,
|
||||
) {
|
||||
fun clear() {
|
||||
stateController.update { it.copy(currentStep = getInitialState()) }
|
||||
}
|
||||
|
||||
fun popBackStack() {
|
||||
private fun closeStaking() {
|
||||
fragmentManager.get()?.popBackStack()
|
||||
stateController.clear()
|
||||
}
|
||||
|
||||
fun onBackClick(isSuccess: Boolean = false) {
|
||||
val type = stateController.uiState.value.currentStep
|
||||
when {
|
||||
isSuccess -> popBackStack()
|
||||
isSuccess -> closeStaking()
|
||||
else -> when (type) {
|
||||
StakingStep.Amount -> showInitial()
|
||||
StakingStep.Confirm -> showAmount()
|
||||
else -> popBackStack()
|
||||
else -> closeStaking()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -34,14 +32,17 @@ internal class StakingStateRouter(
|
|||
StakingStep.Amount,
|
||||
-> showConfirm()
|
||||
StakingStep.Confirm -> showSuccess()
|
||||
StakingStep.Success -> onBackClick()
|
||||
StakingStep.Success -> closeStaking()
|
||||
}
|
||||
}
|
||||
|
||||
fun onPrevClick() {
|
||||
when (stateController.uiState.value.currentStep) {
|
||||
StakingStep.Amount -> showInitial()
|
||||
else -> popBackStack()
|
||||
StakingStep.Confirm -> showAmount()
|
||||
StakingStep.Success -> closeStaking()
|
||||
StakingStep.Validators -> showConfirm()
|
||||
else -> closeStaking()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -64,6 +65,4 @@ internal class StakingStateRouter(
|
|||
fun showSuccess() {
|
||||
stateController.update { it.copy(currentStep = StakingStep.Success) }
|
||||
}
|
||||
|
||||
private fun getInitialState() = StakingStep.InitialInfo
|
||||
}
|
||||
|
|
@ -1,16 +1,13 @@
|
|||
package com.tangem.features.staking.impl.presentation.state
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.event.StateEvent
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.InfoType
|
||||
import com.tangem.features.staking.impl.presentation.viewmodel.StakingClickIntents
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
* Ui states of the staking screen
|
||||
|
|
@ -79,21 +76,12 @@ internal sealed class StakingStates {
|
|||
override val isPrimaryButtonEnabled: Boolean = false,
|
||||
) : ConfirmStakingState()
|
||||
}
|
||||
|
||||
data class FeeState(
|
||||
val innerFeeState: InnerFeeState,
|
||||
val fee: Fee?,
|
||||
val rate: BigDecimal?,
|
||||
val isFeeConvertibleToFiat: Boolean,
|
||||
val appCurrency: AppCurrency,
|
||||
val isFeeApproximate: Boolean,
|
||||
)
|
||||
}
|
||||
|
||||
enum class StakingStep {
|
||||
InitialInfo,
|
||||
Amount,
|
||||
Validators,
|
||||
Confirm,
|
||||
Validators,
|
||||
Success,
|
||||
}
|
||||
|
|
@ -3,10 +3,9 @@ package com.tangem.features.staking.impl.presentation.state.previewdata
|
|||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.AmountType.Coin
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.staking.model.Yield
|
||||
import com.tangem.features.staking.impl.presentation.state.InnerFeeState
|
||||
import com.tangem.features.staking.impl.presentation.state.*
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingNotification
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStates
|
||||
import com.tangem.features.staking.impl.presentation.state.ValidatorState
|
||||
|
|
@ -65,8 +64,7 @@ internal object ConfirmStakingStatePreviewData {
|
|||
|
||||
val confirmStakingState = StakingStates.ConfirmStakingState.Data(
|
||||
isPrimaryButtonEnabled = true,
|
||||
feeState = StakingStates.FeeState(
|
||||
innerFeeState = InnerFeeState.Content(TransactionFee.Single(fee)),
|
||||
feeState = FeeState.Content(
|
||||
fee = fee,
|
||||
rate = BigDecimal.ONE,
|
||||
appCurrency = AppCurrency.Default,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
package com.tangem.features.staking.impl.presentation.state.transformers
|
||||
|
||||
import com.tangem.domain.staking.model.Yield
|
||||
import com.tangem.features.staking.impl.presentation.state.*
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingNotification
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStates
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingUiState
|
||||
import com.tangem.features.staking.impl.presentation.state.ValidatorState
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
@Suppress("UnusedPrivateMember")
|
||||
internal class SetConfirmLoadingStateTransformer(
|
||||
private val yield: Yield,
|
||||
) : Transformer<StakingUiState> {
|
||||
|
||||
override fun transform(prevState: StakingUiState): StakingUiState {
|
||||
val possibleConfirmStakingState = prevState.confirmStakingState as? StakingStates.ConfirmStakingState.Data
|
||||
val possibleValidatorState = possibleConfirmStakingState?.validatorState as? ValidatorState.Content
|
||||
val chosenValidator = possibleValidatorState?.chosenValidator ?: yield.validators[0] // TODO staking add sorting
|
||||
|
||||
return prevState.copy(
|
||||
confirmStakingState = StakingStates.ConfirmStakingState.Data(
|
||||
isPrimaryButtonEnabled = false,
|
||||
feeState = FeeState.Loading,
|
||||
validatorState = ValidatorState.Content(
|
||||
chosenValidator = chosenValidator,
|
||||
availableValidators = yield.validators,
|
||||
),
|
||||
notifications = persistentListOf(
|
||||
StakingNotification.Warning.EarnRewards(
|
||||
currencyName = yield.token.name,
|
||||
days = yield.metadata.cooldownPeriod.days,
|
||||
),
|
||||
),
|
||||
footerText = "",
|
||||
isSuccess = false,
|
||||
isStaking = false, // TODO staking move to enum
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,34 +2,49 @@ package com.tangem.features.staking.impl.presentation.state.transformers
|
|||
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.staking.model.Yield
|
||||
import com.tangem.domain.staking.model.transaction.StakingGasEstimate
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.transaction.usecase.IsFeeApproximateUseCase
|
||||
import com.tangem.features.staking.impl.presentation.state.FeeState
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStates
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingUiState
|
||||
import com.tangem.features.staking.impl.presentation.state.previewdata.ConfirmStakingStatePreviewData
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
import com.tangem.blockchain.common.Amount
|
||||
|
||||
@Suppress("UnusedPrivateMember")
|
||||
internal class SetConfirmStateDataStateTransformer(
|
||||
private val yield: Yield,
|
||||
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||
private val isFeeApproximateUseCase: IsFeeApproximateUseCase,
|
||||
private val stakingGasEstimate: StakingGasEstimate,
|
||||
) : Transformer<StakingUiState> {
|
||||
|
||||
override fun transform(prevState: StakingUiState): StakingUiState {
|
||||
// TODO staking fill with real data
|
||||
return prevState.copy(
|
||||
confirmStakingState = ConfirmStakingStatePreviewData.confirmStakingState,
|
||||
confirmStakingState = prevState.confirmStakingState.copyWrapped(stakingGasEstimate),
|
||||
)
|
||||
}
|
||||
|
||||
private fun isFeeApproximate(fee: Fee): Boolean {
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
return isFeeApproximateUseCase(
|
||||
networkId = cryptoCurrencyStatus.currency.network.id,
|
||||
amountType = fee.amount.type,
|
||||
)
|
||||
private fun StakingStates.ConfirmStakingState.copyWrapped(
|
||||
gasEstimate: StakingGasEstimate,
|
||||
): StakingStates.ConfirmStakingState {
|
||||
if (this is StakingStates.ConfirmStakingState.Data) {
|
||||
return copy(
|
||||
feeState = FeeState.Content(
|
||||
fee = Fee.Common(
|
||||
Amount(
|
||||
currencySymbol = gasEstimate.token.symbol,
|
||||
value = gasEstimate.amount,
|
||||
decimals = gasEstimate.token.decimals,
|
||||
),
|
||||
),
|
||||
rate = cryptoCurrencyStatusProvider().value.fiatRate,
|
||||
isFeeConvertibleToFiat = cryptoCurrencyStatusProvider().currency.network.hasFiatFeeRate,
|
||||
appCurrency = appCurrencyProvider(),
|
||||
isFeeApproximate = false,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
return this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -116,8 +116,8 @@ private fun isButtonEnabled(uiState: StakingUiState): Boolean {
|
|||
return when (uiState.currentStep) {
|
||||
StakingStep.InitialInfo -> uiState.initialInfoState.isPrimaryButtonEnabled
|
||||
StakingStep.Amount -> uiState.amountState.isPrimaryButtonEnabled
|
||||
StakingStep.Validators -> uiState.confirmStakingState.isPrimaryButtonEnabled
|
||||
StakingStep.Confirm -> uiState.confirmStakingState.isPrimaryButtonEnabled
|
||||
StakingStep.Success -> true
|
||||
StakingStep.Validators -> true
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,6 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
|||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.AmountType
|
||||
import com.tangem.blockchain.common.transaction.Fee
|
||||
import com.tangem.blockchain.common.transaction.TransactionFee
|
||||
import com.tangem.core.ui.components.RectangleShimmer
|
||||
import com.tangem.core.ui.components.rows.SelectorRowItem
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
|
|
@ -26,12 +25,11 @@ import com.tangem.common.ui.R
|
|||
import com.tangem.common.ui.amountScreen.utils.getCryptoReference
|
||||
import com.tangem.common.ui.amountScreen.utils.getFiatReference
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.features.staking.impl.presentation.state.InnerFeeState
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStates
|
||||
import com.tangem.features.staking.impl.presentation.state.FeeState
|
||||
import java.math.BigDecimal
|
||||
|
||||
@Composable
|
||||
internal fun StakingFeeBlock(feeState: StakingStates.FeeState) {
|
||||
internal fun StakingFeeBlock(feeState: FeeState) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
|
|
@ -48,37 +46,45 @@ internal fun StakingFeeBlock(feeState: StakingStates.FeeState) {
|
|||
Box(
|
||||
modifier = Modifier.padding(top = TangemTheme.dimens.spacing8),
|
||||
) {
|
||||
val feeAmount = feeState.fee?.amount
|
||||
val (title, icon) = R.string.common_fee_selector_option_market to R.drawable.ic_bird_24
|
||||
SelectorRowItem(
|
||||
titleRes = title,
|
||||
iconRes = icon,
|
||||
preDot = getCryptoReference(feeAmount, feeState.isFeeApproximate),
|
||||
postDot = if (feeState.isFeeConvertibleToFiat) {
|
||||
getFiatReference(feeAmount?.value, feeState.rate, feeState.appCurrency)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
ellipsizeOffset = feeAmount?.currencySymbol?.length,
|
||||
isSelected = true,
|
||||
showDivider = false,
|
||||
showSelectedAppearance = false,
|
||||
paddingValues = PaddingValues(),
|
||||
)
|
||||
FeeLoading(feeState.innerFeeState)
|
||||
FeeError(feeState.innerFeeState)
|
||||
when (feeState) {
|
||||
is FeeState.Content -> {
|
||||
val feeAmount = feeState.fee?.amount
|
||||
val (title, icon) = R.string.common_fee_selector_option_market to R.drawable.ic_bird_24
|
||||
SelectorRowItem(
|
||||
titleRes = title,
|
||||
iconRes = icon,
|
||||
preDot = getCryptoReference(feeAmount, feeState.isFeeApproximate),
|
||||
postDot = if (feeState.isFeeConvertibleToFiat) {
|
||||
getFiatReference(feeAmount?.value, feeState.rate, feeState.appCurrency)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
ellipsizeOffset = feeAmount?.currencySymbol?.length,
|
||||
isSelected = true,
|
||||
showDivider = false,
|
||||
showSelectedAppearance = false,
|
||||
paddingValues = PaddingValues(),
|
||||
)
|
||||
}
|
||||
is FeeState.Loading -> {
|
||||
FeeLoading(feeState)
|
||||
}
|
||||
is FeeState.Error -> {
|
||||
FeeError(feeState)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BoxScope.FeeLoading(feeSelectorState: InnerFeeState) {
|
||||
private fun BoxScope.FeeLoading(feeState: FeeState) {
|
||||
AnimatedContent(
|
||||
targetState = feeSelectorState,
|
||||
targetState = feeState,
|
||||
label = "Fee Loading State Change",
|
||||
modifier = Modifier.align(Alignment.CenterEnd),
|
||||
) {
|
||||
if (it == InnerFeeState.Loading) {
|
||||
if (it == FeeState.Loading) {
|
||||
RectangleShimmer(
|
||||
radius = TangemTheme.dimens.radius3,
|
||||
modifier = Modifier.size(
|
||||
|
|
@ -91,13 +97,13 @@ private fun BoxScope.FeeLoading(feeSelectorState: InnerFeeState) {
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun BoxScope.FeeError(feeSelectorState: InnerFeeState) {
|
||||
private fun BoxScope.FeeError(feeState: FeeState) {
|
||||
AnimatedContent(
|
||||
targetState = feeSelectorState,
|
||||
targetState = feeState,
|
||||
label = "Fee Error State Change",
|
||||
modifier = Modifier.align(Alignment.CenterEnd),
|
||||
) {
|
||||
if (it == InnerFeeState.Error) {
|
||||
if (it == FeeState.Error) {
|
||||
Text(
|
||||
text = BigDecimalFormatter.EMPTY_BALANCE_SIGN,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
|
|
@ -111,7 +117,7 @@ private fun BoxScope.FeeError(feeSelectorState: InnerFeeState) {
|
|||
@Preview
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun FeeBlockPreview(@PreviewParameter(FeeBlockPreviewProvider::class) value: StakingStates.FeeState) {
|
||||
private fun FeeBlockPreview(@PreviewParameter(FeeBlockPreviewProvider::class) value: FeeState.Content) {
|
||||
TangemThemePreview {
|
||||
StakingFeeBlock(
|
||||
feeState = value,
|
||||
|
|
@ -119,9 +125,9 @@ private fun FeeBlockPreview(@PreviewParameter(FeeBlockPreviewProvider::class) va
|
|||
}
|
||||
}
|
||||
|
||||
private class FeeBlockPreviewProvider : PreviewParameterProvider<StakingStates.FeeState> {
|
||||
private class FeeBlockPreviewProvider : PreviewParameterProvider<FeeState.Content> {
|
||||
|
||||
override val values: Sequence<StakingStates.FeeState>
|
||||
override val values: Sequence<FeeState.Content>
|
||||
get() = sequenceOf(
|
||||
feeState,
|
||||
)
|
||||
|
|
@ -135,8 +141,7 @@ private class FeeBlockPreviewProvider : PreviewParameterProvider<StakingStates.F
|
|||
),
|
||||
)
|
||||
|
||||
private val feeState = StakingStates.FeeState(
|
||||
innerFeeState = InnerFeeState.Content(TransactionFee.Single(normal = fee)),
|
||||
private val feeState = FeeState.Content(
|
||||
fee = fee,
|
||||
rate = BigDecimal.ONE,
|
||||
appCurrency = AppCurrency.Default,
|
||||
|
|
|
|||
|
|
@ -8,9 +8,11 @@ import androidx.lifecycle.viewModelScope
|
|||
import arrow.core.getOrElse
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.routing.bundle.unbundle
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.staking.InitializeStakingProcessUseCase
|
||||
import com.tangem.domain.staking.model.Yield
|
||||
import com.tangem.domain.tokens.GetCryptoCurrencyStatusSyncUseCase
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
|
|
@ -21,6 +23,7 @@ import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
|||
import com.tangem.features.staking.impl.navigation.InnerStakingRouter
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStateController
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStateRouter
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingStep
|
||||
import com.tangem.features.staking.impl.presentation.state.StakingUiState
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.*
|
||||
import com.tangem.features.staking.impl.presentation.state.transformers.amount.AmountChangeStateTransformer
|
||||
|
|
@ -45,6 +48,7 @@ internal class StakingViewModel @Inject constructor(
|
|||
private val getCryptoCurrencyStatusSyncUseCase: GetCryptoCurrencyStatusSyncUseCase,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val initializeStakingProcessUseCase: InitializeStakingProcessUseCase,
|
||||
savedStateHandle: SavedStateHandle,
|
||||
) : ViewModel(), DefaultLifecycleObserver, StakingClickIntents {
|
||||
|
||||
|
|
@ -85,10 +89,60 @@ internal class StakingViewModel @Inject constructor(
|
|||
|
||||
override fun onNextClick() {
|
||||
stakingStateRouter.onNextClick()
|
||||
when (value.currentStep) {
|
||||
StakingStep.Confirm -> {
|
||||
initStaking()
|
||||
}
|
||||
StakingStep.InitialInfo -> {
|
||||
// TODO staking
|
||||
}
|
||||
StakingStep.Amount -> {
|
||||
// TODO staking
|
||||
}
|
||||
StakingStep.Success -> {
|
||||
// TODO staking
|
||||
}
|
||||
StakingStep.Validators -> {
|
||||
// TODO staking
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initStaking() {
|
||||
viewModelScope.launch {
|
||||
stateController.update(
|
||||
SetConfirmLoadingStateTransformer(
|
||||
yield = yield,
|
||||
),
|
||||
)
|
||||
|
||||
val actionWithTransaction = initializeStakingProcessUseCase(
|
||||
integrationId = yield.id,
|
||||
amount = (value.amountState as? AmountState.Data)?.amountTextField?.cryptoAmount?.value
|
||||
?: error("No amount provided"),
|
||||
address = cryptoCurrencyStatus.value.networkAddress?.defaultAddress?.value
|
||||
?: error("No available address"),
|
||||
validatorAddress = yield.validators.getOrNull(0)?.address ?: error("No available validator"),
|
||||
token = yield.token,
|
||||
)
|
||||
val (enterAction, stakingTransaction) = actionWithTransaction.getOrElse {
|
||||
error("Can't retrieve action and transaction")
|
||||
}
|
||||
|
||||
val stakingGasEstimate = stakingTransaction.gasEstimate ?: error("Can't get fee info")
|
||||
|
||||
stateController.update(
|
||||
SetConfirmStateDataStateTransformer(
|
||||
appCurrencyProvider = Provider { appCurrency },
|
||||
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
|
||||
stakingGasEstimate = stakingGasEstimate,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPrevClick() {
|
||||
stakingStateRouter.onBackClick()
|
||||
stakingStateRouter.onPrevClick()
|
||||
}
|
||||
|
||||
override fun onInfoClick(infoType: InfoType) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue