Updated on 2026-08-14
This commit is contained in:
parent
910cea0e31
commit
676ed0f5f7
3 changed files with 96 additions and 10 deletions
|
|
@ -81,6 +81,10 @@ dependencies {
|
|||
/** Feature modules */
|
||||
implementation(projects.features.staking.api)
|
||||
implementation(projects.features.txhistory.api)
|
||||
implementation(projects.features.approval.api)
|
||||
|
||||
/** Decompose */
|
||||
implementation(deps.decompose.ext.compose)
|
||||
|
||||
/** DI */
|
||||
implementation(deps.hilt.android)
|
||||
|
|
|
|||
|
|
@ -4,8 +4,12 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.arkivanov.decompose.extensions.compose.subscribeAsState
|
||||
import com.arkivanov.decompose.router.slot.childSlot
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.context.childByContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.features.approval.api.GiveApprovalComponent
|
||||
import com.tangem.features.staking.api.StakingComponent
|
||||
import com.tangem.features.staking.impl.presentation.model.StakingModel
|
||||
import com.tangem.features.staking.impl.presentation.ui.StakingScreen
|
||||
|
|
@ -16,14 +20,34 @@ import dagger.assisted.AssistedInject
|
|||
internal class DefaultStakingComponent @AssistedInject constructor(
|
||||
@Assisted appComponentContext: AppComponentContext,
|
||||
@Assisted params: StakingComponent.Params,
|
||||
private val giveApprovalComponentFactory: GiveApprovalComponent.Factory,
|
||||
) : StakingComponent, AppComponentContext by appComponentContext {
|
||||
|
||||
private val model: StakingModel = getOrCreateModel(params)
|
||||
|
||||
private val approvalSlot = childSlot(
|
||||
key = "stakingApprovalSlot",
|
||||
source = model.approvalSlotNavigation,
|
||||
serializer = null,
|
||||
handleBackButton = true,
|
||||
childFactory = { _, factoryContext ->
|
||||
val approvalParams = model.getApprovalParams()
|
||||
?: error("Approval params are not available")
|
||||
giveApprovalComponentFactory.create(
|
||||
context = childByContext(factoryContext),
|
||||
params = approvalParams,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val currentState by model.uiState.collectAsStateWithLifecycle()
|
||||
val approvalSlotState by approvalSlot.subscribeAsState()
|
||||
|
||||
StakingScreen(currentState)
|
||||
|
||||
approvalSlotState.child?.instance?.BottomSheet()
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
|
|
|
|||
|
|
@ -10,8 +10,13 @@ import com.tangem.common.routing.AppRouter
|
|||
import com.tangem.common.ui.amountScreen.converters.AmountReduceByTransformer.ReduceByData
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
|
||||
import com.arkivanov.decompose.router.slot.SlotNavigation
|
||||
import com.arkivanov.decompose.router.slot.activate
|
||||
import com.arkivanov.decompose.router.slot.dismiss
|
||||
import com.tangem.common.ui.bottomsheet.permission.state.ApproveType
|
||||
import com.tangem.common.ui.bottomsheet.permission.state.GiveTxPermissionBottomSheetConfig
|
||||
import com.tangem.features.approval.api.GiveApprovalComponent
|
||||
import com.tangem.features.approval.api.GiveApprovalFeatureToggles
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.api.ParamsInterceptorHolder
|
||||
|
|
@ -22,6 +27,7 @@ import com.tangem.core.decompose.ui.UiMessageSender
|
|||
import com.tangem.core.navigation.share.ShareManager
|
||||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.core.ui.format.bigdecimal.crypto
|
||||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.core.ui.haptic.TangemHapticEffect
|
||||
|
|
@ -146,12 +152,15 @@ internal class StakingModel @Inject constructor(
|
|||
@DelayedWork private val coroutineScope: CoroutineScope,
|
||||
private val innerRouter: InnerStakingRouter,
|
||||
private val messageSender: UiMessageSender,
|
||||
private val giveApprovalFeatureToggles: GiveApprovalFeatureToggles,
|
||||
appRouter: AppRouter,
|
||||
) : Model(), StakingClickIntents {
|
||||
|
||||
val uiState: StateFlow<StakingUiState> = stateController.uiState
|
||||
val value: StakingUiState get() = uiState.value
|
||||
|
||||
val approvalSlotNavigation = SlotNavigation<Unit>()
|
||||
|
||||
private val params = paramsContainer.require<StakingComponent.Params>()
|
||||
|
||||
private val stakingStateRouter: StakingStateRouter = StakingStateRouter(
|
||||
|
|
@ -254,6 +263,31 @@ internal class StakingModel @Inject constructor(
|
|||
analyticsEventHandler = analyticsEventHandler,
|
||||
)
|
||||
|
||||
private val approvalCallback = object : GiveApprovalComponent.Callback {
|
||||
override fun onApproveClick() {
|
||||
}
|
||||
|
||||
override fun onApproveDone() {
|
||||
approvalSlotNavigation.dismiss()
|
||||
stakingAnalyticSender.sendTransactionApprovalAnalytics(
|
||||
cryptoCurrencyStatus.currency as? CryptoCurrency.Token ?: return,
|
||||
)
|
||||
stateController.update(SetApprovalInProgressTransformer)
|
||||
awaitForAllowance()
|
||||
}
|
||||
|
||||
override fun onApproveFailed() {
|
||||
approvalSlotNavigation.dismiss()
|
||||
stateController.update(
|
||||
SetConfirmationStateResetAssentTransformer(cryptoCurrencyStatus = cryptoCurrencyStatus),
|
||||
)
|
||||
}
|
||||
|
||||
override fun onCancelClick() {
|
||||
approvalSlotNavigation.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
private var stakingApproval: StakingApproval = StakingApproval.Empty
|
||||
private var stakingAllowance: BigDecimal = BigDecimal.ZERO
|
||||
private var isAmountSubtractAvailable: Boolean = false
|
||||
|
|
@ -748,16 +782,20 @@ internal class StakingModel @Inject constructor(
|
|||
}
|
||||
|
||||
override fun showApprovalBottomSheet() {
|
||||
stateController.update(
|
||||
ShowApprovalBottomSheetTransformer(
|
||||
userWallet = userWallet,
|
||||
appCurrencyProvider = Provider { appCurrency },
|
||||
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
|
||||
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
|
||||
) {
|
||||
stateController.update(DismissBottomSheetStateTransformer)
|
||||
},
|
||||
)
|
||||
if (giveApprovalFeatureToggles.isGaslessApprovalEnabled) {
|
||||
approvalSlotNavigation.activate(Unit)
|
||||
} else {
|
||||
stateController.update(
|
||||
ShowApprovalBottomSheetTransformer(
|
||||
userWallet = userWallet,
|
||||
appCurrencyProvider = Provider { appCurrency },
|
||||
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
|
||||
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
|
||||
) {
|
||||
stateController.update(DismissBottomSheetStateTransformer)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onApproveTypeChange(approveType: ApproveType) {
|
||||
|
|
@ -1439,6 +1477,26 @@ internal class StakingModel @Inject constructor(
|
|||
isTonHeatupCase
|
||||
}
|
||||
|
||||
fun getApprovalParams(): GiveApprovalComponent.Params? {
|
||||
val amountState = value.amountState as? AmountState.Data ?: return null
|
||||
val validatorState = value.validatorState as? StakingStates.ValidatorState.Data ?: return null
|
||||
val targetAddress = validatorState.chosenTarget.address
|
||||
val feeCurrencyStatus = feeCryptoCurrencyStatus ?: return null
|
||||
|
||||
return GiveApprovalComponent.Params(
|
||||
userWalletId = userWallet.walletId,
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
feeCryptoCurrencyStatus = feeCurrencyStatus,
|
||||
amount = amountState.amountTextField.value,
|
||||
spenderAddress = targetAddress,
|
||||
subtitle = resourceReference(
|
||||
id = R.string.give_permission_staking_subtitle,
|
||||
formatArgs = wrappedList(cryptoCurrencyStatus.currency.symbol),
|
||||
),
|
||||
callback = approvalCallback,
|
||||
)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val WHAT_IS_STAKING_ARTICLE_URL = "https://tangem.com/en/blog/post/how-to-stake-cryptocurrency/"
|
||||
const val ALLOWANCE_UPDATE_DELAY = 10_000L
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue