diff --git a/app/src/main/java/com/tangem/tap/common/analytics/events/DetailsScreen.kt b/app/src/main/java/com/tangem/tap/common/analytics/events/DetailsScreen.kt deleted file mode 100644 index 775f44a0d8..0000000000 --- a/app/src/main/java/com/tangem/tap/common/analytics/events/DetailsScreen.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.tangem.tap.common.analytics.events - -import com.tangem.core.analytics.models.AnalyticsEvent - -/** -[REDACTED_AUTHOR] - */ -sealed class DetailsScreen( - event: String, - params: Map = mapOf(), -) : AnalyticsEvent("Details Screen", event, params) { - - class ScreenOpened : DetailsScreen("Details Screen Opened") -} \ No newline at end of file diff --git a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/analytics/TokenScreenAnalyticsEvent.kt b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/analytics/TokenScreenAnalyticsEvent.kt index 54eac28f44..b33b3562ed 100644 --- a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/analytics/TokenScreenAnalyticsEvent.kt +++ b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/analytics/TokenScreenAnalyticsEvent.kt @@ -2,6 +2,7 @@ package com.tangem.domain.tokens.model.analytics import com.tangem.core.analytics.models.AnalyticsEvent import com.tangem.core.analytics.models.AnalyticsParam.Key.ACTION +import com.tangem.core.analytics.models.AnalyticsParam.Key.BALANCE import com.tangem.core.analytics.models.AnalyticsParam.Key.BLOCKCHAIN import com.tangem.core.analytics.models.AnalyticsParam.Key.STATUS import com.tangem.core.analytics.models.AnalyticsParam.Key.TOKEN_PARAM @@ -16,11 +17,26 @@ sealed class TokenScreenAnalyticsEvent( ) : AnalyticsEvent("Token", event, params) { /** Legacy event. It has a unique category, but it also is sent on TokenScreen */ - class DetailsScreenOpened(token: String) : AnalyticsEvent( + class DetailsScreenOpened( + blockchain: String, + token: String, + tokenBalance: TokenBalance, + ) : AnalyticsEvent( category = "Details Screen", event = "Details Screen Opened", - params = mapOf("Token" to token), - ) + params = mapOf( + BLOCKCHAIN to blockchain, + TOKEN_PARAM to token, + BALANCE to tokenBalance.name, + ), + ) { + sealed class TokenBalance(val name: String) { + data object Full : TokenBalance("Full") + data object Error : TokenBalance("Error") + data object Empty : TokenBalance("Empty") + data object NoAddress : TokenBalance("No Address") + } + } class ButtonRemoveToken(token: String) : TokenScreenAnalyticsEvent( "Button - Remove Token", diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/model/TokenDetailsModel.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/model/TokenDetailsModel.kt index d0e4d0f29c..7a368fe134 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/model/TokenDetailsModel.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/model/TokenDetailsModel.kt @@ -62,6 +62,7 @@ import com.tangem.domain.tokens.model.analytics.TokenReceiveCopyActionSource import com.tangem.domain.tokens.model.analytics.TokenReceiveNewAnalyticsEvent import com.tangem.domain.tokens.model.analytics.TokenScreenAnalyticsEvent import com.tangem.domain.tokens.model.analytics.TokenScreenAnalyticsEvent.Companion.toReasonAnalyticsText +import com.tangem.domain.tokens.model.analytics.TokenScreenAnalyticsEvent.DetailsScreenOpened.TokenBalance import com.tangem.domain.tokens.model.analytics.TokenSwapPromoAnalyticsEvent import com.tangem.domain.transaction.error.AssociateAssetError import com.tangem.domain.transaction.error.IncompleteTransactionError @@ -90,6 +91,7 @@ import com.tangem.features.tokenreceive.TokenReceiveFeatureToggle import com.tangem.features.txhistory.entity.TxHistoryContentUpdateEmitter import com.tangem.utils.Provider import com.tangem.utils.coroutines.* +import com.tangem.utils.extensions.isZero import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.async @@ -162,6 +164,7 @@ internal class TokenDetailsModel @Inject constructor( private val selectedAppCurrencyFlow: StateFlow = createSelectedAppCurrencyFlow() private var cryptoCurrencyStatus: CryptoCurrencyStatus? = null + private var isBalanceLoadedEventSent = false private var expressTxStatusTaskScheduler = SingleTaskScheduler>() /** Transaction id to check for status */ @@ -207,9 +210,6 @@ internal class TokenDetailsModel @Inject constructor( val uiState: StateFlow = internalUiState init { - analyticsEventsHandler.send( - event = TokenScreenAnalyticsEvent.DetailsScreenOpened(token = cryptoCurrency.symbol), - ) updateTopBarMenu() initButtons() updateContent() @@ -326,6 +326,7 @@ internal class TokenDetailsModel @Inject constructor( .onEach { maybeCurrencyStatus -> internalUiState.value = stateFactory.getCurrencyLoadedBalanceState(maybeCurrencyStatus) maybeCurrencyStatus.onRight { status -> + sendOneTimeBalanceLoadedAnalyticsEvent(status) cryptoCurrencyStatus = status updateButtons(currencyStatus = status) updateWarnings(status) @@ -1122,6 +1123,44 @@ internal class TokenDetailsModel @Inject constructor( ) } + private fun sendOneTimeBalanceLoadedAnalyticsEvent(cryptoCurrencyStatus: CryptoCurrencyStatus?) { + if (isBalanceLoadedEventSent || cryptoCurrencyStatus == null) return + + val tokenBalance = when (val value = cryptoCurrencyStatus.value) { + is CryptoCurrencyStatus.Custom, + is CryptoCurrencyStatus.Loaded, + is CryptoCurrencyStatus.NoQuote, + -> { + if (value.sources.networkSource.isActual()) { + val amount = value.amount + if (amount != null && !amount.isZero()) { + TokenBalance.Full + } else { + TokenBalance.Empty + } + } else { + return + } + } + is CryptoCurrencyStatus.NoAccount, + is CryptoCurrencyStatus.MissedDerivation, + -> TokenBalance.NoAddress + + is CryptoCurrencyStatus.NoAmount, + is CryptoCurrencyStatus.Unreachable, + -> TokenBalance.Error + CryptoCurrencyStatus.Loading -> return + } + analyticsEventsHandler.send( + event = TokenScreenAnalyticsEvent.DetailsScreenOpened( + blockchain = cryptoCurrency.network.name, + token = cryptoCurrency.symbol, + tokenBalance = tokenBalance, + ), + ) + isBalanceLoadedEventSent = true + } + private companion object { const val EXPRESS_STATUS_UPDATE_DELAY = 10_000L }