Updated on 2026-08-14

This commit is contained in:
Tangem 2024-03-12 09:47:35 +00:00
commit 6bc1179aa3
4 changed files with 70 additions and 1 deletions

View file

@ -11,6 +11,11 @@ sealed class AnalyticsParam {
companion object
}
sealed class TokenBalanceState(val value: String) {
object Empty : TokenBalanceState("Empty")
object Full : TokenBalanceState("Full")
}
sealed class RateApp(val value: String) {
object Liked : RateApp("Liked")
object Disliked : RateApp("Disliked")
@ -124,6 +129,7 @@ sealed class AnalyticsParam {
const val TOKEN = "Token"
const val SOURCE = "Source"
const val BALANCE = "Balance"
const val STATE = "State"
const val BATCH = "Batch"
const val TYPE = "Type"
const val FEE_TYPE = "Fee Type"

View file

@ -38,6 +38,14 @@ sealed class WalletScreenAnalyticsEvent {
AnalyticsParam.BALANCE to balance.value,
),
)
class TokenBalance(balance: AnalyticsParam.TokenBalanceState, token: String) : Basic(
event = "Token Balance",
params = mapOf(
AnalyticsParam.STATE to balance.value,
AnalyticsParam.TOKEN to token,
),
)
}
sealed class MainScreen(

View file

@ -1,10 +1,13 @@
package com.tangem.feature.wallet.presentation.wallet.analytics.utils
import arrow.core.getOrElse
import com.tangem.blockchain.common.Blockchain
import com.tangem.common.extensions.isZero
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.domain.analytics.CheckIsWalletToppedUpUseCase
import com.tangem.domain.analytics.model.WalletBalanceState
import com.tangem.domain.common.extensions.fromNetworkId
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.NetworkGroup
import com.tangem.domain.tokens.model.TokenList
@ -14,6 +17,8 @@ import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnaly
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
import com.tangem.feature.wallet.presentation.wallet.utils.ScreenLifecycleProvider
import dagger.hilt.android.scopes.ViewModelScoped
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import java.math.BigDecimal
import javax.inject.Inject
@ -24,6 +29,9 @@ internal class TokenListAnalyticsSender @Inject constructor(
private val screenLifecycleProvider: ScreenLifecycleProvider,
) {
private val balanceWasSentMap = mutableMapOf<String, Boolean>()
private val mutex = Mutex()
suspend fun send(displayedUiState: WalletState?, userWallet: UserWallet, tokenList: TokenList) {
if (screenLifecycleProvider.isBackground) return
if (displayedUiState == null || displayedUiState.pullToRefreshConfig.isRefreshing) return
@ -34,6 +42,7 @@ internal class TokenListAnalyticsSender @Inject constructor(
sendBalanceLoadedEventIfNeeded(tokenList.totalFiatBalance, currenciesStatuses)
sendToppedUpEventIfNeeded(userWallet, tokenList.totalFiatBalance, currenciesStatuses)
sendUnreachableNetworksEventIfNeeded(currenciesStatuses)
sendTokenBalancesIfNeeded(currenciesStatuses)
}
private fun getCurrenciesStatuses(tokenList: TokenList): List<CryptoCurrencyStatus> = when (tokenList) {
@ -72,6 +81,50 @@ internal class TokenListAnalyticsSender @Inject constructor(
}
}
private suspend fun sendTokenBalancesIfNeeded(currenciesStatuses: List<CryptoCurrencyStatus>) {
currenciesStatuses.forEach {
val status = it.value
if (status is CryptoCurrencyStatus.Loaded) {
sendTokenBalancesForSpecificBlockchains(it, status)
}
}
}
// TODO hotfix/5.7.4 send event for log if tokens from polkadot ecosystem have balance
private suspend fun sendTokenBalancesForSpecificBlockchains(
currencyStatus: CryptoCurrencyStatus,
balanceStatus: CryptoCurrencyStatus.Loaded,
) {
// for now send only for Polkadot ecosystem blockchains
// later dependency on Blockchain will be removed and use token name
when (val blockchain = Blockchain.fromNetworkId(currencyStatus.currency.network.backendId)) {
Blockchain.Polkadot,
Blockchain.AlephZero,
Blockchain.Kusama,
-> {
if (balanceWasSentMap[blockchain.currency] != true) {
val tokenBalance = if (balanceStatus.amount.isZero()) {
AnalyticsParam.TokenBalanceState.Empty
} else {
AnalyticsParam.TokenBalanceState.Full
}
analyticsEventHandler.send(
Basic.TokenBalance(
balance = tokenBalance,
token = blockchain.currency,
),
)
mutex.withLock {
balanceWasSentMap[blockchain.currency] = true
}
}
}
else -> {
/* no-op */
}
}
}
private fun getCardBalanceState(fiatBalance: TokenList.FiatBalance.Loaded): AnalyticsParam.CardBalanceState {
return if (fiatBalance.amount > BigDecimal.ZERO) {
AnalyticsParam.CardBalanceState.Full

View file

@ -36,9 +36,11 @@ internal class MultiWalletTokenListSubscriber(
override fun tokenListFlow(): MaybeTokenListFlow = getTokenListUseCase(userWallet.walletId)
override suspend fun onTokenListReceived(maybeTokenList: Either<TokenListError, TokenList>) {
updateSortingIfNeeded(maybeTokenList)
// TODO disabled for 5.7.2 because of potential critical
// updateSortingIfNeeded(maybeTokenList)
}
@Suppress("UnusedPrivateMember")
private suspend fun updateSortingIfNeeded(maybeTokenList: Either<TokenListError, TokenList>) {
val tokenList = maybeTokenList.getOrElse { return }
if (!checkNeedSorting(tokenList)) return