diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index 05634eb5fb..42d008074f 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -22,10 +22,10 @@ import com.tangem.domain.common.LogConfig import com.tangem.tap.common.IntentHandler import com.tangem.tap.common.analytics.AnalyticsFactory import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder -import com.tangem.tap.common.analytics.filters.BasicTopUpFilter import com.tangem.tap.common.analytics.handlers.amplitude.AmplitudeAnalyticsHandler import com.tangem.tap.common.analytics.handlers.appsFlyer.AppsFlyerAnalyticsHandler import com.tangem.tap.common.analytics.handlers.firebase.FirebaseAnalyticsHandler +import com.tangem.tap.common.analytics.topup.TopUpController import com.tangem.tap.common.chat.ChatManager import com.tangem.tap.common.feedback.AdditionalFeedbackInfo import com.tangem.tap.common.feedback.FeedbackManager @@ -158,6 +158,19 @@ class TapApplication : Application(), ImageLoaderFactory { appStateHolder.mainStore = store appStateHolder.userTokensRepository = userTokensRepository appStateHolder.walletStoresManager = walletStoresManager + initTopUpController() + } + + private fun initTopUpController() { + val topUpController = TopUpController( + scanResponseProvider = { + store.state.globalState.scanResponse + ?: store.state.globalState.onboardingState.onboardingManager?.scanResponse + }, + walletStoresManagerProvider = { walletStoresManager }, + topupWalletStorage = preferencesStorage.toppedUpWalletStorage, + ) + store.dispatch(GlobalAction.SetTopUpController(topUpController)) } override fun newImageLoader(): ImageLoader { @@ -186,8 +199,6 @@ class TapApplication : Application(), ImageLoaderFactory { factory.addHandlerBuilder(AppsFlyerAnalyticsHandler.Builder()) factory.addHandlerBuilder(FirebaseAnalyticsHandler.Builder()) - factory.addFilter(BasicTopUpFilter(preferencesStorage.toppedUpWalletStorage)) - val buildData = AnalyticsHandlerBuilder.Data( application = application, config = config, 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 deleted file mode 100644 index 1e1f9894c8..0000000000 --- a/app/src/main/java/com/tangem/tap/common/analytics/converters/BasicEventConverter.kt +++ /dev/null @@ -1,174 +0,0 @@ -package com.tangem.tap.common.analytics.converters - -import com.tangem.common.Converter -import com.tangem.common.extensions.isZero -import com.tangem.core.analytics.Analytics -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.model.WalletDataModel -import com.tangem.tap.domain.model.builders.UserWalletIdBuilder -import com.tangem.tap.features.wallet.redux.ProgressState -import com.tangem.tap.features.wallet.redux.WalletState -import com.tangem.tap.features.wallet.redux.reducers.calculateTotalCryptoAmount -import timber.log.Timber -import java.math.BigDecimal - -/** -[REDACTED_AUTHOR] - */ -class BasicEventsPreChecker { - - fun tryToSend(converterData: BasicEventsSourceData) { - if (!isReadyToSend(converterData)) return - - BasicTopUpEventConverter().convert(converterData)?.let { Analytics.send(it) } - } - - @Suppress("ComplexMethod") - private fun isReadyToSend(data: BasicEventsSourceData): Boolean { - val (scanResponse, walletState, biometricsWalletDataModels) = data - if (walletState.derivationsCheckIsScheduled) { - Timber.d("FAILED: derivationsCheckIsScheduled") - return false - } - if (scanResponse.cardTypesResolver.isMultiwalletAllowed() && walletState.missingDerivations.isNotEmpty()) { - Timber.d("FAILED: isMultiwalletAllowed || missingDerivations.isNotEmpty") - return false - } - - if (biometricsWalletDataModels == null) { - Timber.d("SWITCH: OLD") - val walletsDataFromStores = data.walletState.walletsDataFromStores - if (walletsDataFromStores.isEmpty()) { - Timber.d("FAILED: walletsDataFromStores.isEmpty") - return false - } - - val totalBalanceState = data.walletState.totalBalance?.state - if (totalBalanceState == null || totalBalanceState == ProgressState.Loading || - totalBalanceState == ProgressState.Refreshing - ) { - Timber.d("FAILED: totalBalanceState: ${totalBalanceState?.name}") - return false - } - - val balancesCount = walletsDataFromStores - .map { if (it.currencyData.amount == null) 0 else 1 } - .reduce { acc, i -> acc + i } - - if (balancesCount != walletsDataFromStores.size) { - Timber.d("FAILED: balancesCount != walletsDataFromStores.size") - return false - } - } else { - Timber.d("SWITCH: BIOMETRICS") - if (biometricsWalletDataModels.isEmpty()) { - Timber.d("FAILED: biometricsWalletDataModels.isEmpty") - return false - } - - val isCorrectStatus = biometricsWalletDataModels.any { - it.status is WalletDataModel.Loading || - it.status is WalletDataModel.NoAccount || - it.status is WalletDataModel.Unreachable || - it.status is WalletDataModel.MissedDerivation || - it.status.isErrorStatus - } - if (isCorrectStatus) { - Timber.d("FAILED: by status") - return false - } - } - - Timber.d("SUCCESS") - return true - } -} - -/** - * With biometrics enabled, we should check its storage instead of "WalletState.walletsDataFromStores" - * because the latter is updated after some time. - * @property biometricsWalletDataModels - wallet data models from the 'WalletStoresManager'. If null, then - * the "WalletState.walletsDataFromStores" will be used to determine appropriate state - */ -data class BasicEventsSourceData( - val scanResponse: ScanResponse, - val walletState: WalletState, - val biometricsWalletDataModels: List?, -) { - val userWalletIdStringValue: String? by lazy { - UserWalletIdBuilder.scanResponse(scanResponse).build()?.stringValue - } - - val paramCardCurrency: AnalyticsParam.CardCurrency? by lazy { - ParamCardCurrencyConverter().convert(scanResponse.cardTypesResolver) - } - - val paramCardBalanceState: AnalyticsParam.CardBalanceState by lazy { calculateAmount().toCardBalanceState() } - - private fun calculateAmount(): BigDecimal { - val calculator: IBalanceCalculator = biometricsWalletDataModels - ?.let { BiometricsBalanceCalculator(it) } - ?: BalanceCalculator(walletState) - - return calculator.calculate() - } - - private fun BigDecimal.toCardBalanceState(): AnalyticsParam.CardBalanceState = when { - isZero() -> AnalyticsParam.CardBalanceState.Empty - else -> AnalyticsParam.CardBalanceState.Full - } -} - -private interface IBalanceCalculator { - fun calculate(): BigDecimal -} - -private class BiometricsBalanceCalculator( - private val walletDataModel: List, -) : IBalanceCalculator { - - override fun calculate(): BigDecimal { - val singleToken = walletDataModel - .filter { it.currency.isToken() } - .firstOrNull { it.isCardSingleToken } - - val totalAmount = singleToken?.status?.amount - ?: walletDataModel.calculateTotalCryptoAmount() - - return totalAmount - } - - private fun List.calculateTotalCryptoAmount(): BigDecimal = this - .map { it.status.amount } - .reduce(BigDecimal::plus) -} - -private class BalanceCalculator( - private val walletState: WalletState, -) : IBalanceCalculator { - - override fun calculate(): BigDecimal { - val singleTokenData = walletState.primaryTokenData - val totalAmount = singleTokenData?.currencyData?.amount - ?: walletState.walletsDataFromStores.calculateTotalCryptoAmount() - - return totalAmount - } -} - -class BasicTopUpEventConverter : Converter { - - override fun convert(value: BasicEventsSourceData): Basic.ToppedUp? { - if (value.paramCardCurrency == null || value.userWalletIdStringValue == null) return null - - val data = BasicTopUpFilter.Data( - walletId = value.userWalletIdStringValue!!, - cardBalanceState = value.paramCardBalanceState, - ) - - return Basic.ToppedUp(value.paramCardCurrency!!).apply { filterData = data } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/analytics/converters/TopUpConverter.kt b/app/src/main/java/com/tangem/tap/common/analytics/converters/TopUpConverter.kt new file mode 100644 index 0000000000..429b2e5ebc --- /dev/null +++ b/app/src/main/java/com/tangem/tap/common/analytics/converters/TopUpConverter.kt @@ -0,0 +1,17 @@ +package com.tangem.tap.common.analytics.converters + +import com.tangem.common.Converter +import com.tangem.domain.common.CardTypesResolver +import com.tangem.tap.common.analytics.events.Basic + +/** +[REDACTED_AUTHOR] + */ +class TopUpEventConverter : Converter { + + override fun convert(value: CardTypesResolver): Basic.ToppedUp? { + val paramCardCurrency = ParamCardCurrencyConverter().convert(value) ?: return null + + return Basic.ToppedUp(paramCardCurrency) + } +} \ No newline at end of file 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 deleted file mode 100644 index de89bf9e7e..0000000000 --- a/app/src/main/java/com/tangem/tap/common/analytics/filters/BasicTopUpFilter.kt +++ /dev/null @@ -1,50 +0,0 @@ -package com.tangem.tap.common.analytics.filters - -import com.tangem.common.extensions.guard -import com.tangem.core.analytics.api.AnalyticsEventFilter -import com.tangem.core.analytics.api.AnalyticsHandler -import com.tangem.core.analytics.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 canBeConsumedByHandler(handler: AnalyticsHandler, 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/common/analytics/topup/TopUpController.kt b/app/src/main/java/com/tangem/tap/common/analytics/topup/TopUpController.kt new file mode 100644 index 0000000000..e17985be26 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/common/analytics/topup/TopUpController.kt @@ -0,0 +1,195 @@ +package com.tangem.tap.common.analytics.topup + +import com.tangem.common.extensions.guard +import com.tangem.common.extensions.isZero +import com.tangem.core.analytics.Analytics +import com.tangem.domain.common.CardTypesResolver +import com.tangem.domain.common.ScanResponse +import com.tangem.domain.common.util.UserWalletId +import com.tangem.tap.common.analytics.converters.TopUpEventConverter +import com.tangem.tap.common.analytics.events.AnalyticsParam +import com.tangem.tap.common.extensions.copy +import com.tangem.tap.domain.model.UserWallet +import com.tangem.tap.domain.model.WalletDataModel +import com.tangem.tap.domain.model.WalletStoreModel +import com.tangem.tap.domain.model.builders.UserWalletIdBuilder +import com.tangem.tap.domain.tokens.models.BlockchainNetwork +import com.tangem.tap.domain.walletCurrencies.WalletCurrenciesManager +import com.tangem.tap.domain.walletStores.WalletStoresManager +import com.tangem.tap.features.wallet.models.Currency +import com.tangem.tap.features.wallet.redux.ProgressState +import com.tangem.tap.persistence.ToppedUpWalletStorage +import com.tangem.tap.scope +import kotlinx.coroutines.launch +import java.math.BigDecimal + +/** +[REDACTED_AUTHOR] + */ +class TopUpController( + var scanResponseProvider: (() -> ScanResponse?)? = null, + var walletStoresManagerProvider: (() -> WalletStoresManager)? = null, + private val topupWalletStorage: ToppedUpWalletStorage, +) : WalletCurrenciesManager.Listener { + + private var hadMissedDerivations: Boolean = false + private val addedCurrencies = mutableListOf() + + override fun didUpdate(userWallet: UserWallet, currency: Currency) { + tryToSend() + } + + override fun willCurrenciesAdd(userWallet: UserWallet, currenciesToAdd: List) { + addedCurrencies.addAll(currenciesToAdd.distinct()) + } + + fun walletStoresChanged(walletStores: List) { + val missedDerivations = walletStores + .flatMap { it.walletsData } + .map { it.status } + .filterIsInstance() + + hadMissedDerivations = missedDerivations.isNotEmpty() + } + + fun scanToGetDerivations() { + hadMissedDerivations = true + } + + fun addMissingDerivations(blockchains: List) { + hadMissedDerivations = blockchains.isNotEmpty() + } + + fun totalBalanceStateChanged(state: ProgressState) { + if (state == ProgressState.Done) tryToSend() + } + + fun loadDataSuccess() { + tryToSend() + } + + private fun tryToSend() { + if (hadMissedDerivations) return + val scanResponse = scanResponseProvider?.invoke() ?: return + val userWalletId = UserWalletIdBuilder.scanResponse(scanResponse).build() ?: return + val walletStoresManager = walletStoresManagerProvider?.invoke() ?: return + + scope.launch { + val walletDataModels = walletStoresManager.getSync(userWalletId).flatMap { it.walletsData } + if (walletDataModels.isEmpty()) return@launch + + val isCorrectStatus = walletDataModels.any { + it.status is WalletDataModel.Loading || + it.status is WalletDataModel.NoAccount || + it.status is WalletDataModel.Unreachable || + it.status is WalletDataModel.MissedDerivation || + it.status.isErrorStatus + } + if (isCorrectStatus) return@launch + + val isToppedUpInPast = findToppedUpCurrenciesInPast(walletDataModels).isNotEmpty() + if (isToppedUpInPast) { + val newWalletInfo = ToppedUpWalletStorage.TopupInfo( + walletId = userWalletId.stringValue, + cardBalanceState = AnalyticsParam.CardBalanceState.Full, + ) + topupWalletStorage.save(newWalletInfo) + return@launch + } + + val cardBalanceState = BalanceCalculator(walletDataModels).calculate().toCardBalanceState() + send(userWalletId, cardBalanceState, scanResponse.cardTypesResolver) + } + } + + /** + * A UserWalletId registration should be after creating wallets + */ + fun registerEmptyWallet(scanResponse: ScanResponse) { + UserWalletIdBuilder.scanResponse(scanResponse).build()?.let { + topupWalletStorage.save( + ToppedUpWalletStorage.TopupInfo( + walletId = it.stringValue, + cardBalanceState = AnalyticsParam.CardBalanceState.Empty, + ), + ) + } + } + + fun send( + scanResponse: ScanResponse, + cardBalanceState: AnalyticsParam.CardBalanceState, + ) { + UserWalletIdBuilder.scanResponse(scanResponse).build()?.let { + send(it, cardBalanceState, scanResponse.cardTypesResolver) + } + } + + fun send( + userWalletId: UserWalletId, + cardBalanceState: AnalyticsParam.CardBalanceState, + cardTypesResolver: CardTypesResolver, + ) { + val topupInfo = topupWalletStorage.restore(userWalletId.stringValue).guard { + val topupInfo = ToppedUpWalletStorage.TopupInfo( + walletId = userWalletId.stringValue, + cardBalanceState = cardBalanceState, + ) + topupWalletStorage.save(topupInfo) + return + } + if (topupInfo.isToppedUp) return + + if (!topupInfo.isToppedUp && cardBalanceState.isToppedUp()) { + topupWalletStorage.save(topupInfo.copy(cardBalanceState = AnalyticsParam.CardBalanceState.Full)) + TopUpEventConverter().convert(cardTypesResolver)?.let { + Analytics.send(it) + } + } + } + + private fun findToppedUpCurrenciesInPast(walletDataModels: List): List { + val currenciesToppedUpInPast = addedCurrencies.copy() + .mapNotNull { currency -> + val foundCurrencyModel = walletDataModels + .find { it.currency == currency } + ?: return@mapNotNull null + + if (foundCurrencyModel.status.amount.isZero()) null else foundCurrencyModel + } + addedCurrencies.clear() + + return currenciesToppedUpInPast + } + + private fun BigDecimal.toCardBalanceState(): AnalyticsParam.CardBalanceState = when { + isZero() -> AnalyticsParam.CardBalanceState.Empty + else -> AnalyticsParam.CardBalanceState.Full + } + + private fun AnalyticsParam.CardBalanceState.isToppedUp(): Boolean = this == AnalyticsParam.CardBalanceState.Full +} + +private interface IBalanceCalculator { + fun calculate(): BigDecimal +} + +private class BalanceCalculator( + private val walletDataModels: List, +) : IBalanceCalculator { + + override fun calculate(): BigDecimal { + val singleToken = walletDataModels + .filter { it.currency.isToken() } + .firstOrNull { it.isCardSingleToken } + + val totalAmount = singleToken?.status?.amount + ?: walletDataModels.calculateTotalCryptoAmount() + + return totalAmount + } + + private fun List.calculateTotalCryptoAmount(): BigDecimal = this + .map { it.status.amount } + .reduce(BigDecimal::plus) +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Collections.kt b/app/src/main/java/com/tangem/tap/common/extensions/Collections.kt index 8492ae44f1..517d8ca5ed 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Collections.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Collections.kt @@ -28,4 +28,8 @@ fun MutableList.replaceBy(item: T, predicate: (T) -> Boolean): Boolean { fun MutableList.replaceByOrAdd(item: T, predicate: (T) -> Boolean) { if (!replaceBy(item, predicate)) add(item) +} + +fun MutableList.copy(): MutableList { + return this.map { it }.toMutableList() } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt index f0f6e8244c..a140fb2d0c 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt @@ -7,6 +7,7 @@ import com.tangem.common.core.TangemError import com.tangem.datasource.config.ConfigManager import com.tangem.datasource.config.models.ChatConfig import com.tangem.domain.common.ScanResponse +import com.tangem.tap.common.analytics.topup.TopUpController import com.tangem.tap.common.entities.FiatCurrency import com.tangem.tap.common.feedback.FeedbackData import com.tangem.tap.common.feedback.FeedbackManager @@ -88,6 +89,7 @@ sealed class GlobalAction : Action { data class SetConfigManager(val configManager: ConfigManager) : GlobalAction() data class SetWarningManager(val warningManager: WarningMessagesManager) : GlobalAction() data class SetFeedbackManager(val feedbackManager: FeedbackManager) : GlobalAction() + data class SetTopUpController(val topUpController: TopUpController) : GlobalAction() data class SendEmail(val feedbackData: FeedbackData) : GlobalAction() data class OpenChat(val feedbackData: FeedbackData, val chatConfig: ChatConfig? = null) : GlobalAction() diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt index b7fd1db3fe..5d99c5357e 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt @@ -32,6 +32,7 @@ import com.tangem.tap.scope import com.tangem.tap.store import com.tangem.tap.tangemSdkManager import com.tangem.tap.userTokensRepository +import com.tangem.tap.walletCurrenciesManager import com.tangem.wallet.BuildConfig import kotlinx.coroutines.launch import org.rekotlin.Action @@ -194,6 +195,9 @@ private fun handleAction(action: Action, appState: () -> AppState?, dispatch: Di } } } + is GlobalAction.SetTopUpController -> { + walletCurrenciesManager.addListener(action.topUpController) + } } } diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt index 3ed3751c74..15b8d10c94 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt @@ -49,6 +49,7 @@ fun globalReducer(action: Action, state: AppState, appStateHolder: AppStateHolde globalState.copy(configManager = action.configManager) } is GlobalAction.SetWarningManager -> globalState.copy(warningManager = action.warningManager) + is GlobalAction.SetTopUpController -> globalState.copy(topUpController = action.topUpController) is GlobalAction.UpdateWalletSignedHashes -> { val card = globalState.scanResponse?.card ?: return globalState val wallet = card.wallets diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt index 56059c6799..1d6dddf647 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt @@ -2,6 +2,7 @@ package com.tangem.tap.common.redux.global import com.tangem.datasource.config.ConfigManager import com.tangem.domain.common.ScanResponse +import com.tangem.tap.common.analytics.topup.TopUpController import com.tangem.tap.common.entities.FiatCurrency import com.tangem.tap.common.feedback.FeedbackManager import com.tangem.tap.common.redux.StateDialog @@ -28,6 +29,7 @@ data class GlobalState( val exchangeManager: CurrencyExchangeManager = CurrencyExchangeManager.dummy(), val userCountryCode: String? = null, val userWalletsListManager: UserWalletsListManager? = null, + val topUpController: TopUpController? = null, ) : StateType typealias CryptoCurrencyName = String diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index 15a3835869..509cd78033 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -22,7 +22,6 @@ import com.tangem.tap.features.disclaimer.createDisclaimer import com.tangem.tap.features.disclaimer.redux.DisclaimerAction import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction import com.tangem.tap.features.wallet.redux.WalletAction -import com.tangem.tap.features.wallet.redux.middlewares.handleBasicAnalyticsEvent import com.tangem.tap.preferencesStorage import com.tangem.tap.store import com.tangem.tap.tangemSdkManager @@ -67,7 +66,7 @@ class TapWalletManager { .doOnSuccess { Timber.d("Wallet stores fetched for ${userWallet.walletId}") store.dispatchOnMain(WalletAction.LoadData.Success) - handleBasicAnalyticsEvent() + store.state.globalState.topUpController?.loadDataSuccess() } .doOnFailure { error -> val errorAction = when (error) { diff --git a/app/src/main/java/com/tangem/tap/domain/walletCurrencies/WalletCurrenciesManager.kt b/app/src/main/java/com/tangem/tap/domain/walletCurrencies/WalletCurrenciesManager.kt index 2738438ac1..fa2bbc0424 100644 --- a/app/src/main/java/com/tangem/tap/domain/walletCurrencies/WalletCurrenciesManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/walletCurrencies/WalletCurrenciesManager.kt @@ -69,6 +69,31 @@ interface WalletCurrenciesManager { currenciesToRemove: List, ): CompletionResult + /** + * Add a callback [Listener] + * + * @param listener The callback that will add + */ + fun addListener(listener: Listener) + + /** + * Remove a callback [Listener] + * + * @param listener The callback that will removed + */ + fun removeListener(listener: Listener) + + /** + * Interface definition for a callbacks + */ + interface Listener { + fun willUpdate(userWallet: UserWallet, currency: Currency) {} + fun didUpdate(userWallet: UserWallet, currency: Currency) {} + fun willCurrenciesAdd(userWallet: UserWallet, currenciesToAdd: List) {} + fun willCurrenciesRemove(userWallet: UserWallet, currenciesToRemove: List) {} + fun willCurrencyRemove(userWallet: UserWallet, currencyToRemove: Currency) {} + } + // For provider companion object } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/walletCurrencies/implementation/DefaultWalletCurrenciesManager.kt b/app/src/main/java/com/tangem/tap/domain/walletCurrencies/implementation/DefaultWalletCurrenciesManager.kt index 5fe6dd8e22..97d9eb72e5 100644 --- a/app/src/main/java/com/tangem/tap/domain/walletCurrencies/implementation/DefaultWalletCurrenciesManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/walletCurrencies/implementation/DefaultWalletCurrenciesManager.kt @@ -30,23 +30,31 @@ internal class DefaultWalletCurrenciesManager( private val walletManagersRepository: WalletManagersRepository, private val appCurrencyProvider: () -> FiatCurrency, ) : WalletCurrenciesManager { + + private val listeners = mutableListOf() + override suspend fun update( userWallet: UserWallet, currency: Currency, ): CompletionResult = withContext(Dispatchers.Default) { + listeners.forEach { it.willUpdate(userWallet, currency) } val walletStore = walletStoresRepository.getSync(userWallet.walletId) .find { it.blockchain == currency.blockchain && it.derivationPath?.rawPath == currency.derivationPath } - if (walletStore != null) { + val updateResult = if (walletStore == null) { + CompletionResult.Success(Unit) + } else { walletAmountsRepository.updateAmountsForWalletStore( walletStore = walletStore, userWallet = userWallet, fiatCurrency = appCurrencyProvider(), ) - } else CompletionResult.Success(Unit) + } + listeners.forEach { it.didUpdate(userWallet, currency) } + updateResult } override suspend fun addCurrencies( @@ -55,6 +63,7 @@ internal class DefaultWalletCurrenciesManager( ): CompletionResult = withContext(Dispatchers.Default) { val card = userWallet.scanResponse.card val currenciesToAddWithMissingBlockchains = currenciesToAdd.addMissingBlockchainsIfNeeded(card) + listeners.forEach { it.willCurrenciesAdd(userWallet, currenciesToAddWithMissingBlockchains) } updateWalletStores( userWallet = userWallet, @@ -77,6 +86,7 @@ internal class DefaultWalletCurrenciesManager( userWallet: UserWallet, currenciesToRemove: List, ): CompletionResult = withContext(Dispatchers.Default) { + listeners.forEach { it.willCurrenciesRemove(userWallet, currenciesToRemove) } val card = userWallet.scanResponse.card val remainingCurrencies = getSavedCurrencies(userWallet.walletId) .filter { it !in currenciesToRemove } @@ -96,9 +106,18 @@ internal class DefaultWalletCurrenciesManager( userWallet: UserWallet, currencyToRemove: Currency, ): CompletionResult { + listeners.forEach { it.willCurrencyRemove(userWallet, currencyToRemove) } return removeCurrencies(userWallet, listOf(currencyToRemove)) } + override fun addListener(listener: WalletCurrenciesManager.Listener) { + listeners.add(listener) + } + + override fun removeListener(listener: WalletCurrenciesManager.Listener) { + listeners.remove(listener) + } + private suspend fun getSavedCurrencies(userWalletId: UserWalletId): List { return withContext(Dispatchers.Default) { walletStoresRepository.getSync(userWalletId) diff --git a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectRepository.kt b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectRepository.kt index 12df7aeb8e..8a5490c31a 100644 --- a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectRepository.kt +++ b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectRepository.kt @@ -41,7 +41,7 @@ class WalletConnectRepository(val context: Application) { .hexToUtf8() walletConnectAdapter.fromJson(json)!!.map { it.toSession() } } catch (exception: Exception) { - Timber.e(exception) + Timber.w(exception) emptyList() } } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteMiddleware.kt index 8ec11cf17c..fddc46b3a8 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/note/redux/OnboardingNoteMiddleware.kt @@ -6,7 +6,6 @@ import com.tangem.core.analytics.Analytics import com.tangem.domain.common.extensions.withMainContext import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE import com.tangem.tap.common.analytics.events.AnalyticsParam -import com.tangem.tap.common.analytics.events.Basic import com.tangem.tap.common.analytics.events.Onboarding import com.tangem.tap.common.extensions.dispatchDebugErrorNotification import com.tangem.tap.common.extensions.dispatchDialogShow @@ -98,7 +97,7 @@ private fun handleNoteAction(appState: () -> AppState?, action: Action, dispatch onboardingManager.activationFinished(card.cardId) postUi(DELAY_SDK_DIALOG_CLOSE) { store.dispatch(OnboardingNoteAction.Confetti.Show) } } - else -> {} + else -> Unit } } is OnboardingNoteAction.CreateWallet -> { @@ -111,11 +110,10 @@ private fun handleNoteAction(appState: () -> AppState?, action: Action, dispatch val updatedResponse = scanResponse.copy(card = result.data.card) onboardingManager.scanResponse = updatedResponse onboardingManager.activationStarted(updatedResponse.card.cardId) + store.state.globalState.topUpController?.registerEmptyWallet(updatedResponse) store.dispatch(OnboardingNoteAction.SetStepOfScreen(OnboardingNoteStep.TopUpWallet)) } - is CompletionResult.Failure -> { -// do nothing - } + is CompletionResult.Failure -> Unit } } } @@ -160,15 +158,7 @@ private fun handleNoteAction(appState: () -> AppState?, action: Action, dispatch } is OnboardingNoteAction.Balance.Set -> { if (action.balance.balanceIsToppedUp()) { - Analytics.send( - event = Basic.ToppedUp( - currency = AnalyticsParam.CardCurrency.SingleCurrency( - type = AnalyticsParam.CurrencyType.Blockchain( - blockchain = scanResponse.cardTypesResolver.getBlockchain(), - ), - ), - ), - ) + store.state.globalState.topUpController?.send(scanResponse, AnalyticsParam.CardBalanceState.Full) store.dispatch(OnboardingNoteAction.SetStepOfScreen(OnboardingNoteStep.Done)) } } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsMiddleware.kt index faa3dd2441..73312bd8a9 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/otherCards/redux/OnboardingOtherCardsMiddleware.kt @@ -87,6 +87,7 @@ private fun handleOtherCardsAction(action: Action) { val updatedCard = updatedResponse.card onboardingManager.scanResponse = updatedResponse onboardingManager.activationStarted(updatedCard.cardId) + store.state.globalState.topUpController?.registerEmptyWallet(updatedResponse) val primaryBlockchain = updatedResponse.cardTypesResolver.getBlockchain() val blockchainNetworks = if (primaryBlockchain != Blockchain.Unknown) { diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt index f6d021d0f8..e7d4d1edf5 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt @@ -8,7 +8,6 @@ import com.tangem.domain.common.ScanResponse import com.tangem.domain.common.extensions.withMainContext import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE import com.tangem.tap.common.analytics.events.AnalyticsParam -import com.tangem.tap.common.analytics.events.Basic import com.tangem.tap.common.analytics.events.Onboarding import com.tangem.tap.common.extensions.dispatchDebugErrorNotification import com.tangem.tap.common.extensions.dispatchDialogShow @@ -206,6 +205,8 @@ private fun handle(action: Action, dispatch: DispatchFunction) { is Result.Success -> { Analytics.send(Onboarding.Twins.SetupFinished()) updateScanResponse(result.data) + store.state.globalState.topUpController?.registerEmptyWallet(result.data) + delay(DELAY_SDK_DIALOG_CLOSE) withMainContext { when (twinCardsState.mode) { @@ -262,18 +263,8 @@ private fun handle(action: Action, dispatch: DispatchFunction) { } is TwinCardsAction.Balance.Set -> { if (action.balance.balanceIsToppedUp()) { - Analytics.send( - event = Basic.ToppedUp( - currency = AnalyticsParam.CardCurrency.SingleCurrency( - type = AnalyticsParam.CurrencyType.Blockchain( - blockchain = getScanResponse().cardTypesResolver.getBlockchain(), - ), - ), - ), - ) - scope.launch { - withMainContext { store.dispatch(TwinCardsAction.SetStepOfScreen(TwinCardsStep.Done)) } - } + store.state.globalState.topUpController?.send(getScanResponse(), AnalyticsParam.CardBalanceState.Full) + store.dispatchOnMain(TwinCardsAction.SetStepOfScreen(TwinCardsStep.Done)) } } is TwinCardsAction.ShowAddressInfoDialog -> { diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt index 50a9f32619..94fe803ccc 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt @@ -127,6 +127,7 @@ private fun handleWalletAction(action: Action, state: () -> AppState?, dispatch: primaryCard = result.data.primaryCard, ) onboardingManager.scanResponse = updatedResponse + store.state.globalState.topUpController?.registerEmptyWallet(updatedResponse) val blockchainNetworks = if (DemoHelper.isDemoCardId(result.data.card.cardId)) { DemoHelper.config.demoBlockchains @@ -145,9 +146,7 @@ private fun handleWalletAction(action: Action, state: () -> AppState?, dispatch: startCardActivation(updatedResponse) store.dispatch(OnboardingWalletAction.ResumeBackup) } - is CompletionResult.Failure -> { -// do nothing - } + is CompletionResult.Failure -> Unit } } } @@ -190,7 +189,7 @@ private fun handleWalletAction(action: Action, state: () -> AppState?, dispatch: newAction?.let { store.dispatch(it) } } OnboardingWalletAction.OnBackPressed -> handleOnBackPressed(onboardingWalletState) - else -> {} + else -> Unit } } @@ -249,8 +248,7 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction) is CompletionResult.Success -> { store.dispatchOnMain(BackupAction.StartAddingBackupCards) } - is CompletionResult.Failure -> { - } + is CompletionResult.Failure -> Unit } } } @@ -267,8 +265,7 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction) is CompletionResult.Success -> { store.dispatchOnMain(BackupAction.AddBackupCard.Success) } - is CompletionResult.Failure -> { - } + is CompletionResult.Failure -> Unit } } } @@ -308,8 +305,7 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction) is CompletionResult.Success -> { store.dispatchOnMain(BackupAction.PrepareToWriteBackupCard(1)) } - is CompletionResult.Failure -> { - } + is CompletionResult.Failure -> Unit } } } @@ -324,8 +320,7 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction) store.dispatchOnMain(BackupAction.PrepareToWriteBackupCard(action.cardNumber + 1)) } } - is CompletionResult.Failure -> { - } + is CompletionResult.Failure -> Unit } } } @@ -375,7 +370,7 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction) Analytics.send(Onboarding.Finished()) finishCardActivation(notActivatedCardIds) } - else -> {} + else -> Unit } } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt index 81b306448b..45013512af 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt @@ -19,9 +19,6 @@ import com.tangem.tap.store import org.rekotlin.StateType import kotlin.properties.ReadOnlyProperty -/** - * @property derivationsCheckIsScheduled - used only for analytics - */ data class WalletState( val cardId: String = "", val state: ProgressState = ProgressState.Done, @@ -37,7 +34,6 @@ data class WalletState( val totalBalance: TotalBalance? = null, val showBackupWarning: Boolean = false, val missingDerivations: List = emptyList(), - val derivationsCheckIsScheduled: Boolean = false, val loadingUserTokens: Boolean = false, val walletCardsCount: Int? = null, val canSaveUserWallets: Boolean = false, diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt index 2642cbeb50..f2cc59a816 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/MultiWalletMiddleware.kt @@ -91,13 +91,14 @@ class MultiWalletMiddleware { store.dispatch(NavigationAction.NavigateTo(AppScreen.OnboardingWallet)) } is WalletAction.MultiWallet.AddMissingDerivations -> { - scope.launch { handleBasicAnalyticsEvent() } + store.state.globalState.topUpController?.addMissingDerivations(action.blockchains) } is WalletAction.MultiWallet.ScanToGetDerivations -> { val selectedUserWallet = userWalletsListManager.selectedUserWalletSync.guard { Timber.e("Unable to scan to get derivations, no user wallet selected") return } + store.state.globalState.topUpController?.scanToGetDerivations() scanAndUpdateCard(selectedUserWallet, walletState) } else -> {} @@ -108,7 +109,6 @@ class MultiWalletMiddleware { selectedUserWallet: UserWallet, state: WalletState?, ) = scope.launch(Dispatchers.Default) { - dispatchOnMain(WalletAction.MultiWallet.ScheduleCheckForMissingDerivation) tangemSdkManager.scanProduct( cardId = selectedUserWallet.cardId, userTokensRepository = userTokensRepository, diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt index 9b5324ead5..5d12f94a9a 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt @@ -6,8 +6,6 @@ import com.tangem.blockchain.common.AmountType import com.tangem.common.CompletionResult import com.tangem.common.extensions.guard import com.tangem.core.analytics.Analytics -import com.tangem.tap.common.analytics.converters.BasicEventsPreChecker -import com.tangem.tap.common.analytics.converters.BasicEventsSourceData import com.tangem.tap.common.analytics.events.AnalyticsParam import com.tangem.tap.common.analytics.events.Basic import com.tangem.tap.common.analytics.events.MainScreen @@ -25,7 +23,6 @@ import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.domain.TapError import com.tangem.tap.domain.model.WalletDataModel import com.tangem.tap.domain.model.WalletStoreModel -import com.tangem.tap.domain.model.builders.UserWalletIdBuilder import com.tangem.tap.domain.userWalletList.lockIfLockable import com.tangem.tap.features.demo.DemoHelper import com.tangem.tap.features.home.redux.HomeAction @@ -46,7 +43,6 @@ import com.tangem.tap.tangemSdkManager import com.tangem.tap.totalFiatBalanceCalculator import com.tangem.tap.userWalletsListManager import com.tangem.tap.userWalletsListManagerSafe -import com.tangem.tap.walletStoresManager import com.tangem.wallet.R import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay @@ -188,7 +184,7 @@ class WalletMiddleware { } is WalletAction.UserWalletChanged -> Unit is WalletAction.WalletStoresChanged -> { - store.dispatchOnMain(WalletAction.MultiWallet.ScheduleCheckForMissingDerivation) + store.state.globalState.topUpController?.walletStoresChanged(action.walletStores) updateWalletStores(action.walletStores, walletState) fetchTotalFiatBalance(action.walletStores) findMissedDerivations(action.walletStores) @@ -351,23 +347,4 @@ class WalletMiddleware { tokenRate = tokenRate, ) } -} - -suspend fun handleBasicAnalyticsEvent() { - val scanResponse = store.state.globalState.scanResponse ?: return - - val biometricsWalletDataModels = if (preferencesStorage.shouldSaveUserWallets) { - UserWalletIdBuilder.scanResponse(scanResponse).build()?.let { userWalletId -> - walletStoresManager.getSync(userWalletId).map { it.walletsData }.flatten() - } - } else { - null - } - - val converterData = BasicEventsSourceData( - scanResponse = scanResponse, - walletState = store.state.walletState, - biometricsWalletDataModels = biometricsWalletDataModels, - ) - BasicEventsPreChecker().tryToSend(converterData) } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt index 2dcfeaf198..12d2923899 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/reducers/MultiWalletReducer.kt @@ -15,12 +15,8 @@ class MultiWalletReducer { state.copy(selectedCurrency = action.currency) } is WalletAction.MultiWallet.TryToRemoveWallet -> state - is WalletAction.MultiWallet.ScheduleCheckForMissingDerivation -> state.copy( - derivationsCheckIsScheduled = true, - ) is WalletAction.MultiWallet.AddMissingDerivations -> state.copy( missingDerivations = action.blockchains, - derivationsCheckIsScheduled = false, ) is WalletAction.MultiWallet.BackupWallet -> state is WalletAction.MultiWallet.ScanToGetDerivations -> state.copy(state = ProgressState.Loading) 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 fae5543edf..f3a6eba304 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 androidx.transition.TransitionInflater import by.kirich1409.viewbindingdelegate.viewBinding import coil.load import coil.size.Scale +import com.badoo.mvicore.modelWatcher import com.tangem.core.analytics.Analytics import com.tangem.core.ui.fragments.setStatusBarColor import com.tangem.core.ui.utils.OneTouchClickListener @@ -63,6 +64,14 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber() + private val totalBalanceWatcher = modelWatcher { + (WalletState::totalBalance) { totalBalance -> + totalBalance?.state?.let { + store.state.globalState.topUpController?.totalBalanceStateChanged(it) + } + } + } + override fun onAttach(context: Context) { super.onAttach(context) lifecycle.addObserver(viewModel) @@ -167,6 +176,7 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber {} // we keep the same view unless we scan a card that requires a different view } + totalBalanceWatcher.invoke(state) walletView.swapInteractor = swapInteractor diff --git a/app/src/main/java/com/tangem/tap/persistence/ToppedUpWalletStorage.kt b/app/src/main/java/com/tangem/tap/persistence/ToppedUpWalletStorage.kt index 75759b8d75..892b1a2370 100644 --- a/app/src/main/java/com/tangem/tap/persistence/ToppedUpWalletStorage.kt +++ b/app/src/main/java/com/tangem/tap/persistence/ToppedUpWalletStorage.kt @@ -3,7 +3,7 @@ package com.tangem.tap.persistence import android.content.SharedPreferences import androidx.core.content.edit import com.tangem.common.json.MoshiJsonConverter -import com.tangem.tap.common.analytics.filters.BasicTopUpFilter +import com.tangem.tap.common.analytics.events.AnalyticsParam import timber.log.Timber /** @@ -14,23 +14,23 @@ class ToppedUpWalletStorage( private val jsonConverter: MoshiJsonConverter, ) { - private val walletList: MutableSet = mutableSetOf() + private val walletList: MutableSet = mutableSetOf() init { walletList.addAll(restore()) } - fun save(userWalletInfo: BasicTopUpFilter.Data): Boolean { + fun save(userWalletInfo: TopupInfo): Boolean { walletList.removeAll { it.walletId == userWalletInfo.walletId } walletList.add(userWalletInfo) return save(walletList) } - fun restore(walletId: String): BasicTopUpFilter.Data? { + fun restore(walletId: String): TopupInfo? { return walletList.firstOrNull { it.walletId == walletId } } - private fun save(userWallets: MutableSet): Boolean { + private fun save(userWallets: MutableSet): Boolean { return try { val json = jsonConverter.toJson(userWallets) preferences.edit(true) { putString(KEY, json) } @@ -41,11 +41,11 @@ class ToppedUpWalletStorage( } } - private fun restore(): MutableSet { + private fun restore(): MutableSet { val json = preferences.getString(KEY, null) ?: return mutableSetOf() return try { - val typedList = jsonConverter.typedList(BasicTopUpFilter.Data::class.java) - val listData = jsonConverter.fromJson>(json, typedList)!! + val typedList = jsonConverter.typedList(TopupInfo::class.java) + val listData = jsonConverter.fromJson>(json, typedList)!! listData.toMutableSet() } catch (ex: Exception) { preferences.edit(true) { remove(KEY) } @@ -53,6 +53,13 @@ class ToppedUpWalletStorage( } } + data class TopupInfo( + val walletId: String, + val cardBalanceState: AnalyticsParam.CardBalanceState, + ) { + val isToppedUp: Boolean = cardBalanceState == AnalyticsParam.CardBalanceState.Full + } + companion object { private const val KEY = "userWalletsInfo" } diff --git a/core/analytics/src/main/java/com/tangem/core/analytics/AnalyticsEvent.kt b/core/analytics/src/main/java/com/tangem/core/analytics/AnalyticsEvent.kt index e23a503460..1fbc89d977 100644 --- a/core/analytics/src/main/java/com/tangem/core/analytics/AnalyticsEvent.kt +++ b/core/analytics/src/main/java/com/tangem/core/analytics/AnalyticsEvent.kt @@ -8,5 +8,4 @@ open class AnalyticsEvent( val event: String, var params: Map = mapOf(), val error: Throwable? = null, - var filterData: Any? = null, ) \ No newline at end of file