diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 9c4e5fbd00..6cb76a20e4 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -8,6 +8,7 @@ plugins { alias(deps.plugins.google.services) alias(deps.plugins.hilt.android) alias(deps.plugins.firebase.crashlytics) + alias(deps.plugins.firebase.perf) id("configuration") } @@ -212,7 +213,10 @@ dependencies { implementation(deps.firebase.analytics) implementation(deps.firebase.crashlytics) implementation(deps.firebase.messaging) - + implementation(deps.firebase.perf) { + exclude(group = "com.google.firebase", module = "protolite-well-known-types") + exclude(group = "com.google.protobuf", module = "protobuf-javalite") + } /** Tangem libraries */ implementation(deps.tangem.blockchain) { exclude(module = "joda-time") diff --git a/build.gradle.kts b/build.gradle.kts index 188c0a6ef6..0ace95bd3b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,6 +10,7 @@ plugins { alias(deps.plugins.hilt.android) apply false alias(deps.plugins.google.services) apply false alias(deps.plugins.firebase.crashlytics) apply false + alias(deps.plugins.firebase.perf) apply false alias(deps.plugins.room) apply false } diff --git a/features/wallet/impl/build.gradle.kts b/features/wallet/impl/build.gradle.kts index fcae2b21f7..0681996220 100644 --- a/features/wallet/impl/build.gradle.kts +++ b/features/wallet/impl/build.gradle.kts @@ -40,6 +40,10 @@ dependencies { implementation(deps.tangem.card.core) implementation(deps.tangem.blockchain) implementation(deps.timber) + implementation(deps.firebase.perf) { + exclude(group = "com.google.firebase", module = "protolite-well-known-types") + exclude(group = "com.google.protobuf", module = "protobuf-javalite") + } /** DI */ implementation(deps.hilt.android) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/TokenListAnalyticsSender.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/TokenListAnalyticsSender.kt index fd984d0d22..a475d10af8 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/TokenListAnalyticsSender.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/TokenListAnalyticsSender.kt @@ -1,6 +1,8 @@ package com.tangem.feature.wallet.presentation.wallet.analytics.utils import arrow.core.getOrElse +import com.google.firebase.perf.FirebasePerformance +import com.google.firebase.perf.metrics.Trace import com.tangem.blockchain.common.Blockchain import com.tangem.blockchainsdk.utils.fromNetworkId import com.tangem.common.extensions.isZero @@ -12,6 +14,7 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus import com.tangem.domain.tokens.model.TokenList import com.tangem.domain.tokens.model.TotalFiatBalance import com.tangem.domain.wallets.models.UserWallet +import com.tangem.domain.wallets.models.UserWalletId import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent.Basic import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent.MainScreen import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState @@ -31,11 +34,20 @@ internal class TokenListAnalyticsSender @Inject constructor( private val balanceWasSentMap = mutableMapOf() private val mutex = Mutex() + private val loadingTraces = mutableMapOf() suspend fun send(displayedUiState: WalletState?, userWallet: UserWallet, tokenList: TokenList) { if (screenLifecycleProvider.isBackgroundState.value) return if (displayedUiState == null || displayedUiState.pullToRefreshConfig.isRefreshing) return - if (tokenList.totalFiatBalance is TotalFiatBalance.Loading) return + + if (tokenList.totalFiatBalance is TotalFiatBalance.Loading) { + startLoadingTraceIfNeeded(userWallet.walletId, tokenList) + return + } + + if (isTerminalState(tokenList.totalFiatBalance)) { + stopLoadingTraceIfNeeded(userWallet.walletId, tokenList.totalFiatBalance) + } val currenciesStatuses = tokenList.flattenCurrencies() @@ -45,6 +57,35 @@ internal class TokenListAnalyticsSender @Inject constructor( sendTokenBalancesIfNeeded(currenciesStatuses) } + private suspend fun startLoadingTraceIfNeeded(userWalletId: UserWalletId, tokenList: TokenList) { + mutex.withLock { + if (!loadingTraces.containsKey(userWalletId)) { + val trace = FirebasePerformance.getInstance().newTrace(BALANCE_LOADED_TRACE_NAME) + trace.start() + trace.putAttribute(TOKENS_COUNT, tokenList.flattenCurrencies().size.toString()) + loadingTraces[userWalletId] = trace + } + } + } + + private suspend fun stopLoadingTraceIfNeeded(userWalletId: UserWalletId, totalFiatBalance: TotalFiatBalance) { + mutex.withLock { + loadingTraces[userWalletId]?.apply { + when (totalFiatBalance) { + is TotalFiatBalance.Loaded -> putAttribute(HAS_ERROR, "No") + is TotalFiatBalance.Failed -> putAttribute(HAS_ERROR, "Yes") + else -> { /* Intentionally do nothing */ } + } + stop() + loadingTraces.remove(userWalletId) + } + } + } + + private fun isTerminalState(balance: TotalFiatBalance): Boolean { + return balance is TotalFiatBalance.Failed || balance is TotalFiatBalance.Loaded + } + private fun sendBalanceLoadedEventIfNeeded( fiatBalance: TotalFiatBalance, currenciesStatuses: List, @@ -179,4 +220,10 @@ internal class TokenListAnalyticsSender @Inject constructor( analyticsEventHandler.send(MainScreen.NetworksUnreachable(unreachableCurrencies)) } } + + companion object { + const val BALANCE_LOADED_TRACE_NAME = "Total_balance_loaded" + const val HAS_ERROR = "has_error" + const val TOKENS_COUNT = "tokens_count" + } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/Wallet2CobrandImage.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/Wallet2CobrandImage.kt index 5f66d5f11c..ccb5da40d3 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/Wallet2CobrandImage.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/Wallet2CobrandImage.kt @@ -55,6 +55,18 @@ internal enum class Wallet2CobrandImage( batchIds = setOf("AF97"), ), + CashClubGold( + cards2ResId = R.drawable.ill_cashclubgold_card2_120_106, + cards3ResId = R.drawable.ill_cashclubgold_card3_120_106, + batchIds = setOf("BB000004"), + ), + + Changenow( + cards2ResId = R.drawable.ill_changenow_card2_120_106, + cards3ResId = R.drawable.ill_changenow_card3_120_106, + batchIds = setOf("BB000013"), + ), + CoinMetrica( cards2ResId = R.drawable.ill_coin_metrica_card2_120_106, cards3ResId = R.drawable.ill_coin_metrica_card3_120_106, @@ -97,6 +109,12 @@ internal enum class Wallet2CobrandImage( batchIds = setOf("AF13"), ), + Hodl( + cards2ResId = R.drawable.ill_hodl_card2_120_106, + cards3ResId = R.drawable.ill_hodl_card3_120_106, + batchIds = setOf("BB000009"), + ), + Jr( cards2ResId = R.drawable.ill_jr_card2_120_106, cards3ResId = R.drawable.ill_jr_card3_120_106, @@ -145,12 +163,24 @@ internal enum class Wallet2CobrandImage( batchIds = setOf("AF52"), ), + Kango( + cards2ResId = R.drawable.ill_kango_card2_120_106, + cards3ResId = R.drawable.ill_kango_card3_120_106, + batchIds = setOf("BB000006"), + ), + Konan( cards2ResId = R.drawable.ill_konan_card2_120_106, cards3ResId = R.drawable.ill_konan_card3_120_106, batchIds = setOf("AF93"), ), + Kroak( + cards2ResId = R.drawable.ill_kroak_card2_120_106, + cards3ResId = R.drawable.ill_kroak_card3_120_106, + batchIds = setOf("BB000011"), + ), + Neiro( cards2ResId = R.drawable.ill_neiro_card2_120_106, cards3ResId = R.drawable.ill_neiro_card3_120_106, @@ -163,6 +193,12 @@ internal enum class Wallet2CobrandImage( batchIds = setOf("AF26"), ), + PassimPay( + cards2ResId = R.drawable.ill_passimpay_cards2_120_106, + cards3ResId = R.drawable.ill_passimpay_cards3_120_106, + batchIds = setOf("BB000007"), + ), + // for multicolored cards use image of 3 cards in all cases Pastel( cards2ResId = R.drawable.ill_pastel_cards3_120_106, @@ -176,12 +212,24 @@ internal enum class Wallet2CobrandImage( batchIds = setOf("AF34"), ), + Rizo( + cards2ResId = R.drawable.ill_rizo_card2_120_106, + cards3ResId = R.drawable.ill_rizo_card3_120_106, + batchIds = setOf("BB000012"), + ), + SatoshiFriends( cards2ResId = R.drawable.ill_satoshi_card2_120_106, cards3ResId = R.drawable.ill_satoshi_card3_120_106, batchIds = setOf("AF19"), ), + SinCity( + cards2ResId = R.drawable.ill_sincity_card2_120_106, + cards3ResId = R.drawable.ill_sincity_card3_120_106, + batchIds = setOf("BB000010"), + ), + StealthCard( cards2ResId = R.drawable.ill_stealth_cards2_120_106, cards3ResId = R.drawable.ill_stealth_cards3_120_106, @@ -219,6 +267,12 @@ internal enum class Wallet2CobrandImage( batchIds = setOf("AF40", "AF41", "AF42", "AF75", "AF76", "AF77"), ), + Vnish( + cards2ResId = R.drawable.ill_vnish_card2_120_106, + cards3ResId = R.drawable.ill_vnish_card3_120_106, + batchIds = setOf("BB000005"), + ), + VoltInu( cards2ResId = R.drawable.ill_volt_inu_card2_120_106, cards3ResId = R.drawable.ill_volt_inu_card3_120_106, @@ -231,6 +285,12 @@ internal enum class Wallet2CobrandImage( batchIds = setOf("AF15"), ), + WildGoat( + cards2ResId = R.drawable.ill_wildgoat_card2_120_106, + cards3ResId = R.drawable.ill_wildgoat_card3_120_106, + batchIds = setOf("BB000001"), + ), + Winter( cards2ResId = R.drawable.ill_winter_card2_120_106, cards3ResId = R.drawable.ill_winter_card3_120_106, diff --git a/features/wallet/impl/src/main/res/drawable/ill_cashclubgold_card2_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_cashclubgold_card2_120_106.webp new file mode 100644 index 0000000000..d32f072b9b Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_cashclubgold_card2_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_cashclubgold_card3_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_cashclubgold_card3_120_106.webp new file mode 100644 index 0000000000..52bf5cd3e5 Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_cashclubgold_card3_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_changenow_card2_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_changenow_card2_120_106.webp new file mode 100644 index 0000000000..655e5b0fae Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_changenow_card2_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_changenow_card3_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_changenow_card3_120_106.webp new file mode 100644 index 0000000000..f9708fde10 Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_changenow_card3_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_hodl_card2_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_hodl_card2_120_106.webp new file mode 100644 index 0000000000..9f27e2fdc2 Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_hodl_card2_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_hodl_card3_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_hodl_card3_120_106.webp new file mode 100644 index 0000000000..7961215c48 Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_hodl_card3_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_kango_card2_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_kango_card2_120_106.webp new file mode 100644 index 0000000000..8565e7b9dd Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_kango_card2_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_kango_card3_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_kango_card3_120_106.webp new file mode 100644 index 0000000000..0dd2093311 Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_kango_card3_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_kroak_card2_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_kroak_card2_120_106.webp new file mode 100644 index 0000000000..5aeca16b01 Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_kroak_card2_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_kroak_card3_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_kroak_card3_120_106.webp new file mode 100644 index 0000000000..eca80dd09e Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_kroak_card3_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_passimpay_cards2_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_passimpay_cards2_120_106.webp new file mode 100644 index 0000000000..44ec13507a Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_passimpay_cards2_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_passimpay_cards3_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_passimpay_cards3_120_106.webp new file mode 100644 index 0000000000..4f0885d01e Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_passimpay_cards3_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_rizo_card2_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_rizo_card2_120_106.webp new file mode 100644 index 0000000000..b1b4993e6e Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_rizo_card2_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_rizo_card3_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_rizo_card3_120_106.webp new file mode 100644 index 0000000000..d9e39e39d2 Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_rizo_card3_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_sincity_card2_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_sincity_card2_120_106.webp new file mode 100644 index 0000000000..9af2c6e8e1 Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_sincity_card2_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_sincity_card3_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_sincity_card3_120_106.webp new file mode 100644 index 0000000000..dceee4bd4b Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_sincity_card3_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_vnish_card2_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_vnish_card2_120_106.webp new file mode 100644 index 0000000000..4d7876d76d Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_vnish_card2_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_vnish_card3_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_vnish_card3_120_106.webp new file mode 100644 index 0000000000..a627760725 Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_vnish_card3_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_wildgoat_card2_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_wildgoat_card2_120_106.webp new file mode 100644 index 0000000000..ab0aed4ed9 Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_wildgoat_card2_120_106.webp differ diff --git a/features/wallet/impl/src/main/res/drawable/ill_wildgoat_card3_120_106.webp b/features/wallet/impl/src/main/res/drawable/ill_wildgoat_card3_120_106.webp new file mode 100644 index 0000000000..4169f0d9f1 Binary files /dev/null and b/features/wallet/impl/src/main/res/drawable/ill_wildgoat_card3_120_106.webp differ diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml index dc1d8b9ca6..00a9fc9386 100644 --- a/gradle/dependencies.toml +++ b/gradle/dependencies.toml @@ -7,6 +7,7 @@ androidGradlePlugin = "8.2.2" firebaseCrashlytics = "3.0.1" googleServices = "4.4.1" kotlin = "1.9.22" +firebasePerf = "1.4.2" # endregion Classpath # region AndroidX @@ -45,7 +46,7 @@ coil = "2.1.0" compose-shimmer = "1.0.3" coroutine = "1.7.2" desugarJdkLibs = "1.1.5" -firebase = "33.1.0" +firebase = "33.7.0" googleMaterialComponent = "1.6.1" googlePlayReview = "2.0.1" googlePlayReviewKtx = "2.0.1" @@ -88,7 +89,7 @@ markdownComposeView = "0.5.4" # endregion Other libraries # region Tangem -tangemBlockchainSdk = "release-app_5.20-915" +tangemBlockchainSdk = "release-app_5.20-916" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds tangemCardSdk = "release-app_5.20-423" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^ @@ -122,6 +123,7 @@ kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", versi android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" } android-library = { id = "com.android.library", version.ref = "androidGradlePlugin" } firebase-crashlytics = { id = "com.google.firebase.crashlytics", version.ref = "firebaseCrashlytics" } +firebase-perf = { id = "com.google.firebase.firebase-perf", version.ref = "firebasePerf" } google-services = { id = "com.google.gms.google-services", version.ref = "googleServices" } hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "hilt" } detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" } @@ -182,6 +184,7 @@ firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "fir firebase-analytics = { module = "com.google.firebase:firebase-analytics-ktx" } firebase-crashlytics = { module = "com.google.firebase:firebase-crashlytics-ktx" } firebase-messaging = { module = "com.google.firebase:firebase-messaging-ktx" } +firebase-perf = { module = "com.google.firebase:firebase-perf" } # endregion Firebase # region Tangem