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

@ -15,7 +15,7 @@ import com.tangem.domain.walletconnect.model.sdkcopy.WcSdkSessionRequest
sealed class WcAnalyticEvents(
event: String,
params: Map<String, String> = mapOf(),
) : AnalyticsEvent(category = "Wallet Connect", event = event, params = params) {
) : AnalyticsEvent(category = WC_CATEGORY_NAME, event = event, params = params) {
object ScreenOpened : WcAnalyticEvents(event = "WC Screen Opened")
class NewPairInitiated(source: WcPairRequest.Source) : WcAnalyticEvents(
@ -228,5 +228,6 @@ sealed class WcAnalyticEvents(
companion object {
const val NETWORKS = "Networks"
const val DOMAIN_VERIFICATION = "Domain Verification"
const val WC_CATEGORY_NAME = "Wallet Connect"
}
}

View file

@ -16,6 +16,7 @@ sealed class FeeSelectorParams {
abstract val feeCryptoCurrencyStatus: CryptoCurrencyStatus
abstract val feeStateConfiguration: FeeStateConfiguration
abstract val feeDisplaySource: FeeDisplaySource
abstract val analyticsCategoryName: String
data class FeeSelectorBlockParams(
override val state: FeeSelectorUM,
@ -24,6 +25,7 @@ sealed class FeeSelectorParams {
override val feeCryptoCurrencyStatus: CryptoCurrencyStatus,
override val feeStateConfiguration: FeeStateConfiguration,
override val feeDisplaySource: FeeDisplaySource,
override val analyticsCategoryName: String,
) : FeeSelectorParams()
data class FeeSelectorDetailsParams(
@ -33,6 +35,7 @@ sealed class FeeSelectorParams {
override val feeCryptoCurrencyStatus: CryptoCurrencyStatus,
override val feeStateConfiguration: FeeStateConfiguration,
override val feeDisplaySource: FeeDisplaySource,
override val analyticsCategoryName: String,
val callback: FeeSelectorModelCallback,
) : FeeSelectorParams()

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,
)

View file

@ -89,6 +89,7 @@ internal class SendWithSwapConfirmComponent @AssistedInject constructor(
cryptoCurrencyStatus = model.primaryCurrencyStatus,
feeStateConfiguration = FeeStateConfiguration.ExcludeLow,
feeDisplaySource = FeeDisplaySource.Screen,
analyticsCategoryName = params.analyticsCategoryName,
),
onResult = model::onFeeResult,
)

View file

@ -2,6 +2,7 @@ package com.tangem.features.walletconnect.transaction.components.common
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.domain.walletconnect.WcAnalyticEvents
import com.tangem.features.send.v2.api.FeeSelectorComponent
import com.tangem.features.send.v2.api.params.FeeSelectorParams
import com.tangem.features.walletconnect.connections.components.AlertsComponentV2
@ -50,6 +51,7 @@ internal fun getWcCommonScreen(
callback = model,
feeStateConfiguration = model.feeStateConfiguration,
feeDisplaySource = FeeSelectorParams.FeeDisplaySource.BottomSheet,
analyticsCategoryName = WcAnalyticEvents.WC_CATEGORY_NAME,
),
)
}

View file

@ -6,6 +6,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.arkivanov.essenty.lifecycle.doOnResume
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.domain.walletconnect.WcAnalyticEvents
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.features.send.v2.api.params.FeeSelectorParams
@ -30,6 +31,7 @@ internal class WcSendTransactionComponent(
feeCryptoCurrencyStatus = model.cryptoCurrencyStatus,
feeStateConfiguration = model.feeStateConfiguration,
feeDisplaySource = FeeSelectorParams.FeeDisplaySource.BottomSheet,
analyticsCategoryName = WcAnalyticEvents.WC_CATEGORY_NAME,
),
onResult = model::updateFee,
)