Updated on 2026-08-14

This commit is contained in:
Tangem 2026-05-19 20:42:17 +05:00
parent babb461145
commit 92802e6968
9 changed files with 62 additions and 19 deletions

View file

@ -38,6 +38,10 @@ sealed class MainScreenAnalyticsEvent(
event = "Button - Receive",
)
class ButtonAddFunds : MainScreenAnalyticsEvent(
event = "Button - Add Funds",
)
class LimitsClicked : MainScreenAnalyticsEvent(
event = "Limits Clicked",
)

View file

@ -22,7 +22,6 @@ import com.tangem.features.commonfeatures.api.choosetoken.ChooseTokenComponent
import com.tangem.features.commonfeatures.impl.R
import com.tangem.features.commonfeatures.impl.addfunds.model.AddFundsModel
import com.tangem.features.commonfeatures.impl.addtoportfolio.TokenActionsComponent
import com.tangem.features.commonfeatures.impl.addtoportfolio.analytics.PortfolioAnalyticsEvent
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@ -44,11 +43,6 @@ internal class DefaultAddFundsComponent @AssistedInject constructor(
private val tokenActionsComponent: TokenActionsComponent = tokenActionsComponentFactory.create(
context = child(key = "addFundsTokenActions"),
params = TokenActionsComponent.Params(
eventBuilder = PortfolioAnalyticsEvent.EventBuilder(
tokenSymbol = "",
source = ANALYTICS_SOURCE,
category = ANALYTICS_CATEGORY,
),
data = model.tokenActionsData,
callbacks = model,
bottomAction = TokenActionsComponent.BottomAction.GoToToken,
@ -100,9 +94,4 @@ internal class DefaultAddFundsComponent @AssistedInject constructor(
interface Factory : AddFundsComponent.Factory {
override fun create(context: AppComponentContext, params: AddFundsComponent.Params): DefaultAddFundsComponent
}
private companion object {
const val ANALYTICS_SOURCE = "AddFunds"
const val ANALYTICS_CATEGORY = "Add Funds"
}
}

View file

@ -0,0 +1,28 @@
package com.tangem.features.commonfeatures.impl.addfunds.analytics
import com.tangem.core.analytics.models.AnalyticsEvent
import com.tangem.core.analytics.models.AnalyticsParam
internal sealed class AddFundsAnalyticsEvent(
event: String,
params: Map<String, String> = emptyMap(),
) : AnalyticsEvent(category = CATEGORY, event = event, params = params) {
class MethodScreenOpened(source: String) : AddFundsAnalyticsEvent(
event = "Method Screen Opened",
params = mapOf(AnalyticsParam.SOURCE to source),
)
class ButtonBuy : AddFundsAnalyticsEvent(event = "Button - Buy")
class ButtonSwap : AddFundsAnalyticsEvent(event = "Button - Swap")
class ButtonReceive : AddFundsAnalyticsEvent(event = "Button - Receive")
class ButtonGoToToken : AddFundsAnalyticsEvent(event = "Button - Go to Token")
companion object {
private const val CATEGORY = "Add Funds"
const val SOURCE_MAIN_SCREEN = "Main Screen"
}
}

View file

@ -3,6 +3,8 @@ package com.tangem.features.commonfeatures.impl.addfunds.model
import com.tangem.common.routing.AppRoute
import com.tangem.common.routing.AppRouter
import com.tangem.common.ui.markets.action.CryptoCurrencyData
import com.tangem.common.ui.markets.action.TokenActionsBSContentUM
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,6 +14,7 @@ import com.tangem.features.commonfeatures.api.addfunds.AddFundsComponent
import com.tangem.features.commonfeatures.api.choosetoken.ChooseTokenAnalyticsPayload
import com.tangem.features.commonfeatures.api.choosetoken.ChooseTokenBridge
import com.tangem.features.commonfeatures.api.choosetoken.ChooseTokenResult
import com.tangem.features.commonfeatures.impl.addfunds.analytics.AddFundsAnalyticsEvent
import com.tangem.features.commonfeatures.impl.addtoportfolio.TokenActionsComponent
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.ExperimentalCoroutinesApi
@ -25,6 +28,7 @@ internal class AddFundsModel @Inject constructor(
chooseTokenBridgeFactory: ChooseTokenBridge.Factory,
private val getCryptoCurrencyActionsUseCase: GetCryptoCurrencyActionsUseCaseV2,
private val appRouter: AppRouter,
private val analyticsEventHandler: AnalyticsEventHandler,
override val dispatchers: CoroutineDispatcherProvider,
) : Model(), TokenActionsComponent.Callbacks {
@ -66,12 +70,16 @@ internal class AddFundsModel @Inject constructor(
init {
chooseTokenBridge.selectWalletTab(params.userWalletId)
analyticsEventHandler.send(
AddFundsAnalyticsEvent.MethodScreenOpened(source = AddFundsAnalyticsEvent.SOURCE_MAIN_SCREEN),
)
observeBridge()
}
override fun onBottomActionClick() {
val result = selectedToken.value ?: return
selectedToken.value = null
analyticsEventHandler.send(AddFundsAnalyticsEvent.ButtonGoToToken())
appRouter.replaceCurrent(
AppRoute.CurrencyDetails(
userWalletId = result.wallet.walletId,
@ -80,6 +88,16 @@ internal class AddFundsModel @Inject constructor(
)
}
override fun onQuickActionClick(action: TokenActionsBSContentUM.Action) {
val event = when (action) {
TokenActionsBSContentUM.Action.Buy -> AddFundsAnalyticsEvent.ButtonBuy()
TokenActionsBSContentUM.Action.Exchange -> AddFundsAnalyticsEvent.ButtonSwap()
TokenActionsBSContentUM.Action.Receive -> AddFundsAnalyticsEvent.ButtonReceive()
else -> return
}
analyticsEventHandler.send(event)
}
fun onTokenActionsDismiss() {
selectedToken.value = null
}

View file

@ -58,7 +58,6 @@ internal class DefaultAddToPortfolioComponent @AssistedInject constructor(
tokenActionsComponentFactory.create(
context = child("tokenActionsComponent"),
params = TokenActionsComponent.Params(
eventBuilder = model.eventBuilder,
callbacks = model,
data = model.tokenActionsData,
),

View file

@ -9,6 +9,7 @@ import com.arkivanov.decompose.extensions.compose.subscribeAsState
import com.arkivanov.decompose.router.slot.childSlot
import com.arkivanov.decompose.router.slot.dismiss
import com.tangem.common.ui.markets.action.CryptoCurrencyData
import com.tangem.common.ui.markets.action.TokenActionsBSContentUM
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.context.childByContext
import com.tangem.core.decompose.factory.ComponentFactory
@ -17,7 +18,6 @@ import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.core.ui.res.LocalRedesignEnabled
import com.tangem.domain.models.TokenReceiveConfig
import com.tangem.features.commonfeatures.impl.addtoportfolio.analytics.PortfolioAnalyticsEvent
import com.tangem.features.commonfeatures.impl.addtoportfolio.model.TokenActionsModel
import com.tangem.features.commonfeatures.impl.addtoportfolio.ui.TokenActionsContent
import com.tangem.features.commonfeatures.impl.addtoportfolio.ui.TokenActionsContentV2
@ -72,7 +72,6 @@ internal class TokenActionsComponent @AssistedInject constructor(
)
data class Params(
val eventBuilder: PortfolioAnalyticsEvent.EventBuilder,
val data: Flow<CryptoCurrencyData>,
val callbacks: Callbacks,
val bottomAction: BottomAction = BottomAction.Later,
@ -83,6 +82,7 @@ internal class TokenActionsComponent @AssistedInject constructor(
interface Callbacks {
fun onBottomActionClick()
fun onQuickActionClick(action: TokenActionsBSContentUM.Action) {}
}
@AssistedFactory

View file

@ -7,6 +7,7 @@ import com.arkivanov.decompose.router.stack.replaceAll
import com.tangem.blockchainsdk.compatibility.getTokenIdIfL2Network
import com.tangem.common.ui.markets.action.CryptoCurrencyData
import com.tangem.common.ui.markets.action.QuickActionsConverter.toQuickActions
import com.tangem.common.ui.markets.action.TokenActionsBSContentUM
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
@ -106,6 +107,10 @@ internal class AddToPortfolioModel @Inject constructor(
startRedesignAddToPortfolioFlow()
}
override fun onQuickActionClick(action: TokenActionsBSContentUM.Action) {
analyticsEventHandler.send(eventBuilder.getTokenActionClick(actionUM = action))
}
private fun <T> replayMutableSharedFlow() = MutableSharedFlow<T>(
replay = 1,
onBufferOverflow = BufferOverflow.DROP_OLDEST,

View file

@ -4,7 +4,6 @@ import com.arkivanov.decompose.router.slot.SlotNavigation
import com.arkivanov.decompose.router.slot.activate
import com.tangem.common.ui.markets.action.TokenActionsBSContentUM
import com.tangem.common.ui.markets.action.TokenActionsHandler
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
@ -31,12 +30,10 @@ internal class TokenActionsModel @Inject constructor(
tokenActionsIntentsFactory: TokenActionsHandler.Factory,
override val dispatchers: CoroutineDispatcherProvider,
private val uiBuilder: TokenActionsUiBuilder,
private val analyticsEventHandler: AnalyticsEventHandler,
private val receiveAddressesFactory: ReceiveAddressesFactory,
) : Model() {
private val params = paramsContainer.require<TokenActionsComponent.Params>()
private val analyticsEventBuilder get() = params.eventBuilder
private val currentAppCurrency = getSelectedAppCurrencyUseCase.invokeOrDefault()
.stateIn(
scope = modelScope,
@ -76,8 +73,7 @@ internal class TokenActionsModel @Inject constructor(
)
private fun handledQuickAction(handledAction: TokenActionsHandler.HandledQuickAction) = modelScope.launch {
val event = analyticsEventBuilder.getTokenActionClick(actionUM = handledAction.action)
analyticsEventHandler.send(event)
params.callbacks.onQuickActionClick(handledAction.action)
val isReceive = handledAction.action == TokenActionsBSContentUM.Action.Receive
if (!isReceive) return@launch
modelScope.launch(dispatchers.default) {

View file

@ -1,5 +1,7 @@
package com.tangem.feature.wallet.child.wallet.model.intents
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.analytics.models.event.MainScreenAnalyticsEvent
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.ui.DesignFeatureToggles
import com.tangem.domain.exchange.RampStateManager
@ -45,6 +47,7 @@ internal class WalletClickIntents @Inject constructor(
private val tangemPayIntents: TangemPayClickIntentsImplementor,
private val yieldSupplyApyUpdateUseCase: YieldSupplyApyUpdateUseCase,
private val designFeatureToggles: DesignFeatureToggles,
private val analyticsEventHandler: AnalyticsEventHandler,
) : BaseWalletClickIntents(),
WalletCardClickIntents by walletCardClickIntentsImplementor,
WalletWarningsClickIntents by warningsClickIntentsImplementer,
@ -116,6 +119,7 @@ internal class WalletClickIntents @Inject constructor(
}
fun onAddFundsClick(userWalletId: UserWalletId) {
analyticsEventHandler.send(MainScreenAnalyticsEvent.ButtonAddFunds())
router.openAddFunds(userWalletId)
}