diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index 5417042486..36fcd97572 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -17,6 +17,7 @@ import com.tangem.tap.common.AssetReader import com.tangem.tap.common.analytics.Analytics import com.tangem.tap.common.analytics.AnalyticsHandlersFactory import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder +import com.tangem.tap.common.analytics.filters.BasicSignInFilter import com.tangem.tap.common.analytics.filters.ShopPurchasedEventFilter import com.tangem.tap.common.analytics.handlers.amplitude.AmplitudeAnalyticsHandler import com.tangem.tap.common.analytics.handlers.appsFlyer.AppsFlyerAnalyticsHandler @@ -125,6 +126,7 @@ class TapApplication : Application(), ImageLoaderFactory { } listOf( ShopPurchasedEventFilter(), + BasicSignInFilter(), ).forEach { Analytics.addFilter(it) } } diff --git a/app/src/main/java/com/tangem/tap/common/analytics/converters/BasicSignInEventConverter.kt b/app/src/main/java/com/tangem/tap/common/analytics/converters/BasicSignInEventConverter.kt new file mode 100644 index 0000000000..e3d07461d0 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/common/analytics/converters/BasicSignInEventConverter.kt @@ -0,0 +1,38 @@ +package com.tangem.tap.common.analytics.converters + +import com.tangem.common.Converter +import com.tangem.common.extensions.isZero +import com.tangem.domain.common.ScanResponse +import com.tangem.tap.common.analytics.events.AnalyticsParam +import com.tangem.tap.common.analytics.events.Basic +import com.tangem.tap.domain.tokens.UserWalletId +import com.tangem.tap.features.wallet.redux.ProgressState +import java.math.BigDecimal + +/** +[REDACTED_AUTHOR] + */ +class BasicSignInEventConverter( + private val scanResponse: ScanResponse, + private val progressState: ProgressState, + private val totalCryptoAmount: BigDecimal, +) : Converter { + + override fun convert(value: Any?): Basic.SignedIn? { + if (progressState == ProgressState.Loading || progressState == ProgressState.Refreshing) return null + val cardCurrency = ParamCardCurrencyConverter().convert(scanResponse) ?: return null + + val cardState = when { + totalCryptoAmount.isZero() -> AnalyticsParam.CardState.Empty + else -> AnalyticsParam.CardState.Full + } + + return Basic.SignedIn( + state = cardState, + currency = cardCurrency, + batch = scanResponse.card.batchId, + ).apply { + filterData = UserWalletId(scanResponse.card.wallets.first().publicKey).stringValue + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/analytics/converters/ParamCardCurrencyConverter.kt b/app/src/main/java/com/tangem/tap/common/analytics/converters/ParamCardCurrencyConverter.kt new file mode 100644 index 0000000000..e64b751f4f --- /dev/null +++ b/app/src/main/java/com/tangem/tap/common/analytics/converters/ParamCardCurrencyConverter.kt @@ -0,0 +1,31 @@ +package com.tangem.tap.common.analytics.converters + +import com.tangem.blockchain.common.Blockchain +import com.tangem.common.Converter +import com.tangem.domain.common.SaltPayWorkaround +import com.tangem.domain.common.ScanResponse +import com.tangem.domain.common.TapWorkarounds.getTangemNoteBlockchain +import com.tangem.tap.common.analytics.events.AnalyticsParam +import com.tangem.tap.domain.extensions.isMultiwalletAllowed + +/** +[REDACTED_AUTHOR] + */ +class ParamCardCurrencyConverter : Converter { + + override fun convert(value: ScanResponse): AnalyticsParam.CardCurrency? { + if (value.card.isMultiwalletAllowed) return AnalyticsParam.CardCurrency.MultiCurrency + + val type = when { + value.isTangemNote() -> { + value.card.getTangemNoteBlockchain()?.let { AnalyticsParam.CurrencyType.Blockchain(it) } + } + value.isTangemTwins() -> AnalyticsParam.CurrencyType.Blockchain(Blockchain.Bitcoin) + value.isSaltPay() -> AnalyticsParam.CurrencyType.Token(SaltPayWorkaround.tokenFrom(Blockchain.SaltPay)) + value.getPrimaryToken() != null -> AnalyticsParam.CurrencyType.Token(value.getPrimaryToken()!!) + else -> null + } ?: return null + + return AnalyticsParam.CardCurrency.SingleCurrency(type) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/analytics/events/AnalyticsEvent.kt b/app/src/main/java/com/tangem/tap/common/analytics/events/AnalyticsEvent.kt index 0451fdd68c..8e5cf0e942 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/events/AnalyticsEvent.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/events/AnalyticsEvent.kt @@ -7,4 +7,5 @@ sealed class AnalyticsEvent( val category: String, val event: String, val params: Map = mapOf(), + var filterData: Any? = null, ) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/analytics/events/Basic.kt b/app/src/main/java/com/tangem/tap/common/analytics/events/Basic.kt index bb37145672..cba32f8061 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/events/Basic.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/events/Basic.kt @@ -8,7 +8,7 @@ sealed class Basic( params: Map = mapOf(), ) : AnalyticsEvent("Basic", event, params) { - sealed class SignedIn( + class SignedIn( state: AnalyticsParam.CardState, currency: AnalyticsParam.CardCurrency, batch: String, diff --git a/app/src/main/java/com/tangem/tap/common/analytics/filters/BasicSignInFilter.kt b/app/src/main/java/com/tangem/tap/common/analytics/filters/BasicSignInFilter.kt new file mode 100644 index 0000000000..c885cf7ae6 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/common/analytics/filters/BasicSignInFilter.kt @@ -0,0 +1,27 @@ +package com.tangem.tap.common.analytics.filters + +import com.tangem.tap.common.analytics.api.AnalyticsEventFilter +import com.tangem.tap.common.analytics.api.AnalyticsEventHandler +import com.tangem.tap.common.analytics.events.AnalyticsEvent +import com.tangem.tap.common.analytics.events.Basic + +/** +[REDACTED_AUTHOR] + */ +class BasicSignInFilter : AnalyticsEventFilter { + + private val alreadySignedIn = mutableSetOf() + + override fun canBeAppliedTo(event: AnalyticsEvent): Boolean = event is Basic.SignedIn + + override fun canBeSent(event: AnalyticsEvent): Boolean { + val userWalletId = event.filterData as? String ?: return false + + val canBeSent = !alreadySignedIn.contains(userWalletId) + alreadySignedIn.add(userWalletId) + + return canBeSent + } + + override fun canBeConsumedBy(handler: AnalyticsEventHandler, event: AnalyticsEvent): Boolean = true +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/TotalBalanceOperations.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/TotalBalanceOperations.kt index 15e44ea361..79470dae62 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/TotalBalanceOperations.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/TotalBalanceOperations.kt @@ -17,6 +17,12 @@ fun List.calculateTotalFiatAmount(): BigDecimal { .reduce(BigDecimal::plus) } +fun List.calculateTotalCryptoAmount(): BigDecimal { + return this + .map { it.currencyData.amount ?: BigDecimal.ZERO } + .reduce(BigDecimal::plus) +} + private fun List.mapToProgressState(): List { return this.map { wallet -> if (wallet.fiatRate == null) ProgressState.Error @@ -25,12 +31,15 @@ private fun List.mapToProgressState(): List { BalanceStatus.VerifiedOnline, BalanceStatus.SameCurrencyTransactionInProgress, BalanceStatus.TransactionInProgress, - BalanceStatus.NoAccount -> ProgressState.Done + BalanceStatus.NoAccount, + -> ProgressState.Done BalanceStatus.Unreachable, BalanceStatus.EmptyCard, - BalanceStatus.UnknownBlockchain -> ProgressState.Error + BalanceStatus.UnknownBlockchain, + -> ProgressState.Error BalanceStatus.Loading, - null -> ProgressState.Loading + null, + -> ProgressState.Loading } } } @@ -41,20 +50,24 @@ private infix fun ProgressState.or(newState: ProgressState): ProgressState { ProgressState.Loading, ProgressState.Refreshing, ProgressState.Error, - ProgressState.Done -> this + ProgressState.Done, + -> this } ProgressState.Done, - ProgressState.Error -> when (newState) { + ProgressState.Error, + -> when (newState) { ProgressState.Loading, ProgressState.Refreshing, - ProgressState.Error -> newState + ProgressState.Error, + -> newState ProgressState.Done -> this } ProgressState.Refreshing -> when (newState) { ProgressState.Loading -> this ProgressState.Refreshing, ProgressState.Error, - ProgressState.Done -> newState + ProgressState.Done, + -> newState } } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt index 97fba31222..b44dcebc1d 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt @@ -17,6 +17,7 @@ import coil.size.Scale import com.tangem.domain.common.TapWorkarounds.isSaltPay import com.tangem.tap.MainActivity import com.tangem.tap.common.analytics.Analytics +import com.tangem.tap.common.analytics.converters.BasicSignInEventConverter import com.tangem.tap.common.analytics.events.MainScreen import com.tangem.tap.common.analytics.events.Portfolio import com.tangem.tap.common.extensions.show @@ -33,6 +34,7 @@ import com.tangem.tap.features.wallet.redux.ErrorType import com.tangem.tap.features.wallet.redux.ProgressState import com.tangem.tap.features.wallet.redux.WalletAction import com.tangem.tap.features.wallet.redux.WalletState +import com.tangem.tap.features.wallet.redux.reducers.calculateTotalCryptoAmount import com.tangem.tap.features.wallet.ui.adapters.WarningMessagesAdapter import com.tangem.tap.features.wallet.ui.wallet.MultiWalletView import com.tangem.tap.features.wallet.ui.wallet.SaltPaySingleWalletView @@ -119,6 +121,7 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber