Updated on 2026-08-14

This commit is contained in:
Tangem 2023-10-20 15:42:49 +08:00
parent ad115ebb5a
commit f186efc935
8 changed files with 87 additions and 31 deletions

View file

@ -3,7 +3,7 @@ package com.tangem.tap.features.intentHandler.handlers
import android.content.Intent
import android.net.Uri
import com.tangem.core.analytics.Analytics
import com.tangem.feature.tokendetails.presentation.tokendetails.analytics.TokenScreenEvent
import com.tangem.domain.tokens.models.analytics.TokenScreenAnalyticsEvent
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.features.intentHandler.IntentHandler
import com.tangem.tap.network.exchangeServices.ExchangeUrlBuilder
@ -21,7 +21,7 @@ class BuyCurrencyIntentHandler : IntentHandler {
val successUri = Uri.parse(ExchangeUrlBuilder.SUCCESS_URL)
return if (data.host == successUri.host && data.authority == successUri.authority) {
val currencyType = AnalyticsParam.CurrencyType.Currency(currency)
Analytics.send(TokenScreenEvent.Bought(currencyType.value))
Analytics.send(TokenScreenAnalyticsEvent.Bought(currencyType.value))
true
} else {
false

View file

@ -7,6 +7,8 @@ sealed class TokenReceiveAnalyticsEvent(
params: Map<String, String> = mapOf(),
) : AnalyticsEvent("Token / Receive", event, params, null) {
object ReceiveScreenOpened : TokenReceiveAnalyticsEvent(event = "Receive Screen Opened")
class ButtonCopyAddress(token: String) : TokenReceiveAnalyticsEvent(
event = "Button - Copy Address",
params = mapOf("Token" to token),

View file

@ -1,62 +1,67 @@
package com.tangem.feature.tokendetails.presentation.tokendetails.analytics
package com.tangem.domain.tokens.models.analytics
import com.tangem.core.analytics.models.AnalyticsEvent
/**
[REDACTED_AUTHOR]
*/
sealed class TokenScreenEvent(
sealed class TokenScreenAnalyticsEvent(
event: String,
params: Map<String, String> = mapOf(),
error: Throwable? = null,
) : AnalyticsEvent("Token", event, params, error) {
class Refreshed(token: String) : TokenScreenEvent(
class Refreshed(token: String) : TokenScreenAnalyticsEvent(
event = "Refreshed",
params = mapOf("Token" to token),
)
class ButtonRemoveToken(token: String) : TokenScreenEvent(
class ButtonRemoveToken(token: String) : TokenScreenAnalyticsEvent(
"Button - Remove Token",
params = mapOf("Token" to token),
)
class ButtonExplore(token: String) : TokenScreenEvent(
class ButtonExplore(token: String) : TokenScreenAnalyticsEvent(
event = "Button - Explore",
params = mapOf("Token" to token),
)
class ButtonReload(token: String) : TokenScreenEvent(
class ButtonReload(token: String) : TokenScreenAnalyticsEvent(
event = "Button - Reload",
params = mapOf("Token" to token),
)
class ButtonBuy(token: String) : TokenScreenEvent(
class ButtonBuy(token: String) : TokenScreenAnalyticsEvent(
event = "Button - Buy",
params = mapOf("Token" to token),
)
class ButtonSell(token: String) : TokenScreenEvent(
class ButtonSell(token: String) : TokenScreenAnalyticsEvent(
event = "Button - Sell",
params = mapOf("Token" to token),
)
class ButtonExchange(token: String) : TokenScreenEvent(
class ButtonExchange(token: String) : TokenScreenAnalyticsEvent(
event = "Button - Exchange",
params = mapOf("Token" to token),
)
class ButtonSend(token: String) : TokenScreenEvent(
class ButtonSend(token: String) : TokenScreenAnalyticsEvent(
event = "Button - Send",
params = mapOf("Token" to token),
)
class ButtonReceive(token: String) : TokenScreenEvent(
class ButtonReceive(token: String) : TokenScreenAnalyticsEvent(
event = "Button - Receive",
params = mapOf("Token" to token),
)
class Bought(token: String) : TokenScreenEvent(
class ButtonCopyAddress(token: String) : TokenScreenAnalyticsEvent(
event = "Button - Copy Address",
params = mapOf("Token" to token),
)
class Bought(token: String) : TokenScreenAnalyticsEvent(
event = "Token Bought",
params = mapOf("Token" to token),
)

View file

@ -30,7 +30,12 @@ sealed class SwapEvents(
)
object ButtonGivePermissionClicked : SwapEvents(event = "Button - Give permission")
object ButtonPermissionApproveClicked : SwapEvents(event = "Button - Permission Approve")
data class ButtonPermissionApproveClicked(val sendToken: String, val receiveToken: String) : SwapEvents(
event = "Button - Permission Approve",
params = mapOf("Send Token" to sendToken, "Receive Token" to receiveToken),
)
object ButtonPermissionCancelClicked : SwapEvents(event = "Button - Permission Cancel")
object ButtonSwipeClicked : SwapEvents(event = "Button - Swipe")
object SwapInProgressScreen : SwapEvents(event = "Swap in Progress Screen Opened")

View file

@ -461,7 +461,16 @@ internal class SwapViewModel @Inject constructor(
},
onGivePermissionClick = {
givePermissionsToSwap()
analyticsEventHandler.send(SwapEvents.ButtonPermissionApproveClicked)
val sendTokenSymbol = dataState.fromCurrency?.symbol
val receiveTokenSymbol = dataState.toCurrency?.symbol
if (sendTokenSymbol != null && receiveTokenSymbol != null) {
analyticsEventHandler.send(
SwapEvents.ButtonPermissionApproveClicked(
sendToken = sendTokenSymbol,
receiveToken = receiveTokenSymbol,
),
)
}
},
onChangeCardsClicked = {
onChangeCardsClicked()

View file

@ -21,6 +21,7 @@ import com.tangem.domain.tokens.legacy.TradeCryptoAction
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.models.analytics.TokenReceiveAnalyticsEvent
import com.tangem.domain.tokens.models.analytics.TokenScreenAnalyticsEvent
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase
@ -30,7 +31,6 @@ import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.domain.wallets.usecase.GetExploreUrlUseCase
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.feature.tokendetails.presentation.router.InnerTokenDetailsRouter
import com.tangem.feature.tokendetails.presentation.tokendetails.analytics.TokenScreenEvent
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.TokenDetailsStateFactory
import com.tangem.features.tokendetails.navigation.TokenDetailsRouter
@ -221,7 +221,7 @@ internal class TokenDetailsViewModel @Inject constructor(
}
override fun onBuyClick() {
analyticsEventsHandler.send(TokenScreenEvent.ButtonBuy(cryptoCurrency.symbol))
analyticsEventsHandler.send(TokenScreenAnalyticsEvent.ButtonBuy(cryptoCurrency.symbol))
val status = cryptoCurrencyStatus ?: return
viewModelScope.launch(dispatchers.io) {
@ -236,13 +236,13 @@ internal class TokenDetailsViewModel @Inject constructor(
}
override fun onReloadClick() {
analyticsEventsHandler.send(TokenScreenEvent.ButtonReload(cryptoCurrency.symbol))
analyticsEventsHandler.send(TokenScreenAnalyticsEvent.ButtonReload(cryptoCurrency.symbol))
uiState = stateFactory.getLoadingTxHistoryState()
updateTxHistory(refresh = true, showItemsLoading = true)
}
override fun onSendClick() {
analyticsEventsHandler.send(TokenScreenEvent.ButtonSend(cryptoCurrency.symbol))
analyticsEventsHandler.send(TokenScreenAnalyticsEvent.ButtonSend(cryptoCurrency.symbol))
val cryptoCurrencyStatus = cryptoCurrencyStatus ?: return
@ -284,7 +284,7 @@ internal class TokenDetailsViewModel @Inject constructor(
}
override fun onReceiveClick() {
analyticsEventsHandler.send(TokenScreenEvent.ButtonReceive(cryptoCurrency.symbol))
analyticsEventsHandler.send(TokenScreenAnalyticsEvent.ButtonReceive(cryptoCurrency.symbol))
viewModelScope.launch(dispatchers.io) {
val addresses = walletManagersFacade.getAddress(
@ -292,6 +292,8 @@ internal class TokenDetailsViewModel @Inject constructor(
network = cryptoCurrency.network,
)
analyticsEventsHandler.send(event = TokenReceiveAnalyticsEvent.ReceiveScreenOpened)
uiState = stateFactory.getStateWithReceiveBottomSheet(
currency = cryptoCurrency,
addresses = addresses,
@ -306,7 +308,7 @@ internal class TokenDetailsViewModel @Inject constructor(
}
override fun onSellClick() {
analyticsEventsHandler.send(TokenScreenEvent.ButtonSell(cryptoCurrency.symbol))
analyticsEventsHandler.send(TokenScreenAnalyticsEvent.ButtonSell(cryptoCurrency.symbol))
val status = cryptoCurrencyStatus ?: return
reduxStateHolder.dispatch(
@ -318,7 +320,7 @@ internal class TokenDetailsViewModel @Inject constructor(
}
override fun onSwapClick() {
analyticsEventsHandler.send(TokenScreenEvent.ButtonExchange(cryptoCurrency.symbol))
analyticsEventsHandler.send(TokenScreenAnalyticsEvent.ButtonExchange(cryptoCurrency.symbol))
reduxStateHolder.dispatch(TradeCryptoAction.New.Swap(cryptoCurrency))
}
@ -328,7 +330,7 @@ internal class TokenDetailsViewModel @Inject constructor(
}
override fun onHideClick() {
analyticsEventsHandler.send(TokenScreenEvent.ButtonRemoveToken(cryptoCurrency.symbol))
analyticsEventsHandler.send(TokenScreenAnalyticsEvent.ButtonRemoveToken(cryptoCurrency.symbol))
viewModelScope.launch {
val hasLinkedTokens = removeCurrencyUseCase.hasLinkedTokens(userWalletId, cryptoCurrency)
@ -349,7 +351,7 @@ internal class TokenDetailsViewModel @Inject constructor(
}
override fun onExploreClick() {
analyticsEventsHandler.send(TokenScreenEvent.ButtonExplore(cryptoCurrency.symbol))
analyticsEventsHandler.send(TokenScreenAnalyticsEvent.ButtonExplore(cryptoCurrency.symbol))
viewModelScope.launch(dispatchers.io) {
val addresses = walletManagersFacade.getAddress(
userWalletId = userWalletId,
@ -393,7 +395,7 @@ internal class TokenDetailsViewModel @Inject constructor(
}
override fun onRefreshSwipe() {
analyticsEventsHandler.send(TokenScreenEvent.Refreshed(cryptoCurrency.symbol))
analyticsEventsHandler.send(TokenScreenAnalyticsEvent.Refreshed(cryptoCurrency.symbol))
uiState = stateFactory.getRefreshingState()

View file

@ -247,7 +247,6 @@ private fun WalletBottomSheets(state: WalletState) {
is WalletBottomSheetConfig -> {
WalletBottomSheet(config = bottomSheetConfig)
}
is TokenReceiveBottomSheetConfig -> {
TokenReceiveBottomSheet(config = bottomSheetConfig)
}

View file

@ -50,6 +50,7 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.NetworkGroup
import com.tangem.domain.tokens.model.TokenList
import com.tangem.domain.tokens.models.analytics.TokenReceiveAnalyticsEvent
import com.tangem.domain.tokens.models.analytics.TokenScreenAnalyticsEvent
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase
@ -602,6 +603,11 @@ internal class WalletViewModel @Inject constructor(
override fun onBuyClick(cryptoCurrencyStatus: CryptoCurrencyStatus) {
val state = uiState as? WalletState.ContentState ?: return
analyticsEventsHandler.send(
event = TokenScreenAnalyticsEvent.ButtonBuy(cryptoCurrencyStatus.currency.symbol),
)
val wallet = getWallet(index = state.walletsListConfig.selectedWalletIndex)
reduxStateHolder.dispatch(
@ -614,6 +620,10 @@ internal class WalletViewModel @Inject constructor(
}
override fun onSwapClick(cryptoCurrencyStatus: CryptoCurrencyStatus) {
analyticsEventsHandler.send(
event = TokenScreenAnalyticsEvent.ButtonExchange(cryptoCurrencyStatus.currency.symbol),
)
reduxStateHolder.dispatch(TradeCryptoAction.New.Swap(cryptoCurrencyStatus.currency))
}
@ -622,12 +632,14 @@ internal class WalletViewModel @Inject constructor(
val userWallet = getWallet(index = state.walletsListConfig.selectedWalletIndex)
val coinStatus = if (userWallet.isMultiCurrency) cryptoCurrencyStatus else singleWalletCryptoCurrencyStatus
coinStatus ?: return
analyticsEventsHandler.send(
event = TokenScreenAnalyticsEvent.ButtonSend(coinStatus.currency.symbol),
)
reduxStateHolder.dispatch(
action = TradeCryptoAction.New.SendCoin(
userWallet = userWallet,
coinStatus = coinStatus ?: return,
),
action = TradeCryptoAction.New.SendCoin(userWallet = userWallet, coinStatus = coinStatus),
)
}
@ -639,6 +651,10 @@ internal class WalletViewModel @Inject constructor(
val state = uiState as? WalletState.ContentState ?: return
analyticsEventsHandler.send(
event = TokenScreenAnalyticsEvent.ButtonSend(cryptoCurrencyStatus.currency.symbol),
)
viewModelScope.launch(dispatchers.io) {
val userWallet = getWallet(index = state.walletsListConfig.selectedWalletIndex)
@ -669,6 +685,10 @@ internal class WalletViewModel @Inject constructor(
override fun onReceiveClick(cryptoCurrencyStatus: CryptoCurrencyStatus) {
val state = uiState as? WalletState.ContentState ?: return
analyticsEventsHandler.send(
event = TokenScreenAnalyticsEvent.ButtonReceive(cryptoCurrencyStatus.currency.symbol),
)
viewModelScope.launch(dispatchers.io) {
val userWallet = getWallet(index = state.walletsListConfig.selectedWalletIndex)
@ -677,6 +697,8 @@ internal class WalletViewModel @Inject constructor(
network = cryptoCurrencyStatus.currency.network,
)
analyticsEventsHandler.send(event = TokenReceiveAnalyticsEvent.ReceiveScreenOpened)
val currency = cryptoCurrencyStatus.currency
uiState = stateFactory.getStateWithOpenWalletBottomSheet(
content = TokenReceiveBottomSheetConfig(
@ -703,6 +725,10 @@ internal class WalletViewModel @Inject constructor(
override fun onCopyAddressClick(cryptoCurrencyStatus: CryptoCurrencyStatus) {
val state = uiState as? WalletState.ContentState ?: return
analyticsEventsHandler.send(
event = TokenScreenAnalyticsEvent.ButtonCopyAddress(cryptoCurrencyStatus.currency.symbol),
)
viewModelScope.launch(dispatchers.main) {
val userWallet = getWallet(index = state.walletsListConfig.selectedWalletIndex)
@ -725,6 +751,10 @@ internal class WalletViewModel @Inject constructor(
}
override fun onSellClick(cryptoCurrencyStatus: CryptoCurrencyStatus) {
analyticsEventsHandler.send(
event = TokenScreenAnalyticsEvent.ButtonSell(cryptoCurrencyStatus.currency.symbol),
)
reduxStateHolder.dispatch(
TradeCryptoAction.New.Sell(
cryptoCurrencyStatus = cryptoCurrencyStatus,
@ -888,6 +918,10 @@ internal class WalletViewModel @Inject constructor(
}
override fun onHideTokensClick(cryptoCurrencyStatus: CryptoCurrencyStatus) {
analyticsEventsHandler.send(
event = TokenScreenAnalyticsEvent.ButtonRemoveToken(cryptoCurrencyStatus.currency.symbol),
)
viewModelScope.launch(dispatchers.main) {
val state = uiState as? WalletState.ContentState ?: return@launch
val userWallet = getWallet(state.walletsListConfig.selectedWalletIndex)