From 9b6cb2f235c577b9abc7e57e31c9e7606f877a6f Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 21 Mar 2023 23:07:50 +0800 Subject: [PATCH] Updated on 2026-08-14 --- .../java/com/tangem/tap/TapApplication.kt | 2 - .../converters/BasicEventConverter.kt | 22 +------- .../tap/common/analytics/events/Basic.kt | 10 +++- .../tap/common/analytics/events/Settings.kt | 2 +- .../tap/common/analytics/events/Token.kt | 5 ++ .../analytics/filters/BasicSignInFilter.kt | 27 --------- .../com/tangem/tap/common/redux/AppReducer.kt | 2 + .../com/tangem/tap/common/redux/AppState.kt | 4 ++ .../tap/features/home/redux/HomeMiddleware.kt | 5 +- .../note/redux/OnboardingNoteMiddleware.kt | 10 ++++ .../twins/redux/TwinCardsMiddleware.kt | 10 ++++ .../wallet/redux/OnboardingWalletAction.kt | 12 +--- .../redux/OnboardingWalletMiddleware.kt | 56 ++++++++++++------- .../wallet/redux/OnboardingWalletReducer.kt | 1 + .../redux/OnboardingSaltPayMiddleware.kt | 9 ++- .../wallet/ui/OnboardingWalletFragment.kt | 2 +- .../tap/features/signin/redux/SignInAction.kt | 12 ++++ .../features/signin/redux/SignInMiddleware.kt | 15 +++++ .../features/signin/redux/SignInReducer.kt | 17 ++++++ .../tap/features/signin/redux/SignInState.kt | 8 +++ .../redux/middlewares/WalletMiddleware.kt | 6 +- .../tap/features/wallet/ui/WalletFragment.kt | 3 +- .../tap/features/wallet/ui/WalletViewModel.kt | 29 +++++++++- .../wallet/ui/wallet/SingleWalletView.kt | 4 ++ .../features/welcome/redux/WelcomeAction.kt | 1 - .../welcome/redux/WelcomeMiddleware.kt | 14 ++--- .../features/welcome/ui/WelcomeFragment.kt | 14 +++-- .../referral/analytics/ReferralEvents.kt | 6 +- .../feature/swap/analytics/SwapEvents.kt | 6 +- 29 files changed, 195 insertions(+), 119 deletions(-) delete mode 100644 app/src/main/java/com/tangem/tap/common/analytics/filters/BasicSignInFilter.kt create mode 100644 app/src/main/java/com/tangem/tap/features/signin/redux/SignInAction.kt create mode 100644 app/src/main/java/com/tangem/tap/features/signin/redux/SignInMiddleware.kt create mode 100644 app/src/main/java/com/tangem/tap/features/signin/redux/SignInReducer.kt create mode 100644 app/src/main/java/com/tangem/tap/features/signin/redux/SignInState.kt diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index 56b14e2732..05634eb5fb 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -22,7 +22,6 @@ 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.BasicSignInFilter 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 @@ -187,7 +186,6 @@ class TapApplication : Application(), ImageLoaderFactory { factory.addHandlerBuilder(AppsFlyerAnalyticsHandler.Builder()) factory.addHandlerBuilder(FirebaseAnalyticsHandler.Builder()) - factory.addFilter(BasicSignInFilter()) factory.addFilter(BasicTopUpFilter(preferencesStorage.toppedUpWalletStorage)) val buildData = AnalyticsHandlerBuilder.Data( 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 index 79ce7f700a..1e1f9894c8 100644 --- 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 @@ -23,7 +23,6 @@ class BasicEventsPreChecker { fun tryToSend(converterData: BasicEventsSourceData) { if (!isReadyToSend(converterData)) return - BasicSignInEventConverter().convert(converterData)?.let { Analytics.send(it) } BasicTopUpEventConverter().convert(converterData)?.let { Analytics.send(it) } } @@ -99,12 +98,8 @@ data class BasicEventsSourceData( val walletState: WalletState, val biometricsWalletDataModels: List?, ) { - val batchId: String by lazy { scanResponse.card.batchId } - val userWalletIdStringValue: String? by lazy { - UserWalletIdBuilder.scanResponse(scanResponse) - .build() - ?.stringValue + UserWalletIdBuilder.scanResponse(scanResponse).build()?.stringValue } val paramCardCurrency: AnalyticsParam.CardCurrency? by lazy { @@ -164,21 +159,6 @@ private class BalanceCalculator( } } -class BasicSignInEventConverter : Converter { - - override fun convert(value: BasicEventsSourceData): Basic.SignedIn? { - if (value.paramCardCurrency == null || value.userWalletIdStringValue == null) return null - - return Basic.SignedIn( - state = value.paramCardBalanceState, - currency = value.paramCardCurrency!!, - batch = value.batchId, - ).apply { - filterData = value.userWalletIdStringValue - } - } -} - class BasicTopUpEventConverter : Converter { override fun convert(value: BasicEventsSourceData): Basic.ToppedUp? { 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 76b00ef40f..4a14854595 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 @@ -21,17 +21,21 @@ sealed class Basic( ) class SignedIn( - state: AnalyticsParam.CardBalanceState, currency: AnalyticsParam.CardCurrency, batch: String, + signInType: SignInType, ) : Basic( event = "Signed in", params = mapOf( - "State" to state.value, AnalyticsParam.Currency to currency.value, AnalyticsParam.Batch to batch, + "Sign in type" to signInType.name, ), - ) + ) { + enum class SignInType { + Card, Biometric + } + } class ToppedUp(currency: AnalyticsParam.CardCurrency) : Basic( event = "Topped up", diff --git a/app/src/main/java/com/tangem/tap/common/analytics/events/Settings.kt b/app/src/main/java/com/tangem/tap/common/analytics/events/Settings.kt index 03cbb88ac6..df526f80d5 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/events/Settings.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/events/Settings.kt @@ -58,7 +58,7 @@ sealed class Settings( sealed class AppSettings( event: String, params: Map = mapOf(), - ) : Settings("Settings / App Settings", event, params) { + ) : Settings(category = "Settings / App Settings", event = event, params = params) { class SaveWalletSwitcherChanged(state: AnalyticsParam.OnOffState) : CardSettings( event = "Save Wallet Switcher Changed", diff --git a/app/src/main/java/com/tangem/tap/common/analytics/events/Token.kt b/app/src/main/java/com/tangem/tap/common/analytics/events/Token.kt index 63dd109942..6247c504b3 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/events/Token.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/events/Token.kt @@ -52,6 +52,11 @@ sealed class Token( params = mapOf("Token" to type.value), ) + object ShowWalletAddress : Token( + category = "Token", + event = "Button - Show the Wallet Address" + ) + sealed class Receive( event: String, params: Map = mapOf(), 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 deleted file mode 100644 index 09c26d8d7d..0000000000 --- a/app/src/main/java/com/tangem/tap/common/analytics/filters/BasicSignInFilter.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.tangem.tap.common.analytics.filters - -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.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 canBeConsumedByHandler(handler: AnalyticsHandler, event: AnalyticsEvent): Boolean = true -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt b/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt index 3bcb47a092..ec25507402 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt @@ -13,6 +13,7 @@ import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWallet import com.tangem.tap.features.saveWallet.redux.SaveWalletReducer import com.tangem.tap.features.send.redux.reducers.SendScreenReducer import com.tangem.tap.features.shop.redux.ShopReducer +import com.tangem.tap.features.signin.redux.SignInReducer import com.tangem.tap.features.sprinklr.redux.SprinklrReducer import com.tangem.tap.features.tokens.redux.TokensReducer import com.tangem.tap.features.wallet.redux.reducers.WalletReducer @@ -44,6 +45,7 @@ fun appReducer(action: Action, state: AppState?, appStateHolder: AppStateHolder) saveWalletState = SaveWalletReducer.reduce(action, state), walletSelectorState = WalletSelectorReducer.reduce(action, state), sprinklrState = SprinklrReducer.reduce(action, state), + signInState = SignInReducer.reduce(action, state), ) } diff --git a/app/src/main/java/com/tangem/tap/common/redux/AppState.kt b/app/src/main/java/com/tangem/tap/common/redux/AppState.kt index e9b253d90d..c4d49c0ae2 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/AppState.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/AppState.kt @@ -31,6 +31,8 @@ import com.tangem.tap.features.send.redux.middlewares.SendMiddleware import com.tangem.tap.features.send.redux.states.SendState import com.tangem.tap.features.shop.redux.ShopMiddleware import com.tangem.tap.features.shop.redux.ShopState +import com.tangem.tap.features.signin.redux.SignInMiddleware +import com.tangem.tap.features.signin.redux.SignInState import com.tangem.tap.features.sprinklr.redux.SprinklrMiddleware import com.tangem.tap.features.sprinklr.redux.SprinklrState import com.tangem.tap.features.tokens.redux.TokensMiddleware @@ -64,6 +66,7 @@ data class AppState( val saveWalletState: SaveWalletState = SaveWalletState(), val walletSelectorState: WalletSelectorState = WalletSelectorState(), val sprinklrState: SprinklrState = SprinklrState(), + val signInState: SignInState = SignInState() ) : StateType { val domainState: DomainState @@ -105,6 +108,7 @@ data class AppState( LockUserWalletsTimerMiddleware().middleware, AccessCodeRequestPolicyMiddleware().middleware, SprinklrMiddleware().middleware, + SignInMiddleware.middleware ) } } diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt index 0ea4b412cf..3230f8b878 100644 --- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt @@ -6,6 +6,7 @@ import com.tangem.common.doOnSuccess import com.tangem.core.analytics.Analytics import com.tangem.core.analytics.AnalyticsEvent import com.tangem.domain.common.ScanResponse +import com.tangem.tap.common.analytics.events.Basic import com.tangem.tap.common.analytics.events.IntroductionProcess import com.tangem.tap.common.analytics.events.Shop import com.tangem.tap.common.entities.IndeterminateProgressButton @@ -23,6 +24,7 @@ import com.tangem.tap.features.home.BELARUS_COUNTRY_CODE import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE import com.tangem.tap.features.home.redux.HomeMiddleware.BUY_WALLET_URL import com.tangem.tap.features.send.redux.states.ButtonState +import com.tangem.tap.features.signin.redux.SignInAction import com.tangem.tap.preferencesStorage import com.tangem.tap.scope import com.tangem.tap.store @@ -112,9 +114,10 @@ fun proceedWithScanResponse(scanResponse: ScanResponse) { Timber.e(error, "Unable to save user wallet") } .doOnSuccess { - scope.launch { store.onUserWalletSelected(userWallet) } + scope.launch { store.onUserWalletSelected(userWallet = userWallet) } } .doOnResult { + store.dispatchOnMain(SignInAction.SetSignInType(Basic.SignedIn.SignInType.Card)) navigateTo(AppScreen.Wallet) } } 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 28d62cf134..8ec11cf17c 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,6 +6,7 @@ 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 @@ -159,6 +160,15 @@ 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.dispatch(OnboardingNoteAction.SetStepOfScreen(OnboardingNoteStep.Done)) } } 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 ff7ff2399e..f6d021d0f8 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,6 +8,7 @@ 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 @@ -261,6 +262,15 @@ 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)) } } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt index df5882a35c..47819aea80 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt @@ -1,6 +1,5 @@ package com.tangem.tap.features.onboarding.products.wallet.redux -import android.graphics.Bitmap import android.net.Uri import org.rekotlin.Action @@ -22,10 +21,9 @@ sealed class OnboardingWalletAction : Action { sealed class BackupAction : Action { - object DetermineBackupStep : BackupAction() object IntroduceBackup : BackupAction() object StartBackup : BackupAction() - object DismissBackup : BackupAction() + object SkipBackup : BackupAction() object StartAddingPrimaryCard : BackupAction() object ScanPrimaryCard : BackupAction() @@ -41,13 +39,6 @@ sealed class BackupAction : Action { object Success : BackupAction() } - data class LoadBackupCardArtwork( - val cardId: CardId, - val cardPublicKey: ByteArray, - ) : BackupAction() { - data class Success(val cardId: CardId, val artwork: Bitmap) - } - object FinishAddingBackupCards : BackupAction() object ShowAccessCodeInfoScreen : BackupAction() @@ -55,7 +46,6 @@ sealed class BackupAction : Action { data class CheckAccessCode(val accessCode: String) : BackupAction() data class SetAccessCodeError(val error: AccessCodeError?) : BackupAction() data class SaveFirstAccessCode(val accessCode: String) : BackupAction() - object ShowReenterAccessCodeScreen : BackupAction() data class SaveAccessCodeConfirmation(val accessCodeConfirmation: String) : BackupAction() object OnAccessCodeDialogClosed : BackupAction() 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 4226d47b74..50a9f32619 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 @@ -329,15 +329,6 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction) } } } - is BackupAction.FinishBackup -> { - if (action.withAnalytics) { - Analytics.send(Onboarding.Backup.Finished(backupState.backupCardsNumber)) - } - if (!onboardingWalletState.isSaltPay) { - Analytics.send(Onboarding.Finished()) - finishCardActivation(backupState, card) - } - } is BackupAction.DiscardBackup -> { backupService.discardSavedBackup() } @@ -362,15 +353,36 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction) ) store.dispatch(NavigationAction.NavigateTo(AppScreen.OnboardingWallet)) } - is BackupAction.DismissBackup -> { + is BackupAction.SkipBackup -> { Analytics.send(Onboarding.Backup.Skipped()) - if (onboardingWalletState.isSaltPay) throw UnsupportedOperationException() - store.dispatch(BackupAction.FinishBackup()) + if (onboardingWalletState.isSaltPay) return + + Analytics.send(Onboarding.Finished()) + finishCardActivation(gatherCardIds(backupState, card)) + } + is BackupAction.FinishBackup -> { + if (action.withAnalytics) { + Analytics.send(Onboarding.Backup.Finished(backupState.backupCardsNumber)) + } + if (onboardingWalletState.isSaltPay) return + + val notActivatedCardIds = gatherCardIds(backupState, card) + .mapNotNull { if (cardActivationIsFinished(it)) null else it } + + // All cardIds may already be activated if the backup was skipped before. + if (notActivatedCardIds.isEmpty()) return + + Analytics.send(Onboarding.Finished()) + finishCardActivation(notActivatedCardIds) } else -> {} } } +private fun cardActivationIsFinished(cardId: String): Boolean { + return preferencesStorage.usedCardsPrefStorage.isActivationFinished(cardId) +} + /** * Standard Wallet cards start activation at OnboardingWalletAction.CreateWallet * SaltPay cards start activation at OnboardingWalletAction.StartSaltPayCardActivation @@ -380,16 +392,19 @@ private fun startCardActivation(scanResponse: ScanResponse) { } /** - * Standard Wallet cards finish activation at BackupAction.FinishBackup + * Standard Wallet cards finish activation at BackupAction.SkipBackup and BackupAction.FinishBackup * SaltPay cards finish activation at OnboardingWalletAction.FinishOnboarding */ -internal fun finishCardActivation(backupState: BackupState, card: CardDTO?) { - (listOf(backupState.primaryCardId, card?.cardId) + backupState.backupCardIds) - .distinct() +internal fun finishCardActivation(cardIds: List) { + cardIds.forEach { cardId -> + preferencesStorage.usedCardsPrefStorage.activationFinished(cardId) + } +} + +internal fun gatherCardIds(backupState: BackupState, card: CardDTO?): List { + return (listOf(backupState.primaryCardId, card?.cardId) + backupState.backupCardIds) .filterNotNull() - .forEach { cardId -> - preferencesStorage.usedCardsPrefStorage.activationFinished(cardId) - } + .distinct() } /** @@ -415,7 +430,8 @@ private fun initSaltPayOnBackupFinishedIfNeeded( card = scanResponse.card, ).create() store.dispatchOnMain(OnboardingSaltPayAction.SetDependencies(manager)) - store.dispatchOnMain(OnboardingSaltPayAction.Update(false)) + store.dispatchOnMain(OnboardingSaltPayAction.Update(withAnalytics = false)) + store.dispatchOnMain(OnboardingSaltPayAction.OnSwitchedToSaltPayProcess) } } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletReducer.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletReducer.kt index 5359efde9b..6e457704dd 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletReducer.kt @@ -106,6 +106,7 @@ private object BackupReducer { } else { state.copy(backupStep = BackupStep.WriteBackupCard(action.cardNumber)) } + is BackupAction.SkipBackup -> state.copy(backupStep = BackupStep.Finished) is BackupAction.FinishBackup -> state.copy(backupStep = BackupStep.Finished) BackupAction.OnAccessCodeDialogClosed -> state.copy(backupStep = BackupStep.AddBackupCards) BackupAction.DiscardBackup -> BackupState() diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/saltPay/redux/OnboardingSaltPayMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/saltPay/redux/OnboardingSaltPayMiddleware.kt index 57b1f17f3c..5418a8d42e 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/saltPay/redux/OnboardingSaltPayMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/saltPay/redux/OnboardingSaltPayMiddleware.kt @@ -23,6 +23,7 @@ import com.tangem.tap.features.demo.DemoHelper import com.tangem.tap.features.onboarding.OnboardingManager import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletState import com.tangem.tap.features.onboarding.products.wallet.redux.finishCardActivation +import com.tangem.tap.features.onboarding.products.wallet.redux.gatherCardIds import com.tangem.tap.features.onboarding.products.wallet.saltPay.AllSymbolsTheSameFilter import com.tangem.tap.features.onboarding.products.wallet.saltPay.SaltPayActivationManager import com.tangem.tap.features.onboarding.products.wallet.saltPay.SaltPayExceptionHandler @@ -79,7 +80,7 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App } } is OnboardingSaltPayAction.OnSwitchedToSaltPayProcess -> { - sendAnalyticsScreenOpened(getState().step, newStep = SaltPayActivationStep.None) + sendAnalyticsScreenOpened(SaltPayActivationStep.None, newStep = getState().step) } is OnboardingSaltPayAction.Update -> { handleInProgress = true @@ -279,10 +280,8 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App store.dispatchDebugErrorNotification("OnboardingManager can't be NULL") return } - finishCardActivation( - getOnboardingWalletState().backupState, - onboardingManager.scanResponse.card, - ) + val cardIds = gatherCardIds(getOnboardingWalletState().backupState, onboardingManager.scanResponse.card) + finishCardActivation(cardIds) } } else -> { diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt index d2202cc249..7125990ede 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt @@ -227,7 +227,7 @@ class OnboardingWalletFragment : BaseFragment(R.layout.fragment_onboarding_walle btnWalletMainAction.setOnClickListener { store.dispatch(BackupAction.StartBackup) } btnWalletAlternativeAction.text = getText(R.string.onboarding_button_skip_backup) - btnWalletAlternativeAction.setOnClickListener { store.dispatch(BackupAction.DismissBackup) } + btnWalletAlternativeAction.setOnClickListener { store.dispatch(BackupAction.SkipBackup) } btnWalletAlternativeAction.show(state.canSkipBackup && !isSaltPay) } animator.showBackupIntro(state) diff --git a/app/src/main/java/com/tangem/tap/features/signin/redux/SignInAction.kt b/app/src/main/java/com/tangem/tap/features/signin/redux/SignInAction.kt new file mode 100644 index 0000000000..efbcafb9df --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/signin/redux/SignInAction.kt @@ -0,0 +1,12 @@ +package com.tangem.tap.features.signin.redux + +import com.tangem.tap.common.analytics.events.Basic +import org.rekotlin.Action + +/** +[REDACTED_AUTHOR] + */ +sealed interface SignInAction : Action { + + data class SetSignInType(val type: Basic.SignedIn.SignInType) : SignInAction +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/signin/redux/SignInMiddleware.kt b/app/src/main/java/com/tangem/tap/features/signin/redux/SignInMiddleware.kt new file mode 100644 index 0000000000..1f44dff0f7 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/signin/redux/SignInMiddleware.kt @@ -0,0 +1,15 @@ +package com.tangem.tap.features.signin.redux + +import com.tangem.tap.common.redux.AppState +import org.rekotlin.Middleware + +/** +[REDACTED_AUTHOR] + */ +object SignInMiddleware { + val middleware: Middleware = { _, _ -> + { next -> + { action -> next(action) } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/signin/redux/SignInReducer.kt b/app/src/main/java/com/tangem/tap/features/signin/redux/SignInReducer.kt new file mode 100644 index 0000000000..3d5910774d --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/signin/redux/SignInReducer.kt @@ -0,0 +1,17 @@ +package com.tangem.tap.features.signin.redux + +import com.tangem.tap.common.redux.AppState +import org.rekotlin.Action + +/** +[REDACTED_AUTHOR] + */ +object SignInReducer { + fun reduce(action: Action, state: AppState): SignInState { + if (action !is SignInAction) return state.signInState + + return when (action) { + is SignInAction.SetSignInType -> state.signInState.copy(type = action.type) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/signin/redux/SignInState.kt b/app/src/main/java/com/tangem/tap/features/signin/redux/SignInState.kt new file mode 100644 index 0000000000..95b132aab7 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/signin/redux/SignInState.kt @@ -0,0 +1,8 @@ +package com.tangem.tap.features.signin.redux + +import com.tangem.tap.common.analytics.events.Basic + +/** +[REDACTED_AUTHOR] + */ +data class SignInState(val type: Basic.SignedIn.SignInType? = null) \ No newline at end of file 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 1866921b7e..9b5324ead5 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 @@ -364,6 +364,10 @@ suspend fun handleBasicAnalyticsEvent() { null } - val converterData = BasicEventsSourceData(scanResponse, store.state.walletState, biometricsWalletDataModels) + 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/ui/WalletFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt index 3e99ac95ed..fae5543edf 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 @@ -22,7 +22,6 @@ import com.tangem.core.ui.fragments.setStatusBarColor import com.tangem.core.ui.utils.OneTouchClickListener import com.tangem.feature.swap.domain.SwapInteractor import com.tangem.tap.MainActivity -import com.tangem.tap.common.analytics.events.MainScreen import com.tangem.tap.common.analytics.events.Portfolio import com.tangem.tap.common.extensions.show import com.tangem.tap.common.recyclerView.SpaceItemDecoration @@ -66,6 +65,7 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber { +internal class WalletViewModel : ViewModel(), StoreSubscriber, DefaultLifecycleObserver { private var observeWalletStoresUpdatesJob: Job? = null set(value) { field?.cancel() @@ -41,6 +47,27 @@ internal class WalletViewModel : ViewModel(), StoreSubscriber store.dispatch( WalletAction.DialogAction.QrCode( diff --git a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeAction.kt b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeAction.kt index ddf2e403d3..0d248ec7af 100644 --- a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeAction.kt +++ b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeAction.kt @@ -5,7 +5,6 @@ import com.tangem.common.core.TangemError import org.rekotlin.Action internal sealed interface WelcomeAction : Action { - object OnCreate : WelcomeAction object ProceedWithBiometrics : WelcomeAction { object Success : WelcomeAction data class Error(val error: TangemError) : WelcomeAction diff --git a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt index 84ff91eebf..495b112f1d 100644 --- a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt @@ -4,13 +4,10 @@ import android.content.Intent import com.tangem.common.core.TangemSdkError import com.tangem.common.doOnFailure import com.tangem.common.doOnSuccess -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.events.SignIn import com.tangem.tap.common.extensions.dispatchOnMain -import com.tangem.tap.common.extensions.eraseContext import com.tangem.tap.common.extensions.onUserWalletSelected import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.navigation.AppScreen @@ -19,6 +16,7 @@ import com.tangem.tap.domain.model.builders.UserWalletBuilder import com.tangem.tap.domain.scanCard.ScanCardProcessor import com.tangem.tap.domain.userWalletList.unlockIfLockable import com.tangem.tap.features.onboarding.products.wallet.saltPay.message.SaltPayActivationError +import com.tangem.tap.features.signin.redux.SignInAction import com.tangem.tap.intentHandler import com.tangem.tap.preferencesStorage import com.tangem.tap.scope @@ -44,10 +42,6 @@ internal class WelcomeMiddleware { private fun handleAction(action: WelcomeAction, state: WelcomeState) { when (action) { - is WelcomeAction.OnCreate -> { - Analytics.eraseContext() - Analytics.send(SignIn.ScreenOpened()) - } is WelcomeAction.ProceedWithBiometrics -> { proceedWithBiometrics(state) } @@ -74,9 +68,10 @@ internal class WelcomeMiddleware { store.dispatchOnMain(WelcomeAction.ProceedWithBiometrics.Error(error)) } .doOnSuccess { selectedUserWallet -> + store.dispatchOnMain(SignInAction.SetSignInType(Basic.SignedIn.SignInType.Biometric)) store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.Wallet)) store.dispatchOnMain(WelcomeAction.ProceedWithBiometrics.Success) - store.onUserWalletSelected(selectedUserWallet) + store.onUserWalletSelected(userWallet = selectedUserWallet) intentHandler.handleWalletConnectLink(state.intent) } @@ -93,9 +88,10 @@ internal class WelcomeMiddleware { store.dispatchOnMain(WelcomeAction.ProceedWithCard.Error(error)) } .doOnSuccess { + store.dispatchOnMain(SignInAction.SetSignInType(Basic.SignedIn.SignInType.Card)) store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.Wallet)) store.dispatchOnMain(WelcomeAction.ProceedWithCard.Success) - store.onUserWalletSelected(userWallet) + store.onUserWalletSelected(userWallet = userWallet) intentHandler.handleWalletConnectLink(state.intent) } diff --git a/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeFragment.kt b/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeFragment.kt index e346adb6d1..81cad48aca 100644 --- a/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeFragment.kt @@ -1,6 +1,5 @@ package com.tangem.tap.features.welcome.ui -import android.os.Bundle import androidx.activity.compose.BackHandler import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxWidth @@ -19,22 +18,25 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.colorResource import androidx.fragment.app.viewModels +import com.tangem.core.analytics.Analytics import com.tangem.core.ui.components.SystemBarsEffect import com.tangem.core.ui.fragments.ComposeFragment import com.tangem.core.ui.res.TangemTheme +import com.tangem.tap.common.analytics.events.SignIn +import com.tangem.tap.common.extensions.eraseContext import com.tangem.tap.features.details.ui.cardsettings.resolveReference -import com.tangem.tap.features.welcome.redux.WelcomeAction import com.tangem.tap.features.welcome.ui.components.WarningDialog import com.tangem.tap.features.welcome.ui.components.WelcomeScreenContent -import com.tangem.tap.store import com.tangem.wallet.R internal class WelcomeFragment : ComposeFragment() { + private val viewModel by viewModels() - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - store.dispatch(WelcomeAction.OnCreate) + override fun onStart() { + super.onStart() + Analytics.eraseContext() + Analytics.send(SignIn.ScreenOpened()) } @Composable diff --git a/features/referral/presentation/src/main/java/com/tangem/feature/referral/analytics/ReferralEvents.kt b/features/referral/presentation/src/main/java/com/tangem/feature/referral/analytics/ReferralEvents.kt index 41d4f8b1c0..e82990adf2 100644 --- a/features/referral/presentation/src/main/java/com/tangem/feature/referral/analytics/ReferralEvents.kt +++ b/features/referral/presentation/src/main/java/com/tangem/feature/referral/analytics/ReferralEvents.kt @@ -2,9 +2,7 @@ package com.tangem.feature.referral.analytics import com.tangem.core.analytics.AnalyticsEvent -sealed class ReferralEvents( - event: String, -) : AnalyticsEvent(REFERRAL_PROGRAM_CATEGORY, event) { +sealed class ReferralEvents(event: String) : AnalyticsEvent(REFERRAL_PROGRAM_CATEGORY, event) { object ReferralScreenOpened : ReferralEvents(event = "Referral Screen Opened") object ClickParticipate : ReferralEvents(event = "Button - Participate") @@ -13,4 +11,4 @@ sealed class ReferralEvents( object ClickTaC : ReferralEvents(event = "Link - TaC") } -private const val REFERRAL_PROGRAM_CATEGORY = "Referral program" \ No newline at end of file +private const val REFERRAL_PROGRAM_CATEGORY = "Referral Program" \ No newline at end of file diff --git a/features/swap/presentation/src/main/java/com/tangem/feature/swap/analytics/SwapEvents.kt b/features/swap/presentation/src/main/java/com/tangem/feature/swap/analytics/SwapEvents.kt index 11dce2daa7..e808db167c 100644 --- a/features/swap/presentation/src/main/java/com/tangem/feature/swap/analytics/SwapEvents.kt +++ b/features/swap/presentation/src/main/java/com/tangem/feature/swap/analytics/SwapEvents.kt @@ -15,16 +15,16 @@ sealed class SwapEvents( object SendTokenBalanceClicked : SwapEvents(event = "Send Token Balance Clicked") object ReceiveTokenClicked : SwapEvents(event = "Receive Token Clicked") object ChooseTokenScreenOpened : SwapEvents(event = "Choose Token Screen Opened") - object SearchTokenClicked : SwapEvents(event = "Search Token Clicked") + object SearchTokenClicked : SwapEvents(event = "Searched Token Clicked") data class ButtonSwapClicked(val sendToken: String, val receiveToken: String) : SwapEvents( event = "Button - Swap", params = mapOf("Send Token" to sendToken, "Receive Token" to receiveToken), ) - object ButtonGivePermissionClicked : SwapEvents(event = "Button - Give permission") // ? + object ButtonGivePermissionClicked : SwapEvents(event = "Button - Give permission") object ButtonPermissionApproveClicked : SwapEvents(event = "Button - Permission Approve") object ButtonPermissionCancelClicked : SwapEvents(event = "Button - Permission Cancel") - object ButtonPermitAndSwapClicked : SwapEvents(event = "Button - Permit and Swap") // ? + object ButtonPermitAndSwapClicked : SwapEvents(event = "Button - Permit and Swap") object ButtonSwipeClicked : SwapEvents(event = "Button - Swipe") object SwapInProgressScreen : SwapEvents(event = "Swap in Progress Screen Opened") }