Updated on 2026-08-14
This commit is contained in:
commit
473ec62419
10 changed files with 96 additions and 40 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
)
|
||||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
|
|
@ -35,14 +35,6 @@ sealed class WalletNotification(val config: NotificationConfig) {
|
|||
title = resourceReference(id = R.string.warning_failed_to_verify_card_title),
|
||||
subtitle = resourceReference(id = R.string.warning_failed_to_verify_card_message),
|
||||
)
|
||||
|
||||
data class LowSignatures(val count: Int) : Critical(
|
||||
title = resourceReference(id = R.string.warning_low_signatures_title),
|
||||
subtitle = resourceReference(
|
||||
id = R.string.warning_low_signatures_message,
|
||||
formatArgs = wrappedList(count),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
sealed class Warning(
|
||||
|
|
@ -91,6 +83,14 @@ sealed class WalletNotification(val config: NotificationConfig) {
|
|||
title = resourceReference(id = R.string.warning_testnet_card_title),
|
||||
subtitle = resourceReference(id = R.string.warning_testnet_card_message),
|
||||
)
|
||||
|
||||
data class LowSignatures(val count: Int) : Warning(
|
||||
title = resourceReference(id = R.string.warning_low_signatures_title),
|
||||
subtitle = resourceReference(
|
||||
id = R.string.warning_low_signatures_message,
|
||||
formatArgs = wrappedList(count),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
sealed class Informational(
|
||||
|
|
|
|||
|
|
@ -247,7 +247,6 @@ private fun WalletBottomSheets(state: WalletState) {
|
|||
is WalletBottomSheetConfig -> {
|
||||
WalletBottomSheet(config = bottomSheetConfig)
|
||||
}
|
||||
|
||||
is TokenReceiveBottomSheetConfig -> {
|
||||
TokenReceiveBottomSheet(config = bottomSheetConfig)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ internal class WalletNotificationsListFactory(
|
|||
|
||||
cardTypesResolver.getRemainingSignatures()?.let { remainingSignatures ->
|
||||
addIf(
|
||||
element = WalletNotification.Critical.LowSignatures(count = remainingSignatures),
|
||||
element = WalletNotification.Warning.LowSignatures(count = remainingSignatures),
|
||||
condition = remainingSignatures <= MAX_REMAINING_SIGNATURES_COUNT,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue