Updated on 2026-08-14

This commit is contained in:
Tangem 2025-08-07 16:05:37 +05:00
parent 34f07ed52d
commit 2336cb6aaa
8 changed files with 61 additions and 3 deletions

View file

@ -6,7 +6,6 @@ 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.activate
import com.arkivanov.decompose.router.slot.childSlot
import com.arkivanov.decompose.router.slot.dismiss
import com.tangem.core.decompose.context.AppComponentContext
@ -50,6 +49,7 @@ internal class DefaultFeeSelectorBlockComponent @AssistedInject constructor(
callback = model,
feeStateConfiguration = params.feeStateConfiguration,
feeDisplaySource = FeeSelectorParams.FeeDisplaySource.Screen,
analyticsCategoryName = params.analyticsCategoryName,
),
onDismiss = {
model.feeSelectorBottomSheet.dismiss()
@ -79,7 +79,7 @@ internal class DefaultFeeSelectorBlockComponent @AssistedInject constructor(
modifier = modifier
.conditional(params.feeDisplaySource == FeeSelectorParams.FeeDisplaySource.Screen) {
Modifier.clickable {
model.feeSelectorBottomSheet.activate(Unit)
model.showFeeSelector()
}
},
)

View file

@ -3,8 +3,10 @@ package com.tangem.features.send.v2.feeselector.model
import androidx.compose.runtime.Stable
import arrow.core.getOrElse
import com.arkivanov.decompose.router.slot.SlotNavigation
import com.arkivanov.decompose.router.slot.activate
import com.arkivanov.decompose.router.slot.dismiss
import com.tangem.blockchain.common.AmountType
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
@ -12,13 +14,19 @@ import com.tangem.core.navigation.url.UrlOpener
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.transaction.usecase.IsFeeApproximateUseCase
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents.NonceInserted
import com.tangem.features.send.v2.api.analytics.CommonSendAnalyticEvents.SendScreenSource
import com.tangem.features.send.v2.api.callbacks.FeeSelectorModelCallback
import com.tangem.features.send.v2.api.entity.FeeItem
import com.tangem.features.send.v2.api.entity.FeeNonce
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.features.send.v2.api.params.FeeSelectorParams
import com.tangem.features.send.v2.api.subcomponents.feeSelector.FeeSelectorCheckReloadListener
import com.tangem.features.send.v2.api.subcomponents.feeSelector.FeeSelectorCheckReloadTrigger
import com.tangem.features.send.v2.api.subcomponents.feeSelector.FeeSelectorReloadListener
import com.tangem.features.send.v2.api.subcomponents.feeSelector.analytics.CommonSendFeeAnalyticEvents
import com.tangem.features.send.v2.api.subcomponents.feeSelector.analytics.CommonSendFeeAnalyticEvents.GasPriceInserter
import com.tangem.features.send.v2.feeselector.model.transformers.*
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.transformer.update
@ -43,6 +51,7 @@ internal class FeeSelectorModel @Inject constructor(
private val feeSelectorCheckReloadTrigger: FeeSelectorCheckReloadTrigger,
private val feeSelectorAlertFactory: FeeSelectorAlertFactory,
override val dispatchers: CoroutineDispatcherProvider,
private val analyticsEventHandler: AnalyticsEventHandler,
) : Model(), FeeSelectorIntents, FeeSelectorModelCallback {
private val params = paramsContainer.require<FeeSelectorParams>()
@ -112,6 +121,11 @@ internal class FeeSelectorModel @Inject constructor(
}
override fun onFeeItemSelected(feeItem: FeeItem) {
if (feeItem is FeeItem.Custom) {
analyticsEventHandler.send(
CommonSendFeeAnalyticEvents.CustomFeeButtonClicked(categoryName = params.analyticsCategoryName),
)
}
uiState.update(FeeItemSelectedTransformer(feeItem))
}
@ -132,6 +146,27 @@ internal class FeeSelectorModel @Inject constructor(
}
override fun onDoneClick() {
val feeSelectorUM = uiState.value as? FeeSelectorUM.Content ?: return
analyticsEventHandler.send(
CommonSendFeeAnalyticEvents.SelectedFee(
categoryName = params.analyticsCategoryName,
feeType = feeSelectorUM.toAnalyticType(),
),
)
val isCustomFeeEdited = feeSelectorUM.selectedFeeItem.fee.amount.value != feeSelectorUM.fees.normal.amount.value
if (feeSelectorUM.selectedFeeItem is FeeItem.Custom && isCustomFeeEdited) {
analyticsEventHandler.send(GasPriceInserter(categoryName = params.analyticsCategoryName))
}
if (feeSelectorUM.feeNonce is FeeNonce.Nonce) {
analyticsEventHandler.send(
NonceInserted(
categoryName = params.analyticsCategoryName,
token = params.feeCryptoCurrencyStatus.currency.symbol,
blockchain = params.feeCryptoCurrencyStatus.currency.network.name,
),
)
}
(params as? FeeSelectorParams.FeeSelectorDetailsParams)?.callback?.onFeeResult(uiState.value)
}
@ -140,6 +175,19 @@ internal class FeeSelectorModel @Inject constructor(
feeSelectorBottomSheet.dismiss()
}
fun showFeeSelector() {
analyticsEventHandler.send(
CommonSendAnalyticEvents.FeeScreenOpened(categoryName = params.analyticsCategoryName),
)
analyticsEventHandler.send(
CommonSendAnalyticEvents.ScreenReopened(
categoryName = params.analyticsCategoryName,
source = SendScreenSource.Fee,
),
)
feeSelectorBottomSheet.activate(Unit)
}
private fun subscribeOnFeeReloadTriggerUpdates() {
feeSelectorReloadListener.reloadTriggerFlow
.onEach { data ->

View file

@ -104,6 +104,7 @@ internal class SendConfirmComponent(
cryptoCurrencyStatus = params.cryptoCurrencyStatus,
feeStateConfiguration = model.feeStateConfiguration,
feeDisplaySource = FeeSelectorParams.FeeDisplaySource.Screen,
analyticsCategoryName = params.analyticsCategoryName,
),
onResult = model::onFeeResult,
)