Updated on 2026-08-14

This commit is contained in:
Tangem 2026-07-14 15:09:22 +04:00
parent 178417568b
commit a0c821eb8c
4 changed files with 97 additions and 52 deletions

View file

@ -7,6 +7,7 @@ import com.tangem.common.routing.AppRouter
import com.tangem.common.ui.markets.action.CryptoCurrencyData import com.tangem.common.ui.markets.action.CryptoCurrencyData
import com.tangem.common.ui.markets.action.TokenActionsBSContentUM import com.tangem.common.ui.markets.action.TokenActionsBSContentUM
import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.analytics.models.AnalyticsEvent
import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.event.TransferAnalyticsEvent import com.tangem.core.analytics.models.event.TransferAnalyticsEvent
import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.di.ModelScoped
@ -23,6 +24,7 @@ import com.tangem.domain.models.account.filterCryptoPortfolio
import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.tokens.model.analytics.TokenScreenAnalyticsEvent
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.features.commonfeatures.api.managefunds.ManageFundsComponent import com.tangem.features.commonfeatures.api.managefunds.ManageFundsComponent
import com.tangem.features.commonfeatures.api.addtoportfolio.AvailableToAddData import com.tangem.features.commonfeatures.api.addtoportfolio.AvailableToAddData
@ -153,12 +155,7 @@ internal class ManageFundsModel @Inject constructor(
override fun onQuickActionClick(action: TokenActionsBSContentUM.Action, shouldDismiss: Boolean) { override fun onQuickActionClick(action: TokenActionsBSContentUM.Action, shouldDismiss: Boolean) {
val event = when (flowType) { val event = when (flowType) {
ManageFundsComponent.FlowType.AddFunds -> when (action) { ManageFundsComponent.FlowType.AddFunds -> addFundsQuickActionEvent(action)
TokenActionsBSContentUM.Action.Buy -> ManageFundsAnalyticsEvent.ButtonBuy()
TokenActionsBSContentUM.Action.Exchange -> ManageFundsAnalyticsEvent.ButtonSwap()
TokenActionsBSContentUM.Action.Receive -> ManageFundsAnalyticsEvent.ButtonReceive()
else -> null
}
ManageFundsComponent.FlowType.Transfer -> when (action) { ManageFundsComponent.FlowType.Transfer -> when (action) {
TokenActionsBSContentUM.Action.Send -> TransferAnalyticsEvent.ButtonSend() TokenActionsBSContentUM.Action.Send -> TransferAnalyticsEvent.ButtonSend()
TokenActionsBSContentUM.Action.Exchange -> TransferAnalyticsEvent.ButtonSwap() TokenActionsBSContentUM.Action.Exchange -> TransferAnalyticsEvent.ButtonSwap()
@ -173,6 +170,51 @@ internal class ManageFundsModel @Inject constructor(
} }
} }
private fun addFundsQuickActionEvent(action: TokenActionsBSContentUM.Action): AnalyticsEvent? {
val request = tokenActionsTrigger.value
return if (launchMode is ManageFundsComponent.LaunchMode.TokenActionsOnly && request != null) {
tokenScreenQuickActionEvent(action, request)
} else {
when (action) {
TokenActionsBSContentUM.Action.Buy -> ManageFundsAnalyticsEvent.ButtonBuy()
TokenActionsBSContentUM.Action.Exchange -> ManageFundsAnalyticsEvent.ButtonSwap()
TokenActionsBSContentUM.Action.Receive -> ManageFundsAnalyticsEvent.ButtonReceive()
else -> null
}
}
}
private fun tokenScreenQuickActionEvent(
action: TokenActionsBSContentUM.Action,
request: TokenActionsRequest,
): AnalyticsEvent? {
val token = request.status.currency.symbol
val blockchain = request.status.currency.network.name
val derivationIndex = request.account.account
.takeUnless { it.isMainAccount }
?.derivationIndex?.value
return when (action) {
TokenActionsBSContentUM.Action.Buy -> TokenScreenAnalyticsEvent.ButtonWithParams.ButtonBuy(
token = token,
blockchain = blockchain,
status = TokenScreenAnalyticsEvent.AVAILABLE,
derivationIndex = derivationIndex,
)
TokenActionsBSContentUM.Action.Exchange -> TokenScreenAnalyticsEvent.ButtonWithParams.ButtonExchange(
token = token,
status = TokenScreenAnalyticsEvent.AVAILABLE,
blockchain = blockchain,
derivationIndex = derivationIndex,
)
TokenActionsBSContentUM.Action.Receive -> TokenScreenAnalyticsEvent.ButtonWithParams.ButtonReceive(
token = token,
status = TokenScreenAnalyticsEvent.AVAILABLE,
blockchain = blockchain,
)
else -> null
}
}
fun buildAvailableToAddDataForChooser(): AvailableToAddData { fun buildAvailableToAddDataForChooser(): AvailableToAddData {
val byWallet = filteredEntries.value.groupBy { it.userWallet.walletId } val byWallet = filteredEntries.value.groupBy { it.userWallet.walletId }
return AvailableToAddData( return AvailableToAddData(

View file

@ -76,6 +76,7 @@ internal class AllOffersModel @Inject constructor(
analyticsEventHandler.send( analyticsEventHandler.send(
event = OnrampAnalyticsEvent.OnPaymentMethodChosen(paymentMethod = method.methodConfig.method.name), event = OnrampAnalyticsEvent.OnPaymentMethodChosen(paymentMethod = method.methodConfig.method.name),
) )
analyticsEventHandler.send(OnrampAnalyticsEvent.ProvidersScreenOpened())
} }
} }

View file

@ -50,7 +50,6 @@ import dagger.assisted.AssistedInject
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.launch
@Suppress("LargeClass") @Suppress("LargeClass")
internal class DefaultSendComponent @AssistedInject constructor( internal class DefaultSendComponent @AssistedInject constructor(
@ -91,49 +90,47 @@ internal class DefaultSendComponent @AssistedInject constructor(
lifecycle = lifecycle, lifecycle = lifecycle,
mode = ObserveLifecycleMode.CREATE_DESTROY, mode = ObserveLifecycleMode.CREATE_DESTROY,
) { stack -> ) { stack ->
componentScope.launch { when (val activeComponent = stack.active.instance) {
when (val activeComponent = stack.active.instance) { is SendConfirmComponent -> {
is SendConfirmComponent -> { val fromCurrency = params.currency
val fromCurrency = params.currency val fromDerivationIndex = model.accountFlow.value?.derivationIndex?.value
val fromDerivationIndex = model.accountFlow.value?.derivationIndex?.value .takeIf { model.isAccountModeFlow.value }
.takeIf { model.isAccountModeFlow.value } analyticsEventHandler.send(
analyticsEventHandler.send( CommonSendAnalyticEvents.ConfirmationScreenOpened(
CommonSendAnalyticEvents.ConfirmationScreenOpened( categoryName = model.analyticCategoryName,
categoryName = model.analyticCategoryName, source = model.analyticsSendSource,
source = model.analyticsSendSource, sendBlockchain = fromCurrency.network.name,
sendBlockchain = fromCurrency.network.name, sendToken = fromCurrency.symbol,
sendToken = fromCurrency.symbol, fromDerivationIndex = fromDerivationIndex,
fromDerivationIndex = fromDerivationIndex, toDerivationIndex = null,
toDerivationIndex = null, type = model.consumeEntryType(),
type = model.consumeEntryType(), ),
), )
) if (model.currentRoute.value.isEditMode) {
if (model.currentRoute.value.isEditMode) { activeComponent.updateState(model.uiState.value)
activeComponent.updateState(model.uiState.value)
}
}
is SendAmountComponent -> {
analyticsEventHandler.send(
CommonSendAnalyticEvents.AmountScreenOpened(
categoryName = model.analyticCategoryName,
source = model.analyticsSendSource,
type = model.consumeEntryType(),
),
)
activeComponent.updateState(model.uiState.value.amountUM)
}
is DefaultSendDestinationComponent -> {
analyticsEventHandler.send(
CommonSendAnalyticEvents.AddressScreenOpened(
categoryName = model.analyticCategoryName,
source = model.analyticsSendSource,
),
)
activeComponent.updateState(model.uiState.value.destinationUM)
} }
} }
model.currentRoute.emit(stack.active.configuration) is SendAmountComponent -> {
analyticsEventHandler.send(
CommonSendAnalyticEvents.AmountScreenOpened(
categoryName = model.analyticCategoryName,
source = model.analyticsSendSource,
type = model.consumeEntryType(),
),
)
activeComponent.updateState(model.uiState.value.amountUM)
}
is DefaultSendDestinationComponent -> {
analyticsEventHandler.send(
CommonSendAnalyticEvents.AddressScreenOpened(
categoryName = model.analyticCategoryName,
source = model.analyticsSendSource,
),
)
activeComponent.updateState(model.uiState.value.destinationUM)
}
} }
model.currentRoute.value = stack.active.configuration
} }
} }

View file

@ -339,15 +339,19 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
} }
override fun onNFTClick(userWallet: UserWallet) { override fun onNFTClick(userWallet: UserWallet) {
val selectedWallet = stateHolder.getSelectedWallet() as? WalletState.MultiCurrency.Content ?: return val nftState = if (stateHolder.value.isRedesignEnabled) {
when (val state = selectedWallet.nftState) { stateHolder.getSelectedWalletUM().nftState
} else {
(stateHolder.getSelectedWallet() as? WalletState.MultiCurrency.Content)?.nftState
}
when (nftState) {
is WalletNFTItemUM.Content -> { is WalletNFTItemUM.Content -> {
analyticsEventHandler.send( analyticsEventHandler.send(
NFTAnalyticsEvent.NFTListScreenOpened( NFTAnalyticsEvent.NFTListScreenOpened(
state = AnalyticsParam.EmptyFull.Full, state = AnalyticsParam.EmptyFull.Full,
allAssetsCount = state.allAssetsCount, allAssetsCount = nftState.allAssetsCount,
collectionsCount = state.collectionsCount, collectionsCount = nftState.collectionsCount,
noCollectionAssetsCount = state.noCollectionAssetsCount, noCollectionAssetsCount = nftState.noCollectionAssetsCount,
), ),
) )
} }
@ -364,6 +368,7 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
is WalletNFTItemUM.Failed, is WalletNFTItemUM.Failed,
is WalletNFTItemUM.Hidden, is WalletNFTItemUM.Hidden,
is WalletNFTItemUM.Loading, is WalletNFTItemUM.Loading,
null,
-> Unit -> Unit
} }