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 41a70887ba..a32012ca51 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 @@ -14,6 +14,7 @@ import com.tangem.tap.common.extensions.setContext import com.tangem.tap.common.extensions.setHotWalletContext import com.tangem.common.extensions.calculateSha256 import com.tangem.common.extensions.toHexString +import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.domain.models.wallet.UserWalletId /** @@ -91,7 +92,7 @@ internal class DefaultTrackingContextProxy(private val abTestsManager: ABTestsMa abTestsManager.setUserProperties( userId = calculateUserIdHash(userWallet.walletId), batch = null, - productType = "Mobile Wallet", + productType = AnalyticsParam.ProductType.MobileWallet.value, firmware = null, ) } 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 805090e6c0..1608ebc3f4 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 @@ -2,13 +2,13 @@ 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.domain.card.analytics.IntroductionProcess import com.tangem.domain.card.analytics.ParamCardCurrencyConverter import com.tangem.domain.card.common.util.cardTypesResolver import com.tangem.domain.models.scan.ProductType import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.wallets.builder.UserWalletIdBuilder -import com.tangem.tap.common.analytics.events.AnalyticsParam import com.tangem.tap.common.extensions.inject import com.tangem.tap.features.demo.DemoHelper import com.tangem.tap.proxy.redux.DaggerGraphState @@ -50,17 +50,17 @@ class CardContextInterceptor( if (scanResponse.productType != ProductType.Ring && userWalletId != null) { val isWalletWithRing = runBlocking { walletsRepository.isWalletWithRing(userWalletId) } - if (isWalletWithRing) return "Ring" + if (isWalletWithRing) return AnalyticsParam.ProductType.Ring.value } return when (scanResponse.productType) { - ProductType.Note -> "Note" - ProductType.Twins -> "Twin" - ProductType.Wallet -> "Wallet" - ProductType.Wallet2 -> "Wallet 2.0" - ProductType.Ring -> "Ring" - ProductType.Start2Coin -> "Start2Coin" - ProductType.Visa -> "VISA" + ProductType.Note -> AnalyticsParam.ProductType.Note.value + ProductType.Twins -> AnalyticsParam.ProductType.Twins.value + ProductType.Wallet -> AnalyticsParam.ProductType.Wallet.value + ProductType.Wallet2 -> AnalyticsParam.ProductType.Wallet2.value + ProductType.Ring -> AnalyticsParam.ProductType.Ring.value + ProductType.Start2Coin -> AnalyticsParam.ProductType.Start2Coin.value + ProductType.Visa -> AnalyticsParam.ProductType.Visa.value else -> if (DemoHelper.isDemoCard(scanResponse)) getDemoCardProductType() else "Other" } } 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 8ed80f5e60..b7be0155f7 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 @@ -13,7 +13,7 @@ class HotWalletContextInterceptor( override fun canBeAppliedTo(event: AnalyticsEvent): Boolean = true override fun intercept(params: MutableMap) { - params[AnalyticsParam.PRODUCT_TYPE] = "Mobile Wallet" + params[AnalyticsParam.PRODUCT_TYPE] = AnalyticsParam.ProductType.MobileWallet.value } companion object { diff --git a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt index 022b1adfc8..bc3d85e945 100644 --- a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt +++ b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt @@ -563,6 +563,8 @@ internal class ChildFactory @Inject constructor( userWalletId = route.userWalletId, isUpgradeFlow = route.isUpgradeFlow, shouldSetAccessCode = route.setAccessCode, + analyticsSource = route.analyticsSource, + analyticsAction = route.analyticsAction, ), componentFactory = createWalletBackupComponentFactory, ) @@ -572,6 +574,7 @@ internal class ChildFactory @Inject constructor( context = context, params = UpdateAccessCodeComponent.Params( userWalletId = route.userWalletId, + source = route.source, ), componentFactory = updateAccessCodeComponentFactory, ) diff --git a/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt b/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt index 850968f92a..92ab4f3da6 100644 --- a/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt +++ b/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt @@ -364,6 +364,8 @@ sealed class AppRoute(val path: String) : Route { @Serializable data class CreateWalletBackup( val userWalletId: UserWalletId, + val analyticsSource: String, + val analyticsAction: String, val isUpgradeFlow: Boolean = false, val setAccessCode: Boolean = false, ) : AppRoute(path = "/create_wallet_backup/${userWalletId.stringValue}") @@ -371,6 +373,7 @@ sealed class AppRoute(val path: String) : Route { @Serializable data class UpdateAccessCode( val userWalletId: UserWalletId, + val source: String, ) : AppRoute(path = "/update_access_code/${userWalletId.stringValue}") @Serializable 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 9fa02703d3..47d586e92e 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 @@ -85,6 +85,10 @@ sealed class AnalyticsParam { data object Markets : ScreensSources("Markets") data object HotWallet : ScreensSources("Hot Wallet") data object TangemPay : ScreensSources("Tangem Pay") + data object WalletSettings : ScreensSources("Wallet Settings") + data object Upgrade : ScreensSources("Upgrade") + data object HardwareWallet : ScreensSources("Hardware Wallet") + data object ImportWallet : ScreensSources("Import Wallet") } sealed class TxSentFrom(val value: String) { @@ -203,6 +207,17 @@ sealed class AnalyticsParam { EMPTY("Empty"), FULL("Full") } + enum class ProductType(val value: String) { + Note("Note"), + Twins("Twins"), + Wallet("Wallet"), + Start2Coin("Start2Coin"), + Wallet2("Wallet 2.0"), + Ring("Ring"), + Visa("VISA"), + MobileWallet("Mobile Wallet"), + } + companion object Key { const val BLOCKCHAIN = "Blockchain" const val TOKEN_PARAM = "Token" diff --git a/domain/wallets/build.gradle.kts b/domain/wallets/build.gradle.kts index 8f794ae784..ad9162e60a 100644 --- a/domain/wallets/build.gradle.kts +++ b/domain/wallets/build.gradle.kts @@ -15,6 +15,7 @@ dependencies { // region Core modules implementation(projects.core.res) implementation(projects.core.utils) + implementation(projects.core.analytics) // endregion // region Domain modules diff --git a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/analytics/Settings.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/analytics/Settings.kt similarity index 81% rename from features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/analytics/Settings.kt rename to domain/wallets/src/main/java/com/tangem/domain/wallets/analytics/Settings.kt index a3e4a8008b..6bc640e1e2 100644 --- a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/analytics/Settings.kt +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/analytics/Settings.kt @@ -1,8 +1,8 @@ -package com.tangem.feature.walletsettings.analytics +package com.tangem.domain.wallets.analytics import com.tangem.core.analytics.models.AnalyticsEvent -internal sealed class Settings( +sealed class Settings( category: String = "Settings", event: String, params: Map = emptyMap(), diff --git a/domain/wallets/src/main/java/com/tangem/domain/wallets/analytics/WalletSettingsAnalyticEvents.kt b/domain/wallets/src/main/java/com/tangem/domain/wallets/analytics/WalletSettingsAnalyticEvents.kt new file mode 100644 index 0000000000..4a46695ee3 --- /dev/null +++ b/domain/wallets/src/main/java/com/tangem/domain/wallets/analytics/WalletSettingsAnalyticEvents.kt @@ -0,0 +1,154 @@ +package com.tangem.domain.wallets.analytics + +import com.tangem.core.analytics.models.AnalyticsEvent +import com.tangem.core.analytics.models.AnalyticsParam +import com.tangem.core.analytics.models.AnalyticsParam.Key.ACTION +import com.tangem.core.analytics.models.AnalyticsParam.Key.STATUS + +sealed class WalletSettingsAnalyticEvents( + category: String = "Settings / Wallet Settings", + event: String, + params: Map = emptyMap(), +) : AnalyticsEvent(category, event, params) { + + data class NftToggleSwitch(val enabled: AnalyticsParam.OnOffState) : WalletSettingsAnalyticEvents( + event = "NFT toggle switch", + params = mapOf(STATUS to enabled.value), + ) + + object WalletSettingsScreenOpened : WalletSettingsAnalyticEvents( + event = "Wallet Settings Screen Opened", + ) + + object ButtonBackup : WalletSettingsAnalyticEvents( + event = "Button - Backup", + ) + + data class ButtonAccessCode( + private val isCodeSet: Boolean, + ) : WalletSettingsAnalyticEvents( + event = "Button - Access Code", + params = mapOf(ACTION to if (isCodeSet) "Changing" else "Set"), + ) + + data class BackupScreenOpened( + val isManualBackupEnabled: Boolean, + ) : WalletSettingsAnalyticEvents( + event = "Backup Screen Opened", + params = mapOf("Manual Backup" to if (isManualBackupEnabled) "Enabled" else "Disabled"), + ) + + object ButtonRecoveryPhrase : WalletSettingsAnalyticEvents( + event = "Button - Recovery phrase", + ) + + data class NoticeBackupFirst( + val source: String, + val action: Action, + ) : WalletSettingsAnalyticEvents( + event = "Notice - Backup First", + params = mapOf( + AnalyticsParam.Key.SOURCE to source, + AnalyticsParam.Key.ACTION to action.value, + ), + ) { + enum class Action(val value: String) { + AccessCode("Access Code"), + Upgrade("Upgrade"), + Remove("Remove"), + } + } + + object ButtonHardwareUpdate : WalletSettingsAnalyticEvents( + event = "Button - Hardware Update", + ) + + object HardwareUpgradeScreenOpened : WalletSettingsAnalyticEvents( + event = "Hardware Upgrade Screen Opened", + ) + + object ButtonCreateNewWallet : WalletSettingsAnalyticEvents( + event = "Button - Create New Wallet", + ) + + object ButtonUpgradeCurrent : WalletSettingsAnalyticEvents( + event = "Button - Upgrade Current", + ) + + object CreateWalletScreenOpened : WalletSettingsAnalyticEvents( + event = "Create Wallet Screen Opened", + ) + + object HardwareBackupScreenOpened : WalletSettingsAnalyticEvents( + event = "Hardware Backup Screen Opened", + ) + + data class RecoveryPhraseScreenInfo( + val source: String, + val action: String, + ) : WalletSettingsAnalyticEvents( + event = "Recovery Phrase Screen Info", + params = mapOf( + AnalyticsParam.Key.SOURCE to source, + AnalyticsParam.Key.ACTION to action, + ), + ) + + data class RecoveryPhraseScreen( + val source: String, + val action: String, + ) : WalletSettingsAnalyticEvents( + event = "Recovery Phrase Screen", + params = mapOf( + AnalyticsParam.Key.SOURCE to source, + AnalyticsParam.Key.ACTION to action, + ), + ) + + data class RecoveryPhraseCheck( + val source: String, + val action: String, + ) : WalletSettingsAnalyticEvents( + event = "Recovery Phrase Check", + params = mapOf( + AnalyticsParam.Key.SOURCE to source, + AnalyticsParam.Key.ACTION to action, + ), + ) + + data class BackupCompleteScreen( + val source: String, + val action: String, + ) : WalletSettingsAnalyticEvents( + event = "Backup Complete Screen", + params = mapOf( + AnalyticsParam.Key.SOURCE to source, + AnalyticsParam.Key.ACTION to action, + ), + ) + + data class AccessCodeScreenOpened( + val source: String, + ) : WalletSettingsAnalyticEvents( + event = "Access Code Screen Opened", + params = mapOf(AnalyticsParam.Key.SOURCE to source), + ) + + data class ReEnterAccessCodeScreen( + val source: String, + ) : WalletSettingsAnalyticEvents( + event = "Re-enter Access Code Screen", + params = mapOf(AnalyticsParam.Key.SOURCE to source), + ) + + object ButtonStartUpgrade : WalletSettingsAnalyticEvents( + event = "Button - Start Upgrade", + ) + + enum class RecoveryPhraseScreenAction(val value: String) { + Upgrade("Upgrade"), + Backup("Backup"), + AccessCode("Access Code"), + Remove("Remove"), + } +} \ No newline at end of file diff --git a/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/CreateWalletBackupComponent.kt b/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/CreateWalletBackupComponent.kt index 7ecc294b25..4ef515352f 100644 --- a/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/CreateWalletBackupComponent.kt +++ b/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/CreateWalletBackupComponent.kt @@ -10,6 +10,8 @@ interface CreateWalletBackupComponent : ComposableContentComponent { val userWalletId: UserWalletId, val isUpgradeFlow: Boolean, val shouldSetAccessCode: Boolean, + val analyticsSource: String, + val analyticsAction: String, ) interface Factory : ComponentFactory diff --git a/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/UpdateAccessCodeComponent.kt b/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/UpdateAccessCodeComponent.kt index 3ca8f98314..a6d223bd14 100644 --- a/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/UpdateAccessCodeComponent.kt +++ b/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/UpdateAccessCodeComponent.kt @@ -7,6 +7,7 @@ import com.tangem.domain.models.wallet.UserWalletId interface UpdateAccessCodeComponent : ComposableContentComponent { data class Params( val userWalletId: UserWalletId, + val source: String, ) interface Factory : ComponentFactory } \ No newline at end of file diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/addexistingwallet/entry/AddExistingWalletModel.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/addexistingwallet/entry/AddExistingWalletModel.kt index 5b08056d7d..e40072474a 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/addexistingwallet/entry/AddExistingWalletModel.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/addexistingwallet/entry/AddExistingWalletModel.kt @@ -2,6 +2,8 @@ package com.tangem.features.hotwallet.addexistingwallet.entry import com.arkivanov.decompose.router.stack.* import com.tangem.common.routing.AppRoute +import com.tangem.core.analytics.api.AnalyticsEventHandler +import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.core.analytics.utils.TrackingContextProxy import com.tangem.core.decompose.di.GlobalUiMessageSender import com.tangem.core.decompose.di.ModelScoped @@ -15,6 +17,7 @@ import com.tangem.core.ui.message.EventMessageAction import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.settings.ShouldAskPermissionUseCase import com.tangem.domain.hotwallet.SetAccessCodeSkippedUseCase +import com.tangem.domain.wallets.analytics.WalletSettingsAnalyticEvents import com.tangem.features.hotwallet.addexistingwallet.entry.routing.AddExistingWalletRoute import com.tangem.features.hotwallet.addexistingwallet.im.port.AddExistingWalletImportComponent import com.tangem.features.hotwallet.manualbackup.completed.ManualBackupCompletedComponent @@ -28,6 +31,7 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.launch import javax.inject.Inject +@Suppress("LongParameterList") @ModelScoped internal class AddExistingWalletModel @Inject constructor( override val dispatchers: CoroutineDispatcherProvider, @@ -36,6 +40,7 @@ internal class AddExistingWalletModel @Inject constructor( @GlobalUiMessageSender private val uiMessageSender: UiMessageSender, private val trackingContextProxy: TrackingContextProxy, private val setAccessCodeSkippedUseCase: SetAccessCodeSkippedUseCase, + private val analyticsEventHandler: AnalyticsEventHandler, ) : Model() { val hotWalletStepperComponentModelCallback = HotWalletStepperComponentModelCallback() @@ -49,6 +54,8 @@ internal class AddExistingWalletModel @Inject constructor( val startRoute = AddExistingWalletRoute.Import val currentRoute: MutableStateFlow = MutableStateFlow(startRoute) + private val analyticsSource = AnalyticsParam.ScreensSources.ImportWallet + init { trackingContextProxy.addHotWalletContext() } @@ -133,6 +140,9 @@ internal class AddExistingWalletModel @Inject constructor( inner class ManualBackupCompletedModelCallbacks : ManualBackupCompletedComponent.ModelCallbacks { override fun onContinueClick(userWalletId: UserWalletId) { + analyticsEventHandler.send( + event = WalletSettingsAnalyticEvents.AccessCodeScreenOpened(source = analyticsSource.value), + ) stackNavigation.replaceAll(AddExistingWalletRoute.SetAccessCode(userWalletId)) } @@ -141,6 +151,9 @@ internal class AddExistingWalletModel @Inject constructor( inner class AccessCodeModelCallbacks : AccessCodeComponent.ModelCallbacks { override fun onNewAccessCodeInput(userWalletId: UserWalletId, accessCode: String) { + analyticsEventHandler.send( + event = WalletSettingsAnalyticEvents.ReEnterAccessCodeScreen(source = analyticsSource.value), + ) stackNavigation.push(AddExistingWalletRoute.ConfirmAccessCode(userWalletId, accessCode)) } diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/CreateHardwareWalletModel.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/CreateHardwareWalletModel.kt index 992eefd69f..da08951a67 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/CreateHardwareWalletModel.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/CreateHardwareWalletModel.kt @@ -23,6 +23,7 @@ import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.common.wallets.error.SaveWalletError import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.settings.repositories.SettingsRepository +import com.tangem.domain.wallets.analytics.WalletSettingsAnalyticEvents import com.tangem.domain.wallets.builder.ColdUserWalletBuilder import com.tangem.domain.wallets.usecase.GenerateBuyTangemCardLinkUseCase import com.tangem.domain.wallets.usecase.SaveWalletUseCase @@ -64,6 +65,10 @@ internal class CreateHardwareWalletModel @Inject constructor( ), ) + init { + analyticsEventHandler.send(WalletSettingsAnalyticEvents.CreateWalletScreenOpened) + } + override fun onDestroy() { super.onDestroy() } diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createwalletbackup/CreateWalletBackupModel.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createwalletbackup/CreateWalletBackupModel.kt index 5980bf78e0..440dadd85a 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createwalletbackup/CreateWalletBackupModel.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createwalletbackup/CreateWalletBackupModel.kt @@ -4,6 +4,7 @@ import com.arkivanov.decompose.router.stack.StackNavigation import com.arkivanov.decompose.router.stack.pop import com.arkivanov.decompose.router.stack.push import com.tangem.common.routing.AppRoute +import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.analytics.utils.TrackingContextProxy import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.model.Model @@ -11,6 +12,7 @@ import com.tangem.core.decompose.model.ParamsContainer import com.tangem.core.decompose.navigation.Router import com.tangem.core.decompose.navigation.popTo import com.tangem.domain.models.wallet.UserWalletId +import com.tangem.domain.wallets.analytics.WalletSettingsAnalyticEvents import com.tangem.features.hotwallet.CreateWalletBackupComponent import com.tangem.features.hotwallet.createwalletbackup.routing.CreateWalletBackupRoute import com.tangem.features.hotwallet.manualbackup.check.ManualBackupCheckComponent @@ -27,6 +29,7 @@ internal class CreateWalletBackupModel @Inject constructor( override val dispatchers: CoroutineDispatcherProvider, private val router: Router, private val trackingContextProxy: TrackingContextProxy, + private val analyticsEventHandler: AnalyticsEventHandler, ) : Model() { val params = paramsContainer.require() @@ -42,6 +45,12 @@ internal class CreateWalletBackupModel @Inject constructor( init { trackingContextProxy.addHotWalletContext() + analyticsEventHandler.send( + event = WalletSettingsAnalyticEvents.RecoveryPhraseScreenInfo( + source = params.analyticsSource, + action = params.analyticsAction, + ), + ) } override fun onDestroy() { @@ -59,14 +68,32 @@ internal class CreateWalletBackupModel @Inject constructor( } fun onManualBackupStarted() { + analyticsEventHandler.send( + event = WalletSettingsAnalyticEvents.RecoveryPhraseScreen( + source = params.analyticsSource, + action = params.analyticsAction, + ), + ) stackNavigation.push(CreateWalletBackupRoute.RecoveryPhrase) } fun onManualBackupPhraseShown() { + analyticsEventHandler.send( + event = WalletSettingsAnalyticEvents.RecoveryPhraseCheck( + source = params.analyticsSource, + action = params.analyticsAction, + ), + ) stackNavigation.push(CreateWalletBackupRoute.ConfirmBackup) } fun onManualBackupChecked() { + analyticsEventHandler.send( + event = WalletSettingsAnalyticEvents.BackupCompleteScreen( + source = params.analyticsSource, + action = params.analyticsAction, + ), + ) stackNavigation.push( configuration = CreateWalletBackupRoute.BackupCompleted( isUpgradeFlow = params.isUpgradeFlow, @@ -80,6 +107,7 @@ internal class CreateWalletBackupModel @Inject constructor( router.replaceCurrent( route = AppRoute.UpdateAccessCode( userWalletId = params.userWalletId, + source = params.analyticsSource, ), ) } else { diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/updateaccesscode/UpdateAccessCodeModel.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/updateaccesscode/UpdateAccessCodeModel.kt index 82c10d1309..cd562b219b 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/updateaccesscode/UpdateAccessCodeModel.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/updateaccesscode/UpdateAccessCodeModel.kt @@ -11,6 +11,8 @@ import com.tangem.domain.models.wallet.UserWalletId import com.tangem.features.hotwallet.UpdateAccessCodeComponent import com.tangem.features.hotwallet.updateaccesscode.routing.UpdateAccessCodeRoute import com.tangem.features.hotwallet.accesscode.AccessCodeComponent +import com.tangem.core.analytics.api.AnalyticsEventHandler +import com.tangem.domain.wallets.analytics.WalletSettingsAnalyticEvents import com.tangem.features.hotwallet.setupfinished.MobileWalletSetupFinishedComponent import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.flow.MutableStateFlow @@ -21,6 +23,7 @@ internal class UpdateAccessCodeModel @Inject constructor( override val dispatchers: CoroutineDispatcherProvider, private val router: Router, paramsContainer: ParamsContainer, + private val analyticsEventHandler: AnalyticsEventHandler, ) : Model(), AccessCodeComponent.ModelCallbacks { private val params = paramsContainer.require() @@ -30,6 +33,10 @@ internal class UpdateAccessCodeModel @Inject constructor( val currentRoute: MutableStateFlow = MutableStateFlow(startRoute) val mobileWalletSetupFinishedComponentModelCallbacks = MobileWalletSetupFinishedComponentModelCallbacks() + init { + analyticsEventHandler.send(WalletSettingsAnalyticEvents.AccessCodeScreenOpened(source = params.source)) + } + fun onChildBack() { when (currentRoute.value) { is UpdateAccessCodeRoute.SetAccessCode -> router.pop() @@ -39,6 +46,7 @@ internal class UpdateAccessCodeModel @Inject constructor( } override fun onNewAccessCodeInput(userWalletId: UserWalletId, accessCode: String) { + analyticsEventHandler.send(WalletSettingsAnalyticEvents.ReEnterAccessCodeScreen(source = params.source)) stackNavigation.push(UpdateAccessCodeRoute.ConfirmAccessCode(userWalletId, accessCode)) } diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/UpgradeWalletModel.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/UpgradeWalletModel.kt index d8d10b2729..976804e17d 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/UpgradeWalletModel.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/UpgradeWalletModel.kt @@ -6,6 +6,7 @@ import com.tangem.common.doOnFailure import com.tangem.common.doOnResult import com.tangem.common.doOnSuccess import com.tangem.common.routing.AppRoute +import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer @@ -25,6 +26,7 @@ import com.tangem.domain.feedback.models.FeedbackEmailType import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.settings.repositories.SettingsRepository +import com.tangem.domain.wallets.analytics.WalletSettingsAnalyticEvents import com.tangem.domain.wallets.builder.ColdUserWalletBuilder import com.tangem.domain.wallets.usecase.ClearHotWalletContextualUnlockUseCase import com.tangem.domain.wallets.usecase.GenerateBuyTangemCardLinkUseCase @@ -58,6 +60,7 @@ internal class UpgradeWalletModel @Inject constructor( private val tangemSdkManager: TangemSdkManager, private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase, private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory, + private val analyticsEventHandler: AnalyticsEventHandler, ) : Model() { private val params = paramsContainer.require() @@ -73,6 +76,10 @@ internal class UpgradeWalletModel @Inject constructor( ), ) + init { + analyticsEventHandler.send(WalletSettingsAnalyticEvents.HardwareUpgradeScreenOpened) + } + override fun onDestroy() { clearHotWalletContextualUnlockUseCase.invoke(params.userWalletId) super.onDestroy() @@ -85,6 +92,7 @@ internal class UpgradeWalletModel @Inject constructor( } private fun onContinueClick() { + analyticsEventHandler.send(WalletSettingsAnalyticEvents.ButtonStartUpgrade) scanCard() } @@ -151,8 +159,6 @@ internal class UpgradeWalletModel @Inject constructor( private fun showCardVerificationFailedDialog(error: TangemError) { if (error !is TangemSdkError.CardVerificationFailed) return - // TODO [REDACTED_TASK_KEY] track error - val resource = error.localizedDescriptionRes() val resId = resource.resId ?: R.string.common_unknown_error val resArgs = resource.args.map { it.value } diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/walletactivation/entry/WalletActivationModel.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/walletactivation/entry/WalletActivationModel.kt index ae8297cc1b..d8f16f65e8 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/walletactivation/entry/WalletActivationModel.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/walletactivation/entry/WalletActivationModel.kt @@ -4,6 +4,8 @@ import com.arkivanov.decompose.router.stack.StackNavigation import com.arkivanov.decompose.router.stack.pop import com.arkivanov.decompose.router.stack.push import com.arkivanov.decompose.router.stack.replaceAll +import com.tangem.core.analytics.api.AnalyticsEventHandler +import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.core.analytics.utils.TrackingContextProxy import com.tangem.core.decompose.di.GlobalUiMessageSender import com.tangem.core.decompose.di.ModelScoped @@ -18,6 +20,7 @@ import com.tangem.core.ui.message.EventMessageAction import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.settings.ShouldAskPermissionUseCase import com.tangem.domain.hotwallet.SetAccessCodeSkippedUseCase +import com.tangem.domain.wallets.analytics.WalletSettingsAnalyticEvents import com.tangem.features.hotwallet.manualbackup.check.ManualBackupCheckComponent import com.tangem.features.hotwallet.manualbackup.completed.ManualBackupCompletedComponent import com.tangem.features.hotwallet.manualbackup.phrase.ManualBackupPhraseComponent @@ -41,9 +44,10 @@ internal class WalletActivationModel @Inject constructor( override val dispatchers: CoroutineDispatcherProvider, private val router: Router, private val shouldAskPermissionUseCase: ShouldAskPermissionUseCase, + private val setAccessCodeSkippedUseCase: SetAccessCodeSkippedUseCase, @GlobalUiMessageSender private val uiMessageSender: UiMessageSender, private val trackingContextProxy: TrackingContextProxy, - private val setAccessCodeSkippedUseCase: SetAccessCodeSkippedUseCase, + private val analyticsEventHandler: AnalyticsEventHandler, ) : Model() { val params = paramsContainer.require() @@ -66,8 +70,19 @@ internal class WalletActivationModel @Inject constructor( } val currentRoute: MutableStateFlow = MutableStateFlow(startRoute) + private val source = AnalyticsParam.ScreensSources.Main + private val action = WalletSettingsAnalyticEvents.RecoveryPhraseScreenAction.Backup + init { trackingContextProxy.addHotWalletContext() + if (startRoute is WalletActivationRoute.ManualBackupStart) { + analyticsEventHandler.send( + event = WalletSettingsAnalyticEvents.RecoveryPhraseScreenInfo( + source = source.value, + action = action.value, + ), + ) + } } override fun onDestroy() { @@ -143,13 +158,23 @@ internal class WalletActivationModel @Inject constructor( inner class ManualBackupStartModelCallbacks : ManualBackupStartComponent.ModelCallbacks { override fun onContinueClick() { stackNavigation.push(WalletActivationRoute.ManualBackupPhrase) + analyticsEventHandler.send( + event = WalletSettingsAnalyticEvents.RecoveryPhraseScreen( + source = source.value, + action = action.value, + ), + ) } } inner class ManualBackupPhraseModelCallbacks : ManualBackupPhraseComponent.ModelCallbacks { override fun onContinueClick() { - stackNavigation.push( - WalletActivationRoute.ManualBackupCheck, + stackNavigation.push(WalletActivationRoute.ManualBackupCheck) + analyticsEventHandler.send( + event = WalletSettingsAnalyticEvents.RecoveryPhraseCheck( + source = source.value, + action = action.value, + ), ) } } @@ -157,6 +182,12 @@ internal class WalletActivationModel @Inject constructor( inner class ManualBackupCheckModelCallbacks : ManualBackupCheckComponent.ModelCallbacks { override fun onCompleteClick() { stackNavigation.push(WalletActivationRoute.ManualBackupCompleted) + analyticsEventHandler.send( + event = WalletSettingsAnalyticEvents.BackupCompleteScreen( + source = source.value, + action = action.value, + ), + ) } } diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/walletbackup/model/WalletBackupModel.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/walletbackup/model/WalletBackupModel.kt index a5986e0a60..1e183bf849 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/walletbackup/model/WalletBackupModel.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/walletbackup/model/WalletBackupModel.kt @@ -1,6 +1,8 @@ package com.tangem.features.hotwallet.walletbackup.model import com.tangem.common.routing.AppRoute +import com.tangem.core.analytics.api.AnalyticsEventHandler +import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer @@ -11,6 +13,7 @@ import com.tangem.core.ui.components.label.entity.LabelStyle import com.tangem.core.ui.components.label.entity.LabelUM import com.tangem.core.ui.extensions.resourceReference import com.tangem.domain.models.wallet.UserWallet +import com.tangem.domain.wallets.analytics.WalletSettingsAnalyticEvents import com.tangem.domain.wallets.usecase.GenerateBuyTangemCardLinkUseCase import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.domain.wallets.usecase.UnlockHotWalletContextualUseCase @@ -27,12 +30,13 @@ import javax.inject.Inject @ModelScoped internal class WalletBackupModel @Inject constructor( paramsContainer: ParamsContainer, + override val dispatchers: CoroutineDispatcherProvider, private val getUserWalletUseCase: GetUserWalletUseCase, private val unlockHotWalletContextualUseCase: UnlockHotWalletContextualUseCase, - override val dispatchers: CoroutineDispatcherProvider, private val generateBuyTangemCardLinkUseCase: GenerateBuyTangemCardLinkUseCase, private val urlOpener: UrlOpener, private val router: Router, + private val analyticsEventHandler: AnalyticsEventHandler, ) : Model() { private val params: WalletBackupComponent.Params = paramsContainer.require() @@ -63,6 +67,7 @@ internal class WalletBackupModel @Inject constructor( ) init { + analyticsEventHandler.send(WalletSettingsAnalyticEvents.BackupScreenOpened(isManualBackupEnabled = true)) getUserWalletUseCase.invokeFlow(params.userWalletId) .onEach { either -> either.fold( @@ -112,6 +117,7 @@ internal class WalletBackupModel @Inject constructor( } private fun onRecoveryPhraseClick() { + analyticsEventHandler.send(WalletSettingsAnalyticEvents.ButtonRecoveryPhrase) if (uiState.value.backedUp) { getUserWalletUseCase.invoke(params.userWalletId) .fold( @@ -132,6 +138,8 @@ internal class WalletBackupModel @Inject constructor( router.push( AppRoute.CreateWalletBackup( userWalletId = params.userWalletId, + analyticsSource = AnalyticsParam.ScreensSources.Backup.value, + analyticsAction = WalletSettingsAnalyticEvents.RecoveryPhraseScreenAction.Backup.value, ), ) } @@ -152,6 +160,7 @@ internal class WalletBackupModel @Inject constructor( } private fun onHardwareWalletClick() { + analyticsEventHandler.send(WalletSettingsAnalyticEvents.ButtonHardwareUpdate) router.push(AppRoute.WalletHardwareBackup(params.userWalletId)) } } \ No newline at end of file diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/wallethardwarebackup/model/WalletHardwareBackupModel.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/wallethardwarebackup/model/WalletHardwareBackupModel.kt index 5b85a497b5..f7e8fff31f 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/wallethardwarebackup/model/WalletHardwareBackupModel.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/wallethardwarebackup/model/WalletHardwareBackupModel.kt @@ -2,6 +2,8 @@ package com.tangem.features.hotwallet.wallethardwarebackup.model import arrow.core.getOrElse import com.tangem.common.routing.AppRoute +import com.tangem.core.analytics.api.AnalyticsEventHandler +import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer @@ -18,6 +20,7 @@ import com.tangem.core.ui.components.label.entity.LabelUM import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.message.bottomSheetMessage import com.tangem.domain.models.wallet.UserWallet +import com.tangem.domain.wallets.analytics.WalletSettingsAnalyticEvents import com.tangem.domain.wallets.usecase.GenerateBuyTangemCardLinkUseCase import com.tangem.domain.wallets.usecase.GetUserWalletUseCase import com.tangem.domain.wallets.usecase.UnlockHotWalletContextualUseCase @@ -46,30 +49,41 @@ internal class WalletHardwareBackupModel @Inject constructor( private val urlOpener: UrlOpener, private val getUserWalletUseCase: GetUserWalletUseCase, private val messageSender: UiMessageSender, + private val analyticsEventHandler: AnalyticsEventHandler, ) : Model() { private val params = paramsContainer.require() private val makeBackupAtFirstAlertBS - get() = bottomSheetMessage { - infoBlock { - icon(R.drawable.ic_passcode_lock_32) { - type = MessageBottomSheetUMV2.Icon.Type.Accent - backgroundType = MessageBottomSheetUMV2.Icon.BackgroundType.SameAsTint + get() = run { + analyticsEventHandler.send( + WalletSettingsAnalyticEvents.NoticeBackupFirst( + source = AnalyticsParam.ScreensSources.HardwareWallet.value, + action = WalletSettingsAnalyticEvents.NoticeBackupFirst.Action.Upgrade, + ), + ) + bottomSheetMessage { + infoBlock { + icon(R.drawable.ic_passcode_lock_32) { + type = MessageBottomSheetUMV2.Icon.Type.Accent + backgroundType = MessageBottomSheetUMV2.Icon.BackgroundType.SameAsTint + } + title = resourceReference(R.string.hw_backup_need_finish_first) + body = resourceReference(R.string.hw_backup_to_upgrade_description) } - title = resourceReference(R.string.hw_backup_need_finish_first) - body = resourceReference(R.string.hw_backup_to_upgrade_description) - } - primaryButton { - text = resourceReference(R.string.hw_backup_need_action) - onClick { - router.push( - AppRoute.CreateWalletBackup( - userWalletId = params.userWalletId, - isUpgradeFlow = true, - ), - ) - closeBs() + primaryButton { + text = resourceReference(R.string.hw_backup_need_action) + onClick { + router.push( + AppRoute.CreateWalletBackup( + userWalletId = params.userWalletId, + isUpgradeFlow = true, + analyticsSource = AnalyticsParam.ScreensSources.HardwareWallet.value, + analyticsAction = WalletSettingsAnalyticEvents.RecoveryPhraseScreenAction.Upgrade.value, + ), + ) + closeBs() + } } } } @@ -100,6 +114,7 @@ internal class WalletHardwareBackupModel @Inject constructor( ) init { + analyticsEventHandler.send(WalletSettingsAnalyticEvents.HardwareBackupScreenOpened) showPurchaseBlockWithDelay() } @@ -111,6 +126,7 @@ internal class WalletHardwareBackupModel @Inject constructor( } private fun onCreateNewWalletClick() { + analyticsEventHandler.send(WalletSettingsAnalyticEvents.ButtonCreateNewWallet) router.push(AppRoute.CreateHardwareWallet) } @@ -118,6 +134,7 @@ internal class WalletHardwareBackupModel @Inject constructor( val userWallet = getUserWalletUseCase.invoke(params.userWalletId) .getOrElse { error("Cannot find user wallet with id: ${params.userWalletId.stringValue}") } if (userWallet is UserWallet.Hot) { + analyticsEventHandler.send(WalletSettingsAnalyticEvents.ButtonUpgradeCurrent) if (!userWallet.backedUp) { messageSender.send(makeBackupAtFirstAlertBS) } else { diff --git a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/analytics/WalletSettingsAnalyticEvents.kt b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/analytics/WalletSettingsAnalyticEvents.kt deleted file mode 100644 index 37898660f7..0000000000 --- a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/analytics/WalletSettingsAnalyticEvents.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.tangem.feature.walletsettings.analytics - -import com.tangem.core.analytics.models.AnalyticsEvent -import com.tangem.core.analytics.models.AnalyticsParam -import com.tangem.core.analytics.models.AnalyticsParam.Key.STATUS - -internal sealed class WalletSettingsAnalyticEvents( - category: String = "Settings / Wallet", - event: String, - params: Map = emptyMap(), -) : AnalyticsEvent(category, event, params) { - - data class NftToggleSwitch(val enabled: AnalyticsParam.OnOffState) : WalletSettingsAnalyticEvents( - event = "NFT toggle switch", - params = mapOf(STATUS to enabled.value), - ) -} \ No newline at end of file diff --git a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/component/preview/PreviewWalletSettingsComponent.kt b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/component/preview/PreviewWalletSettingsComponent.kt index 4c6713f424..bdf3f94838 100644 --- a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/component/preview/PreviewWalletSettingsComponent.kt +++ b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/component/preview/PreviewWalletSettingsComponent.kt @@ -5,7 +5,6 @@ import androidx.compose.ui.Modifier import com.tangem.common.ui.account.AccountIconPreviewData import com.tangem.common.ui.userwallet.state.UserWalletItemUM import com.tangem.common.ui.userwallet.state.UserWalletItemUM.ImageState -import com.tangem.core.decompose.navigation.DummyRouter import com.tangem.core.ui.components.block.model.BlockUM import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringReference @@ -43,9 +42,7 @@ internal class PreviewWalletSettingsComponent : WalletSettingsComponent { private val previewState = WalletSettingsUM( popBack = {}, - items = ItemsBuilder( - router = DummyRouter(), - ).buildItems( + items = ItemsBuilder().buildItems( userWallet = UserWallet.Hot( walletId = UserWalletId("011"), name = "My Wallet", @@ -71,6 +68,8 @@ internal class PreviewWalletSettingsComponent : WalletSettingsComponent { walletUpgradeDismissed = false, onUpgradeWalletClick = {}, onDismissUpgradeWalletClick = {}, + onBackupClick = {}, + onCardSettingsClick = {}, accountsUM = previewAccounts(), cardItem = previewCardBlock(), ), diff --git a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/model/WalletSettingsModel.kt b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/model/WalletSettingsModel.kt index 99cb03e19a..826d89ac75 100644 --- a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/model/WalletSettingsModel.kt +++ b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/model/WalletSettingsModel.kt @@ -8,6 +8,7 @@ import com.arkivanov.decompose.router.slot.activate import com.tangem.common.routing.AppRoute import com.tangem.common.routing.AppRoute.ManageTokens.Source import com.tangem.core.analytics.api.AnalyticsEventHandler +import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.core.analytics.models.AnalyticsParam.OnOffState.Off import com.tangem.core.analytics.models.AnalyticsParam.OnOffState.On import com.tangem.core.analytics.utils.TrackingContextProxy @@ -36,9 +37,10 @@ import com.tangem.domain.nft.EnableWalletNFTUseCase import com.tangem.domain.nft.GetWalletNFTEnabledUseCase import com.tangem.domain.notifications.repository.NotificationsRepository import com.tangem.domain.settings.repositories.PermissionRepository +import com.tangem.domain.wallets.analytics.Settings +import com.tangem.domain.wallets.analytics.WalletSettingsAnalyticEvents +import com.tangem.domain.wallets.analytics.WalletSettingsAnalyticEvents.RecoveryPhraseScreenAction import com.tangem.domain.wallets.usecase.* -import com.tangem.feature.walletsettings.analytics.Settings -import com.tangem.feature.walletsettings.analytics.WalletSettingsAnalyticEvents import com.tangem.feature.walletsettings.component.WalletSettingsComponent import com.tangem.feature.walletsettings.entity.* import com.tangem.feature.walletsettings.impl.R @@ -111,8 +113,9 @@ internal class WalletSettingsModel @Inject constructor( ) init { - getUserWalletUseCase.invoke(params.userWalletId).onRight { - trackingContextProxy.addContext(it) + getUserWalletUseCase.invoke(params.userWalletId).onRight { wallet -> + trackingContextProxy.addContext(wallet) + analyticsEventHandler.send(WalletSettingsAnalyticEvents.WalletSettingsScreenOpened) } fun combineUI(wallet: UserWallet) = combine( @@ -235,10 +238,12 @@ internal class WalletSettingsModel @Inject constructor( isNotificationsPermissionGranted = isNotificationsPermissionGranted, onCheckedNotificationsChanged = ::onCheckedNotificationsChange, onNotificationsDescriptionClick = ::onNotificationsDescriptionClick, - onAccessCodeClick = ::onAccessCodeClick, + onAccessCodeClick = { onAccessCodeClick(userWallet) }, walletUpgradeDismissed = isUpgradeNotificationEnabled, - onUpgradeWalletClick = ::onUpgradeWalletClick, + onUpgradeWalletClick = { onUpgradeWalletClick() }, onDismissUpgradeWalletClick = ::onDismissUpgradeWalletClick, + onBackupClick = ::onBackupClick, + onCardSettingsClick = ::onCardSettingsClick, accountsUM = accountList, ) } @@ -262,7 +267,6 @@ internal class WalletSettingsModel @Inject constructor( } private fun onLinkMoreCardsClick(scanResponse: ScanResponse) { - analyticsEventHandler.send(Settings.ButtonCreateBackup) trackingContextProxy.addContext(scanResponse) router.push( @@ -357,23 +361,35 @@ internal class WalletSettingsModel @Inject constructor( } } - private fun onAccessCodeClick() { - if (!state.value.isWalletBackedUp) { - showMakeBackupAtFirstAlertBS(isUpgradeFlow = false) - } else { - unlockWalletIfNeedAndProceed { authorizationRequired -> - router.push( - route = AppRoute.UpdateAccessCode( - userWalletId = params.userWalletId, - ), + private fun onAccessCodeClick(userWallet: UserWallet) { + if (userWallet is UserWallet.Hot) { + val isCodeSet = userWallet.hotWalletId.authType != HotWalletId.AuthType.NoPassword + analyticsEventHandler.send(WalletSettingsAnalyticEvents.ButtonAccessCode(isCodeSet)) + if (!state.value.isWalletBackedUp) { + showMakeBackupAtFirstAlertBS( + isUpgradeFlow = false, + action = WalletSettingsAnalyticEvents.NoticeBackupFirst.Action.AccessCode, ) + } else { + unlockWalletIfNeedAndProceed { authorizationRequired -> + router.push( + route = AppRoute.UpdateAccessCode( + userWalletId = params.userWalletId, + source = AnalyticsParam.ScreensSources.WalletSettings.value, + ), + ) + } } } } private fun onUpgradeWalletClick() { + analyticsEventHandler.send(WalletSettingsAnalyticEvents.ButtonHardwareUpdate) if (!state.value.isWalletBackedUp) { - showMakeBackupAtFirstAlertBS(isUpgradeFlow = true) + showMakeBackupAtFirstAlertBS( + isUpgradeFlow = true, + action = WalletSettingsAnalyticEvents.NoticeBackupFirst.Action.Upgrade, + ) } else { unlockWalletIfNeedAndProceed { router.push(AppRoute.UpgradeWallet(userWalletId = params.userWalletId)) @@ -387,7 +403,25 @@ internal class WalletSettingsModel @Inject constructor( } } - private fun showMakeBackupAtFirstAlertBS(isUpgradeFlow: Boolean) { + private fun onBackupClick() { + analyticsEventHandler.send(WalletSettingsAnalyticEvents.ButtonBackup) + router.push(AppRoute.WalletBackup(params.userWalletId)) + } + + private fun onCardSettingsClick() { + router.push(AppRoute.CardSettings(params.userWalletId)) + } + + private fun showMakeBackupAtFirstAlertBS( + action: WalletSettingsAnalyticEvents.NoticeBackupFirst.Action, + isUpgradeFlow: Boolean, + ) { + analyticsEventHandler.send( + event = WalletSettingsAnalyticEvents.NoticeBackupFirst( + source = AnalyticsParam.ScreensSources.WalletSettings.value, + action = action, + ), + ) val message = bottomSheetMessage { infoBlock { icon(R.drawable.ic_passcode_lock_32) { @@ -405,6 +439,12 @@ internal class WalletSettingsModel @Inject constructor( userWalletId = params.userWalletId, isUpgradeFlow = isUpgradeFlow, setAccessCode = true, + analyticsSource = AnalyticsParam.ScreensSources.WalletSettings.value, + analyticsAction = if (isUpgradeFlow) { + RecoveryPhraseScreenAction.Backup.value + } else { + RecoveryPhraseScreenAction.AccessCode.value + }, ), ) closeBs() @@ -478,6 +518,15 @@ internal class WalletSettingsModel @Inject constructor( ) } is UserWallet.Hot -> { + if (!userWallet.backedUp) { + analyticsEventHandler.send( + event = WalletSettingsAnalyticEvents.NoticeBackupFirst( + source = AnalyticsParam.ScreensSources.WalletSettings.value, + action = WalletSettingsAnalyticEvents.NoticeBackupFirst.Action.Remove, + ), + ) + } + bottomSheetMessage { infoBlock { icon(R.drawable.ic_alert_circle_24) { @@ -525,6 +574,8 @@ internal class WalletSettingsModel @Inject constructor( router.push( AppRoute.CreateWalletBackup( userWalletId = userWallet.walletId, + analyticsSource = AnalyticsParam.ScreensSources.WalletSettings.value, + analyticsAction = RecoveryPhraseScreenAction.Remove.value, ), ) closeBs() diff --git a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/ItemsBuilder.kt b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/ItemsBuilder.kt index 9ea22eaee1..ed3c42d51e 100644 --- a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/ItemsBuilder.kt +++ b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/ItemsBuilder.kt @@ -1,8 +1,6 @@ package com.tangem.feature.walletsettings.utils -import com.tangem.common.routing.AppRoute import com.tangem.core.decompose.di.ModelScoped -import com.tangem.core.decompose.navigation.Router import com.tangem.core.ui.components.block.model.BlockUM import com.tangem.core.ui.components.label.entity.LabelStyle import com.tangem.core.ui.components.label.entity.LabelUM @@ -18,9 +16,7 @@ import kotlinx.collections.immutable.toImmutableList import javax.inject.Inject @ModelScoped -internal class ItemsBuilder @Inject constructor( - private val router: Router, -) { +internal class ItemsBuilder @Inject constructor() { @Suppress("LongParameterList") fun buildItems( @@ -45,6 +41,8 @@ internal class ItemsBuilder @Inject constructor( walletUpgradeDismissed: Boolean, onUpgradeWalletClick: () -> Unit, onDismissUpgradeWalletClick: () -> Unit, + onBackupClick: () -> Unit, + onCardSettingsClick: () -> Unit, ): PersistentList = persistentListOf() .add(cardItem) .addAll( @@ -66,6 +64,8 @@ internal class ItemsBuilder @Inject constructor( onLinkMoreCardsClick = onLinkMoreCardsClick, onReferralClick = onReferralClick, onManageTokensClick = onManageTokensClick, + onBackupClick = onBackupClick, + onCardSettingsClick = onCardSettingsClick, ), ) .addAll( @@ -173,18 +173,19 @@ internal class ItemsBuilder @Inject constructor( onLinkMoreCardsClick: () -> Unit, onReferralClick: () -> Unit, onManageTokensClick: () -> Unit, + onBackupClick: () -> Unit, + onCardSettingsClick: () -> Unit, ) = WalletSettingsItemUM.WithItems( id = "card", description = resourceReference(R.string.settings_card_settings_footer), blocks = buildList { - val userWalletId = userWallet.walletId val isHotWallet = userWallet is UserWallet.Hot if (isHotWallet) { val hasBackup = userWallet.backedUp val backupBlock = BlockUM( text = resourceReference(R.string.common_backup), iconRes = R.drawable.ic_more_cards_24, - onClick = { router.push(AppRoute.WalletBackup(userWalletId)) }, + onClick = { onBackupClick() }, endContent = if (hasBackup) { BlockUM.EndContent.None } else { @@ -224,7 +225,7 @@ internal class ItemsBuilder @Inject constructor( val deviceSettingsBlock = BlockUM( text = resourceReference(R.string.card_settings_title), iconRes = R.drawable.ic_card_settings_24, - onClick = { router.push(AppRoute.CardSettings(userWalletId)) }, + onClick = { onCardSettingsClick() }, ) add(deviceSettingsBlock)