diff --git a/app/src/main/java/com/tangem/tap/common/analytics/DefaultTrackingContextProxy.kt b/app/src/main/java/com/tangem/tap/common/analytics/DefaultTrackingContextProxy.kt index 923b26cbf5..6174bb4473 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/DefaultTrackingContextProxy.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/DefaultTrackingContextProxy.kt @@ -71,12 +71,6 @@ internal class DefaultTrackingContextProxy(private val abTestsManager: ABTestsMa Analytics.removeContext() } - override fun proceedWithContext(userWallet: UserWallet, action: () -> Unit) { - setContext(userWallet) - action() - eraseContext() - } - private fun calculateUserIdHash(userWalletId: UserWalletId?): String? { return userWalletId?.value ?.calculateSha256() diff --git a/app/src/main/java/com/tangem/tap/common/analytics/events/SignIn.kt b/app/src/main/java/com/tangem/tap/common/analytics/events/SignIn.kt index d34334ec34..21f5f23180 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/events/SignIn.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/events/SignIn.kt @@ -10,8 +10,6 @@ sealed class SignIn( params: Map = emptyMap(), ) : AnalyticsEvent("Sign In", event, params) { - class ScreenOpened : SignIn(event = "Sign In Screen Opened") - class ButtonBiometricSignIn : SignIn(event = "Button - Biometric Sign In") class ButtonCardSignIn : SignIn(event = "Button - Card Sign In") } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/analytics/paramsInterceptor/CardContextInterceptor.kt b/app/src/main/java/com/tangem/tap/common/analytics/paramsInterceptor/CardContextInterceptor.kt index c7bc17f8e9..cdd42cdde9 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/paramsInterceptor/CardContextInterceptor.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/paramsInterceptor/CardContextInterceptor.kt @@ -3,6 +3,7 @@ package com.tangem.tap.common.analytics.paramsInterceptor import com.tangem.core.analytics.api.ParamsInterceptor import com.tangem.core.analytics.models.AnalyticsEvent import com.tangem.core.analytics.models.AnalyticsParam +import com.tangem.core.analytics.models.event.SignIn import com.tangem.domain.card.analytics.IntroductionProcess import com.tangem.domain.card.analytics.ParamCardCurrencyConverter import com.tangem.domain.card.common.util.cardTypesResolver @@ -30,8 +31,11 @@ class CardContextInterceptor( override fun canBeAppliedTo(event: AnalyticsEvent): Boolean { return when (event) { - is IntroductionProcess.ButtonScanCardLegacy -> false - is IntroductionProcess.ButtonScanCard -> false + is IntroductionProcess.ButtonScanCard, + is IntroductionProcess.ButtonScanCardLegacy, + is SignIn.ScreenOpened, + is SignIn.ButtonAddWallet, + -> false else -> true } } diff --git a/app/src/main/java/com/tangem/tap/common/analytics/paramsInterceptor/HotWalletContextInterceptor.kt b/app/src/main/java/com/tangem/tap/common/analytics/paramsInterceptor/HotWalletContextInterceptor.kt index ab9c9d3b54..f67eaab3f8 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/paramsInterceptor/HotWalletContextInterceptor.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/paramsInterceptor/HotWalletContextInterceptor.kt @@ -3,6 +3,8 @@ package com.tangem.tap.common.analytics.paramsInterceptor import com.tangem.core.analytics.api.ParamsInterceptor import com.tangem.core.analytics.models.AnalyticsEvent import com.tangem.core.analytics.models.AnalyticsParam +import com.tangem.core.analytics.models.event.SignIn +import com.tangem.domain.card.analytics.IntroductionProcess class HotWalletContextInterceptor( val parent: ParamsInterceptor? = null, @@ -10,7 +12,16 @@ class HotWalletContextInterceptor( override fun id(): String = HotWalletContextInterceptor.id() - override fun canBeAppliedTo(event: AnalyticsEvent): Boolean = true + override fun canBeAppliedTo(event: AnalyticsEvent): Boolean { + return when (event) { + is SignIn.ScreenOpened, + is SignIn.ButtonAddWallet, + is SignIn.ButtonUnlockAllWithBiometric, + is IntroductionProcess.ButtonScanCard, + -> false + else -> true + } + } override fun intercept(params: MutableMap) { params[AnalyticsParam.PRODUCT_TYPE] = AnalyticsParam.ProductType.MobileWallet.value diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/DefaultUserWalletsListRepository.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/DefaultUserWalletsListRepository.kt index 29f19ffb75..3064dd8840 100644 --- a/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/DefaultUserWalletsListRepository.kt +++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/repository/DefaultUserWalletsListRepository.kt @@ -525,13 +525,12 @@ internal class DefaultUserWalletsListRepository( } private fun trackSignInEvent(userWallet: UserWallet, type: Basic.SignedIn.SignInType) { - trackingContextProxy.proceedWithContext(userWallet) { - analyticsEventHandler.send( - event = Basic.SignedIn( - signInType = type, - walletsCount = userWallets.value?.size ?: 0, - ), - ) - } + trackingContextProxy.addContext(userWallet) + analyticsEventHandler.send( + event = Basic.SignedIn( + signInType = type, + walletsCount = userWallets.value?.size ?: 0, + ), + ) } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/routing/component/impl/DefaultRoutingComponent.kt b/app/src/main/java/com/tangem/tap/routing/component/impl/DefaultRoutingComponent.kt index 483891f435..9e4f210063 100644 --- a/app/src/main/java/com/tangem/tap/routing/component/impl/DefaultRoutingComponent.kt +++ b/app/src/main/java/com/tangem/tap/routing/component/impl/DefaultRoutingComponent.kt @@ -227,14 +227,13 @@ internal class DefaultRoutingComponent @AssistedInject constructor( if (hotWalletFeatureToggles.isHotWalletEnabled) { val userWallets = userWalletsListRepository.userWalletsSync() val selectedWallet = userWalletsListRepository.selectedUserWalletSync() ?: return - trackingContextProxy.proceedWithContext(selectedWallet) { - analyticsEventHandler.send( - event = Basic.SignedIn( - signInType = Basic.SignedIn.SignInType.NoSecurity, - walletsCount = userWallets.size, - ), - ) - } + trackingContextProxy.addContext(selectedWallet) + analyticsEventHandler.send( + event = Basic.SignedIn( + signInType = Basic.SignedIn.SignInType.NoSecurity, + walletsCount = userWallets.size, + ), + ) } } } \ No newline at end of file diff --git a/common/ui/src/main/java/com/tangem/common/ui/userwallet/UserWalletUnlockError.kt b/common/ui/src/main/java/com/tangem/common/ui/userwallet/UserWalletUnlockError.kt index 851972f960..e7e4b2a884 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/userwallet/UserWalletUnlockError.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/userwallet/UserWalletUnlockError.kt @@ -1,6 +1,8 @@ package com.tangem.common.ui.userwallet import com.tangem.common.ui.R +import com.tangem.core.analytics.api.AnalyticsEventHandler +import com.tangem.core.analytics.models.event.SignIn import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringReference @@ -13,6 +15,7 @@ import com.tangem.domain.common.wallets.error.UnlockWalletError.UnableToUnlock.R inline fun UnlockWalletError.handle( onAlreadyUnlocked: () -> Unit = {}, onUserCancelled: () -> Unit = {}, + analyticsEventHandler: AnalyticsEventHandler, noinline showMessage: (EventMessage) -> Unit, ) { when (this) { @@ -30,15 +33,20 @@ inline fun UnlockWalletError.handle( // This should never happen in this flow, as we always check for the wallet existence before unlocking showMessage(SnackbarMessage(TextReference.Res(R.string.generic_error))) } - is UnlockWalletError.UnableToUnlock -> handleUnableToUnlock(this, showMessage) + is UnlockWalletError.UnableToUnlock -> handleUnableToUnlock(this, analyticsEventHandler, showMessage) } } -fun handleUnableToUnlock(error: UnlockWalletError.UnableToUnlock, showDialog: (DialogMessage) -> Unit) { +fun handleUnableToUnlock( + error: UnlockWalletError.UnableToUnlock, + analyticsEventHandler: AnalyticsEventHandler, + showDialog: (DialogMessage) -> Unit, +) { val dialogMessage = when (error) { is UnlockWalletError.UnableToUnlock.WithReason -> { when (error.reason) { Reason.AllKeysInvalidated -> { + analyticsEventHandler.send(SignIn.ErrorBiometricUpdated()) DialogMessage( title = resourceReference(R.string.biometric_updated_warning_title), message = resourceReference(R.string.biometric_updated_warning_description), diff --git a/core/analytics/models/src/main/java/com/tangem/core/analytics/models/AnalyticsParam.kt b/core/analytics/models/src/main/java/com/tangem/core/analytics/models/AnalyticsParam.kt index 7f051ebf87..8ea55f5139 100644 --- a/core/analytics/models/src/main/java/com/tangem/core/analytics/models/AnalyticsParam.kt +++ b/core/analytics/models/src/main/java/com/tangem/core/analytics/models/AnalyticsParam.kt @@ -83,7 +83,7 @@ sealed class AnalyticsParam { data object Upgrade : ScreensSources("Upgrade") data object HardwareWallet : ScreensSources("Hardware Wallet") data object ImportWallet : ScreensSources("Import Wallet") - data object CreateNewWallet : ScreensSources("Create New Wallet") + data object CreateWalletIntro : ScreensSources("Create Wallet Intro") data object AddNewWallet : ScreensSources("Add New Wallet") data object CreateWallet : ScreensSources("Create Wallet") } diff --git a/core/analytics/models/src/main/java/com/tangem/core/analytics/models/event/SignIn.kt b/core/analytics/models/src/main/java/com/tangem/core/analytics/models/event/SignIn.kt index 5d0e483b1c..9b88374046 100644 --- a/core/analytics/models/src/main/java/com/tangem/core/analytics/models/event/SignIn.kt +++ b/core/analytics/models/src/main/java/com/tangem/core/analytics/models/event/SignIn.kt @@ -17,13 +17,19 @@ sealed class SignIn( ), ) + class ButtonBiometricSignIn : SignIn(event = "Button - Biometric Sign In") + class ButtonUnlockAllWithBiometric : SignIn(event = "Button - Unlock All With Biometric") + class ErrorBiometricUpdated : SignIn(event = "Error - Biometric Updated") + class ButtonWallet( signInType: SignInType, + walletsCount: Int, ) : SignIn( event = "Button - Wallet", params = buildMap { + put("Wallets Count", walletsCount.toString()) put("Sign in type", signInType.value) }, ) { diff --git a/core/analytics/src/main/java/com/tangem/core/analytics/utils/TrackingContextProxy.kt b/core/analytics/src/main/java/com/tangem/core/analytics/utils/TrackingContextProxy.kt index 30671f81d0..23be99e1fd 100644 --- a/core/analytics/src/main/java/com/tangem/core/analytics/utils/TrackingContextProxy.kt +++ b/core/analytics/src/main/java/com/tangem/core/analytics/utils/TrackingContextProxy.kt @@ -23,6 +23,4 @@ interface TrackingContextProxy { fun addHotWalletContext() fun removeContext() - - fun proceedWithContext(userWallet: UserWallet, action: () -> Unit) } \ No newline at end of file diff --git a/domain/card/src/main/kotlin/com/tangem/domain/card/analytics/IntroductionProcess.kt b/domain/card/src/main/kotlin/com/tangem/domain/card/analytics/IntroductionProcess.kt index b6ec1affa6..b7151afd3d 100644 --- a/domain/card/src/main/kotlin/com/tangem/domain/card/analytics/IntroductionProcess.kt +++ b/domain/card/src/main/kotlin/com/tangem/domain/card/analytics/IntroductionProcess.kt @@ -13,6 +13,8 @@ sealed class IntroductionProcess( class ButtonBuyCards : IntroductionProcess("Button - Buy Cards") class ButtonScanCardLegacy : IntroductionProcess("Button - Scan Card") + class CreateWalletIntroScreenOpened : IntroductionProcess("Create Wallet Intro Screen Opened") + class ButtonScanCard( val source: AnalyticsParam.ScreensSources, ) : IntroductionProcess( diff --git a/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModel.kt b/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModel.kt index c72cfae7a2..554c0becb1 100644 --- a/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModel.kt +++ b/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModel.kt @@ -127,9 +127,15 @@ internal class CreateWalletStartModel @Inject constructor( }, ) + init { + analyticsEventHandler.send( + event = IntroductionProcess.CreateWalletIntroScreenOpened(), + ) + } + private fun onScanClick() { analyticsEventHandler.send( - event = IntroductionProcess.ButtonScanCard(AnalyticsParam.ScreensSources.CreateNewWallet), + event = IntroductionProcess.ButtonScanCard(AnalyticsParam.ScreensSources.CreateWalletIntro), ) scanCard() } @@ -137,7 +143,7 @@ internal class CreateWalletStartModel @Inject constructor( private fun onStartWithMobileWalletClick() { analyticsEventHandler.send( event = OnboardingAnalyticsEvent.Onboarding.ButtonMobileWallet( - source = AnalyticsParam.ScreensSources.CreateNewWallet.value, + source = AnalyticsParam.ScreensSources.CreateWalletIntro.value, ), ) if (!isHotWalletCreationSupported()) { @@ -147,11 +153,11 @@ internal class CreateWalletStartModel @Inject constructor( return } - router.push(AppRoute.CreateMobileWallet(AnalyticsParam.ScreensSources.CreateNewWallet.value)) + router.push(AppRoute.CreateMobileWallet(AnalyticsParam.ScreensSources.CreateWalletIntro.value)) } private fun onBuyClick() { - analyticsEventHandler.send(Basic.ButtonBuy(source = AnalyticsParam.ScreensSources.CreateNewWallet)) + analyticsEventHandler.send(Basic.ButtonBuy(source = AnalyticsParam.ScreensSources.CreateWalletIntro)) modelScope.launch { generateBuyTangemCardLinkUseCase.invoke().let { urlOpener.openUrl(it) } } diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/UserWalletListModel.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/UserWalletListModel.kt index 923627f080..f0b9432ebf 100644 --- a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/UserWalletListModel.kt +++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/UserWalletListModel.kt @@ -3,6 +3,9 @@ package com.tangem.features.details.model import com.tangem.common.routing.AppRoute import com.tangem.common.ui.userwallet.handle import com.tangem.common.ui.userwallet.state.UserWalletItemUM +import com.tangem.core.analytics.api.AnalyticsEventHandler +import com.tangem.core.analytics.models.AnalyticsParam +import com.tangem.core.analytics.models.event.SignIn import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.navigation.Router @@ -39,6 +42,7 @@ internal class UserWalletListModel @Inject constructor( private val userWalletSaver: UserWalletSaver, private val hotWalletFeatureToggles: HotWalletFeatureToggles, private val unlockWalletUseCase: UnlockWalletUseCase, + private val analyticsEventHandler: AnalyticsEventHandler, ) : Model() { private val isWalletSavingInProgress: MutableStateFlow = MutableStateFlow(value = false) @@ -87,6 +91,7 @@ internal class UserWalletListModel @Inject constructor( private fun onAddNewWalletClick() { if (hotWalletFeatureToggles.isHotWalletEnabled) { + analyticsEventHandler.send(SignIn.ButtonAddWallet(AnalyticsParam.ScreensSources.SignIn)) router.push(AppRoute.CreateWalletSelection) } else { withProgress(isWalletSavingInProgress) { @@ -105,6 +110,7 @@ internal class UserWalletListModel @Inject constructor( error.handle( onUserCancelled = {}, onAlreadyUnlocked = { router.push(AppRoute.WalletSettings(userWalletId)) }, + analyticsEventHandler = analyticsEventHandler, showMessage = messageSender::send, ) } diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscoderequest/HotAccessCodeRequestModel.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscoderequest/HotAccessCodeRequestModel.kt index ad3e784dd7..ba2bbf512a 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscoderequest/HotAccessCodeRequestModel.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscoderequest/HotAccessCodeRequestModel.kt @@ -1,5 +1,7 @@ package com.tangem.features.hotwallet.accesscoderequest +import com.tangem.core.analytics.api.AnalyticsEventHandler +import com.tangem.core.analytics.models.event.SignIn import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.model.Model import com.tangem.core.ui.components.fields.PinTextColor @@ -33,6 +35,7 @@ internal class HotAccessCodeRequestModel @Inject constructor( private val hotAccessCodeAttemptsRepository: HotWalletAccessCodeAttemptsRepository, private val userWalletsListRepository: UserWalletsListRepository, private val canUseBiometryUseCase: CanUseBiometryUseCase, + private val analyticsEventHandler: AnalyticsEventHandler, ) : Model() { private val result = MutableStateFlow(null) @@ -108,6 +111,7 @@ internal class HotAccessCodeRequestModel @Inject constructor( onAccessCodeChange = ::onAccessCodeChange, accessCode = "", useBiometricClick = { + analyticsEventHandler.send(SignIn.ButtonBiometricSignIn()) dismissState() result.value = HotWalletPasswordRequester.Result.UseBiometry }, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt index 7f79c77cb4..05b094761f 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt @@ -199,6 +199,7 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( error.handle( onAlreadyUnlocked = {}, onUserCancelled = {}, + analyticsEventHandler = analyticsEventHandler, showMessage = uiMessageSender::send, ) } diff --git a/features/welcome/impl/src/main/kotlin/com/tangem/features/welcome/impl/model/WelcomeModel.kt b/features/welcome/impl/src/main/kotlin/com/tangem/features/welcome/impl/model/WelcomeModel.kt index c0a06bc9e6..249109f0e4 100644 --- a/features/welcome/impl/src/main/kotlin/com/tangem/features/welcome/impl/model/WelcomeModel.kt +++ b/features/welcome/impl/src/main/kotlin/com/tangem/features/welcome/impl/model/WelcomeModel.kt @@ -58,14 +58,18 @@ internal class WelcomeModel @Inject constructor( modelScope.launch { val userWallets = userWalletsListRepository.userWalletsSync() val userWallet = userWallets.first { it.walletId == walletId } - trackingContextProxy.proceedWithContext(userWallet) { - val signInType = when { - !userWallet.isLocked -> SignIn.ButtonWallet.SignInType.NoSecurity - userWallet is UserWallet.Cold -> SignIn.ButtonWallet.SignInType.Card - else -> SignIn.ButtonWallet.SignInType.AccessCode - } - analyticsEventHandler.send(SignIn.ButtonWallet(signInType)) + trackingContextProxy.addContext(userWallet) + val signInType = when { + !userWallet.isLocked -> SignIn.ButtonWallet.SignInType.NoSecurity + userWallet is UserWallet.Cold -> SignIn.ButtonWallet.SignInType.Card + else -> SignIn.ButtonWallet.SignInType.AccessCode } + analyticsEventHandler.send( + event = SignIn.ButtonWallet( + signInType = signInType, + walletsCount = userWallets.size, + ), + ) onUserWalletClick(userWallet) } }, @@ -210,6 +214,7 @@ internal class WelcomeModel @Inject constructor( router.replaceAll(AppRoute.Wallet) }, onUserCancelled = { onUserCancelled() }, + analyticsEventHandler = analyticsEventHandler, showMessage = uiMessageSender::send, ) } @@ -226,13 +231,12 @@ internal class WelcomeModel @Inject constructor( private suspend fun trackSignInEvent(userWallet: UserWallet, type: Basic.SignedIn.SignInType) { val walletsCount = userWalletsListRepository.userWalletsSync().size - trackingContextProxy.proceedWithContext(userWallet) { - analyticsEventHandler.send( - event = Basic.SignedIn( - signInType = type, - walletsCount = walletsCount, - ), - ) - } + trackingContextProxy.addContext(userWallet) + analyticsEventHandler.send( + event = Basic.SignedIn( + signInType = type, + walletsCount = walletsCount, + ), + ) } } \ No newline at end of file