diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index 36fcd97572..be1837114f 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -18,6 +18,7 @@ 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.BasicTopUpFilter 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 @@ -127,6 +128,7 @@ class TapApplication : Application(), ImageLoaderFactory { listOf( ShopPurchasedEventFilter(), BasicSignInFilter(), + BasicTopUpFilter(preferencesStorage.toppedUpWalletStorage), ).forEach { Analytics.addFilter(it) } } diff --git a/app/src/main/java/com/tangem/tap/common/analytics/converters/BasicEventConverter.kt b/app/src/main/java/com/tangem/tap/common/analytics/converters/BasicEventConverter.kt new file mode 100644 index 0000000000..3950f458bc --- /dev/null +++ b/app/src/main/java/com/tangem/tap/common/analytics/converters/BasicEventConverter.kt @@ -0,0 +1,76 @@ +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.common.analytics.filters.BasicTopUpFilter +import com.tangem.tap.domain.extensions.getUserWalletId +import com.tangem.tap.domain.extensions.isMultiwalletAllowed +import com.tangem.tap.features.wallet.redux.ProgressState +import com.tangem.tap.features.wallet.redux.WalletData +import com.tangem.tap.features.wallet.redux.WalletState +import com.tangem.tap.features.wallet.redux.reducers.calculateTotalCryptoAmount + +/** +[REDACTED_AUTHOR] + */ +class BasicSignInEventConverter( + private val scanResponse: ScanResponse, +) : Converter { + + override fun convert(value: WalletState): Basic.SignedIn? { + if (!statesIsReadyToCreateEvent(scanResponse, value)) return null + val cardCurrency = ParamCardCurrencyConverter().convert(scanResponse) ?: return null + + return Basic.SignedIn( + state = AnalyticsParam.CardBalanceState.from(value.walletsData), + currency = cardCurrency, + batch = scanResponse.card.batchId, + ).apply { + filterData = scanResponse.card.getUserWalletId() + } + } +} + +class BasicTopUpEventConverter( + private val scanResponse: ScanResponse, +) : Converter { + + override fun convert(value: WalletState): Basic.ToppedUp? { + if (!statesIsReadyToCreateEvent(scanResponse, value)) return null + val cardCurrency = ParamCardCurrencyConverter().convert(scanResponse) ?: return null + + val data = BasicTopUpFilter.Data( + walletId = scanResponse.card.getUserWalletId(), + cardBalanceState = AnalyticsParam.CardBalanceState.from(value.walletsData), + ) + + return Basic.ToppedUp(cardCurrency).apply { filterData = data } + } +} + +private fun AnalyticsParam.CardBalanceState.Companion.from(walletsData: List): AnalyticsParam.CardBalanceState { + val totalCryptoAmount = walletsData.calculateTotalCryptoAmount() + return when { + totalCryptoAmount.isZero() -> AnalyticsParam.CardBalanceState.Empty + else -> AnalyticsParam.CardBalanceState.Full + } +} + +private fun statesIsReadyToCreateEvent(scanResponse: ScanResponse, state: WalletState): Boolean { + if (scanResponse.card.isMultiwalletAllowed && state.missingDerivations.isNotEmpty()) return false + if (state.walletsData.isEmpty()) return false + + val totalBalanceState = state.totalBalance?.state ?: return false + if (totalBalanceState == ProgressState.Loading || totalBalanceState == ProgressState.Refreshing) return false + + val balancesCount = state.walletsData.map { + if (it.currencyData.amount == null) 0 else 1 + }.reduce { acc, i -> acc + i } + + if (balancesCount != state.wallets.size) return false + + return true +} \ No newline at end of file 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 deleted file mode 100644 index 083fd47f08..0000000000 --- a/app/src/main/java/com/tangem/tap/common/analytics/converters/BasicSignInEventConverter.kt +++ /dev/null @@ -1,38 +0,0 @@ -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.extensions.getUserWalletId -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 = scanResponse.card.getUserWalletId() - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/analytics/events/AnalyticsParam.kt b/app/src/main/java/com/tangem/tap/common/analytics/events/AnalyticsParam.kt index 08cc1d9e5b..71e6eb6c09 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/events/AnalyticsParam.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/events/AnalyticsParam.kt @@ -18,9 +18,10 @@ sealed class AnalyticsParam { class SingleCurrency(type: CurrencyType) : CardCurrency(type.value) } - sealed class CardState(val value: String) { - object Empty : CardState("Empty") - object Full : CardState("Full") + sealed class CardBalanceState(val value: String) { + object Empty : CardBalanceState("Empty") + object Full : CardBalanceState("Full") + companion object } sealed class RateApp(val value: String) { 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 cba32f8061..f1e3927530 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 @@ -9,7 +9,7 @@ sealed class Basic( ) : AnalyticsEvent("Basic", event, params) { class SignedIn( - state: AnalyticsParam.CardState, + state: AnalyticsParam.CardBalanceState, currency: AnalyticsParam.CardCurrency, batch: String, ) : Basic( diff --git a/app/src/main/java/com/tangem/tap/common/analytics/filters/BasicTopUpFilter.kt b/app/src/main/java/com/tangem/tap/common/analytics/filters/BasicTopUpFilter.kt new file mode 100644 index 0000000000..5b0638231e --- /dev/null +++ b/app/src/main/java/com/tangem/tap/common/analytics/filters/BasicTopUpFilter.kt @@ -0,0 +1,50 @@ +package com.tangem.tap.common.analytics.filters + +import com.tangem.common.extensions.guard +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.AnalyticsParam +import com.tangem.tap.common.analytics.events.Basic +import com.tangem.tap.persistence.ToppedUpWalletStorage + +/** +[REDACTED_AUTHOR] + */ +class BasicTopUpFilter( + private val topupWalletStorage: ToppedUpWalletStorage, +) : AnalyticsEventFilter { + + override fun canBeAppliedTo(event: AnalyticsEvent): Boolean = event is Basic.ToppedUp + + override fun canBeSent(event: AnalyticsEvent): Boolean { + val data = event.filterData as? Data ?: return false + + val walletInfo = topupWalletStorage.restore(data.walletId).guard { + val newWalletInfo = Data( + walletId = data.walletId, + cardBalanceState = data.cardBalanceState, + ) + topupWalletStorage.save(newWalletInfo) + return false + } + + if (walletInfo.isToppedUp) return false + + return if (!walletInfo.isToppedUp && data.isToppedUp) { + topupWalletStorage.save(walletInfo.copy(cardBalanceState = AnalyticsParam.CardBalanceState.Full)) + true + } else { + false + } + } + + override fun canBeConsumedBy(handler: AnalyticsEventHandler, event: AnalyticsEvent): Boolean = true + + data class Data( + val walletId: String, + val cardBalanceState: AnalyticsParam.CardBalanceState, + ) { + val isToppedUp: Boolean = cardBalanceState == AnalyticsParam.CardBalanceState.Full + } +} \ 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 b44dcebc1d..544d94e6ca 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 @@ -18,6 +18,7 @@ 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.converters.BasicTopUpEventConverter import com.tangem.tap.common.analytics.events.MainScreen import com.tangem.tap.common.analytics.events.Portfolio import com.tangem.tap.common.extensions.show @@ -34,7 +35,6 @@ 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 @@ -231,13 +231,9 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber = mutableSetOf() + + init { + walletList.addAll(restore()) + } + + fun save(userWalletInfo: BasicTopUpFilter.Data): Boolean { + walletList.removeAll { it.walletId == userWalletInfo.walletId } + walletList.add(userWalletInfo) + return save(walletList) + } + + fun restore(walletId: String): BasicTopUpFilter.Data? { + return walletList.firstOrNull { it.walletId == walletId } + } + + private fun save(userWallets: MutableSet): Boolean { + return try { + val json = jsonConverter.toJson(userWallets) + preferences.edit(true) { putString(KEY, json) } + true + } catch (ex: Exception) { + Timber.e(ex) + false + } + } + + private fun restore(): MutableSet { + val json = preferences.getString(KEY, null) ?: return mutableSetOf() + return try { + jsonConverter.fromJson(json, jsonConverter.typedList(BasicTopUpFilter.Data::class.java))!! + } catch (ex: Exception) { + preferences.edit(true) { remove(KEY) } + mutableSetOf() + } + } + + companion object { + private const val KEY = "userWalletsInfo" + } +} \ No newline at end of file