From 503bac327d6a5821543a77086829dcdbe87ee3e8 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 29 Nov 2024 16:39:09 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../DefaultOnboardingMultiWalletComponent.kt | 4 ++ .../impl/analytics/OnboardingEvent.kt | 68 +++++++++++++++++++ .../model/MultiWalletAccessCodeModel.kt | 9 +++ .../backup/model/MultiWalletBackupModel.kt | 26 +++++-- .../impl/child/backup/ui/Dialogs.kt | 24 ++++--- .../model/Wallet1ChooseOptionModel.kt | 9 +++ .../model/MultiWalletCreateWalletModel.kt | 16 ++++- .../model/MultiWalletFinalizeModel.kt | 5 +- .../model/MultiWalletSeedPhraseModel.kt | 26 ++++++- .../impl/model/OnboardingMultiWalletModel.kt | 8 +-- .../impl/DefaultOnboardingStepperComponent.kt | 10 +++ 11 files changed, 178 insertions(+), 27 deletions(-) create mode 100644 features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/analytics/OnboardingEvent.kt diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/DefaultOnboardingMultiWalletComponent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/DefaultOnboardingMultiWalletComponent.kt index a5a3d003df..750a119975 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/DefaultOnboardingMultiWalletComponent.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/DefaultOnboardingMultiWalletComponent.kt @@ -18,6 +18,7 @@ import com.arkivanov.decompose.router.slot.navigate import com.arkivanov.decompose.router.stack.* import com.arkivanov.decompose.value.Value import com.arkivanov.essenty.instancekeeper.getOrCreateSimple +import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.decompose.context.childByContext import com.tangem.core.decompose.model.getOrCreateModel @@ -25,6 +26,7 @@ import com.tangem.core.decompose.navigation.inner.InnerNavigation import com.tangem.core.decompose.navigation.inner.InnerNavigationState import com.tangem.core.ui.decompose.ComposableContentComponent import com.tangem.features.onboarding.v2.multiwallet.api.OnboardingMultiWalletComponent +import com.tangem.features.onboarding.v2.multiwallet.impl.analytics.OnboardingEvent import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams import com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode.MultiWalletAccessCodeComponent import com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.MultiWalletBackupComponent @@ -46,6 +48,7 @@ import kotlinx.coroutines.launch internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor( @Assisted private val context: AppComponentContext, @Assisted private val params: OnboardingMultiWalletComponent.Params, + private val analyticsHandler: AnalyticsEventHandler, ) : OnboardingMultiWalletComponent, AppComponentContext by context { private val model: OnboardingMultiWalletModel = getOrCreateModel(params) @@ -182,6 +185,7 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor } Done -> { // final step - navigate to parent + analyticsHandler.send(OnboardingEvent.Finished) val userWallet = childParams.multiWalletState.value.resultUserWallet ?: return params.onDone(userWallet) } diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/analytics/OnboardingEvent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/analytics/OnboardingEvent.kt new file mode 100644 index 0000000000..2945b7ce27 --- /dev/null +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/analytics/OnboardingEvent.kt @@ -0,0 +1,68 @@ +package com.tangem.features.onboarding.v2.multiwallet.impl.analytics + +import com.tangem.core.analytics.models.AnalyticsEvent + +sealed class OnboardingEvent( + category: String, + event: String, + params: Map = mapOf(), +) : AnalyticsEvent(category, event, params) { + + data object Started : OnboardingEvent("Onboarding", "Onboarding Started") + data object Finished : OnboardingEvent("Onboarding", "Onboarding Finished") + + sealed class CreateWallet( + event: String, + params: Map = mapOf(), + ) : OnboardingEvent("Onboarding / Create Wallet", event, params) { + + data object ScreenOpened : CreateWallet("Create Wallet Screen Opened") + data object ButtonCreateWallet : CreateWallet("Button - Create Wallet") + class WalletCreatedSuccessfully( + creationType: WalletCreationType = WalletCreationType.PrivateKey, + seedPhraseLength: Int? = null, + ) : CreateWallet( + event = "Wallet Created Successfully", + params = buildMap { + put("Creation Type", creationType.value) + if (seedPhraseLength != null) { + put("Seed Phrase Length", seedPhraseLength.toString()) + } + }, + ) + + sealed class WalletCreationType(val value: String) { + data object PrivateKey : WalletCreationType(value = "Private Key") + data object NewSeed : WalletCreationType(value = "New Seed") + data object SeedImport : WalletCreationType(value = "Seed Import") + } + } + + sealed class Backup( + event: String, + params: Map = mapOf(), + ) : OnboardingEvent("Onboarding / Backup", event, params) { + + data object ScreenOpened : Backup("Backup Screen Opened") + data object Started : Backup("Backup Started") + data object Skipped : Backup("Backup Skipped") + data object SettingAccessCodeStarted : Backup("Setting Access Code Started") + data object AccessCodeEntered : Backup("Access Code Entered") + data object AccessCodeReEntered : Backup("Access Code Re-entered") + + class Finished(cardsCount: Int) : Backup( + event = "Backup Finished", + params = mapOf("Cards count" to "$cardsCount"), + ) + + data object ResetCancelEvent : Backup( + event = "Reset Card Notification", + params = mapOf("Option" to "Cancel"), + ) + + data object ResetPerformEvent : Backup( + event = "Reset Card Notification", + params = mapOf("Option" to "Reset"), + ) + } +} \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/accesscode/model/MultiWalletAccessCodeModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/accesscode/model/MultiWalletAccessCodeModel.kt index 5d301c7325..755d6c3b3a 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/accesscode/model/MultiWalletAccessCodeModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/accesscode/model/MultiWalletAccessCodeModel.kt @@ -1,9 +1,11 @@ package com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode.model import androidx.compose.ui.text.input.TextFieldValue +import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.decompose.di.ComponentScoped import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer +import com.tangem.features.onboarding.v2.multiwallet.impl.analytics.OnboardingEvent import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams import com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode.ui.state.MultiWalletAccessCodeUM import com.tangem.features.onboarding.v2.multiwallet.impl.model.OnboardingMultiWalletState @@ -23,6 +25,7 @@ internal class MultiWalletAccessCodeModel @Inject constructor( paramsContainer: ParamsContainer, override val dispatchers: CoroutineDispatcherProvider, private val backupServiceHolder: BackupServiceHolder, + private val analyticsHandler: AnalyticsEventHandler, ) : Model() { private val _uiState = MutableStateFlow(getInitialState()) @@ -32,6 +35,8 @@ internal class MultiWalletAccessCodeModel @Inject constructor( val onDismiss = MutableSharedFlow() init { + analyticsHandler.send(OnboardingEvent.Backup.SettingAccessCodeStarted) + params.multiWalletState.update { it.copy(accessCode = null) } @@ -111,6 +116,8 @@ internal class MultiWalletAccessCodeModel @Inject constructor( it.copy(atLeast4CharError = true) } } + + analyticsHandler.send(OnboardingEvent.Backup.AccessCodeEntered) } MultiWalletAccessCodeUM.Step.ConfirmAccessCode -> { if (checkAccessCode()) { @@ -123,6 +130,8 @@ internal class MultiWalletAccessCodeModel @Inject constructor( } modelScope.launch { onDismiss.emit(Unit) } } + + analyticsHandler.send(OnboardingEvent.Backup.AccessCodeReEntered) } } } diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/backup/model/MultiWalletBackupModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/backup/model/MultiWalletBackupModel.kt index 125c6ecc80..89a5685f63 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/backup/model/MultiWalletBackupModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/backup/model/MultiWalletBackupModel.kt @@ -3,6 +3,7 @@ package com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.model import com.google.firebase.crashlytics.FirebaseCrashlytics import com.tangem.common.CompletionResult import com.tangem.common.core.TangemSdkError +import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.decompose.di.ComponentScoped import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer @@ -10,6 +11,7 @@ import com.tangem.core.ui.extensions.resourceReference import com.tangem.domain.card.repository.CardSdkConfigRepository import com.tangem.domain.models.scan.ProductType import com.tangem.features.onboarding.v2.impl.R +import com.tangem.features.onboarding.v2.multiwallet.impl.analytics.OnboardingEvent import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams import com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.MultiWalletBackupComponent import com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.ui.backupCardAttestationFailedDialog @@ -33,6 +35,7 @@ class MultiWalletBackupModel @Inject constructor( private val backupServiceHolder: BackupServiceHolder, private val cardSdkConfigRepository: CardSdkConfigRepository, private val tangemSdkManager: TangemSdkManager, + private val analyticsHandler: AnalyticsEventHandler, ) : Model() { @Suppress("UnusedPrivateMember") @@ -57,6 +60,15 @@ class MultiWalletBackupModel @Inject constructor( val uiState: StateFlow = _uiState val eventFlow = MutableSharedFlow() + init { + // for wallet 1 this event is sent in Wallet1ChooseOptionModel + if (scanResponse.productType == ProductType.Wallet2 || scanResponse.productType == ProductType.Ring) { + analyticsHandler.send(OnboardingEvent.Backup.ScreenOpened) + } + + analyticsHandler.send(OnboardingEvent.Backup.Started) + } + private fun getInitState(): MultiWalletBackupUM { return when (backupService.currentState) { BackupService.State.Preparing -> { @@ -89,9 +101,6 @@ class MultiWalletBackupModel @Inject constructor( if (primaryCard != null) { backupService.setPrimaryCard(primaryCard) addBackupCardWithService() - } else { - // TODO wallet 2 ??? or from main? - // BackupAction.StartAddingPrimaryCard } } @@ -146,6 +155,8 @@ class MultiWalletBackupModel @Inject constructor( } } modelScope.launch { eventFlow.emit(MultiWalletBackupComponent.Event.Done) } + + analyticsHandler.send(OnboardingEvent.Backup.Finished(cardsCount = state.value.backupCardsNumber + 1)) } private fun addBackupCardWithService() { @@ -189,7 +200,12 @@ class MultiWalletBackupModel @Inject constructor( st.copy( dialog = resetBackupCardDialog( onReset = { resetBackupCard(cardId = error.cardId) }, - onDismiss = { _uiState.update { it.copy(dialog = null) } }, + onDismiss = { + _uiState.update { it.copy(dialog = null) } + }, + onDismissClick = { + analyticsHandler.send(OnboardingEvent.Backup.ResetCancelEvent) + }, ), ) } @@ -211,6 +227,8 @@ class MultiWalletBackupModel @Inject constructor( } private fun resetBackupCard(cardId: String) { + analyticsHandler.send(OnboardingEvent.Backup.ResetPerformEvent) + modelScope.launch { tangemSdkManager.resetToFactorySettings( cardId = cardId, diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/backup/ui/Dialogs.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/backup/ui/Dialogs.kt index 5b9acbb42e..15d4a0b457 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/backup/ui/Dialogs.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/backup/ui/Dialogs.kt @@ -4,16 +4,20 @@ import com.tangem.core.ui.extensions.resourceReference import com.tangem.features.onboarding.v2.impl.R import com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.ui.state.MultiWalletBackupUMDialog -internal fun resetBackupCardDialog(onReset: () -> Unit, onDismiss: () -> Unit) = MultiWalletBackupUMDialog( - title = resourceReference(R.string.common_attention), - bodyText = resourceReference(R.string.onboarding_linking_error_card_with_wallets), - confirmText = resourceReference(R.string.common_cancel), - cancelText = resourceReference(R.string.card_settings_action_sheet_reset), - warningCancelColor = true, - onDismiss = onDismiss, - onConfirm = onDismiss, - onCancel = { onReset(); onDismiss() }, -) +internal fun resetBackupCardDialog(onReset: () -> Unit, onDismiss: () -> Unit, onDismissClick: () -> Unit) = + MultiWalletBackupUMDialog( + title = resourceReference(R.string.common_attention), + bodyText = resourceReference(R.string.onboarding_linking_error_card_with_wallets), + confirmText = resourceReference(R.string.common_cancel), + cancelText = resourceReference(R.string.card_settings_action_sheet_reset), + warningCancelColor = true, + onDismiss = { + onDismiss() + onDismissClick() + }, + onConfirm = onDismiss, + onCancel = { onReset(); onDismiss() }, + ) internal fun backupCardAttestationFailedDialog(onDismiss: () -> Unit) = MultiWalletBackupUMDialog( title = resourceReference(R.string.common_error), diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/chooseoption/model/Wallet1ChooseOptionModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/chooseoption/model/Wallet1ChooseOptionModel.kt index d0c206de50..4fe5566d5e 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/chooseoption/model/Wallet1ChooseOptionModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/chooseoption/model/Wallet1ChooseOptionModel.kt @@ -1,5 +1,6 @@ package com.tangem.features.onboarding.v2.multiwallet.impl.child.chooseoption.model +import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.decompose.di.ComponentScoped import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer @@ -9,6 +10,7 @@ import com.tangem.domain.wallets.builder.UserWalletBuilder import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase import com.tangem.domain.wallets.usecase.SaveWalletUseCase +import com.tangem.features.onboarding.v2.multiwallet.impl.analytics.OnboardingEvent import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.flow.MutableSharedFlow @@ -23,18 +25,25 @@ internal class Wallet1ChooseOptionModel @Inject constructor( private val generateWalletNameUseCase: GenerateWalletNameUseCase, private val cardRepository: CardRepository, private val saveWalletUseCase: SaveWalletUseCase, + private val analyticsHandler: AnalyticsEventHandler, ) : Model() { private val params = paramsContainer.require() private var skipClicked = false val returnToParentFlow = MutableSharedFlow() + init { + analyticsHandler.send(OnboardingEvent.Backup.ScreenOpened) + } + fun onSkipClick() { // TODO show confirmation dialog if (skipClicked) return skipClicked = true + analyticsHandler.send(OnboardingEvent.Backup.Skipped) + modelScope.launch { val scanResponse = params.multiWalletState.value.currentScanResponse diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/createwallet/model/MultiWalletCreateWalletModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/createwallet/model/MultiWalletCreateWalletModel.kt index c934b818b3..b7b153a6f7 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/createwallet/model/MultiWalletCreateWalletModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/createwallet/model/MultiWalletCreateWalletModel.kt @@ -2,6 +2,7 @@ package com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.mo import com.tangem.common.CompletionResult import com.tangem.common.core.TangemSdkError +import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.decompose.di.ComponentScoped import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer @@ -11,6 +12,7 @@ import com.tangem.domain.feedback.GetCardInfoUseCase import com.tangem.domain.feedback.SendFeedbackEmailUseCase import com.tangem.domain.feedback.models.FeedbackEmailType import com.tangem.features.onboarding.v2.impl.R +import com.tangem.features.onboarding.v2.multiwallet.impl.analytics.OnboardingEvent import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams import com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.ui.state.MultiWalletCreateWalletUM import com.tangem.features.onboarding.v2.multiwallet.impl.common.ui.resetCardDialog @@ -24,6 +26,7 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import javax.inject.Inject +@Suppress("LongParameterList") @ComponentScoped internal class MultiWalletCreateWalletModel @Inject constructor( paramsContainer: ParamsContainer, @@ -32,6 +35,7 @@ internal class MultiWalletCreateWalletModel @Inject constructor( private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase, private val getCardInfoUseCase: GetCardInfoUseCase, private val cardRepository: CardRepository, + private val analyticsHandler: AnalyticsEventHandler, ) : Model() { private val params = paramsContainer.require() @@ -50,7 +54,10 @@ internal class MultiWalletCreateWalletModel @Inject constructor( } else { resourceReference(R.string.onboarding_create_wallet_body) }, - onCreateWalletClick = { createWallet(false) }, + onCreateWalletClick = { + analyticsHandler.send(OnboardingEvent.CreateWallet.ButtonCreateWallet) + createWallet(false) + }, showOtherOptionsButton = params.parentParams.withSeedPhraseFlow, onOtherOptionsClick = { modelScope.launch { @@ -64,6 +71,10 @@ internal class MultiWalletCreateWalletModel @Inject constructor( val uiState: StateFlow = _uiState val onDone = MutableSharedFlow() + init { + analyticsHandler.send(OnboardingEvent.CreateWallet.ScreenOpened) + } + private fun createWallet(shouldReset: Boolean) { modelScope.launch { val result = tangemSdkManager.createProductWallet( @@ -91,8 +102,7 @@ internal class MultiWalletCreateWalletModel @Inject constructor( onDone.emit(OnboardingMultiWalletState.Step.ChooseBackupOption) } - // TODO - // Analytics.send(Onboarding.CreateWallet.WalletCreatedSuccessfully()) + analyticsHandler.send(OnboardingEvent.CreateWallet.WalletCreatedSuccessfully()) } is CompletionResult.Failure -> { diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/finalize/model/MultiWalletFinalizeModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/finalize/model/MultiWalletFinalizeModel.kt index 590bf7d021..1214bf588d 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/finalize/model/MultiWalletFinalizeModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/finalize/model/MultiWalletFinalizeModel.kt @@ -79,7 +79,7 @@ internal class MultiWalletFinalizeModel @Inject constructor( private fun writePrimaryCard() { val backupService = backupServiceHolder.backupService.get() ?: return - // store.dispatchOnMain(BackupAction.SetHasRing(hasRing = isRing)) + // TODO store.dispatchOnMain(BackupAction.SetHasRing(hasRing = isRing)) val primaryCardBatchId = backupService.primaryCardBatchId ?: return val isRing = isRing(primaryCardBatchId) @@ -108,7 +108,7 @@ internal class MultiWalletFinalizeModel @Inject constructor( private fun writeBackupCard(cardIndex: Int) { val backupService = backupServiceHolder.backupService.get() ?: return - // store.dispatchOnMain(BackupAction.SetHasRing(hasRing = isRing)) + // TODO store.dispatchOnMain(BackupAction.SetHasRing(hasRing = isRing)) val backupCardBatchId = backupService.backupCardsBatchIds.getOrNull(cardIndex) ?: return val isRing = isRing(backupCardBatchId) @@ -120,7 +120,6 @@ internal class MultiWalletFinalizeModel @Inject constructor( is CompletionResult.Success -> { val backupValidator = BackupValidator() if (backupValidator.isValidBackupStatus(CardDTO(result.data)).not()) { - // TODO store.dispatchOnMain(BackupAction.ErrorInBackupCard) walletHasBackupError = true } diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MultiWalletSeedPhraseModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MultiWalletSeedPhraseModel.kt index a1925f6a35..d636e7e2ca 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MultiWalletSeedPhraseModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/child/seedphrase/model/MultiWalletSeedPhraseModel.kt @@ -2,6 +2,7 @@ package com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.mode import com.tangem.common.CompletionResult import com.tangem.common.core.TangemSdkError +import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.decompose.di.ComponentScoped import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer @@ -11,6 +12,7 @@ import com.tangem.domain.card.repository.CardRepository import com.tangem.domain.feedback.GetCardInfoUseCase import com.tangem.domain.feedback.SendFeedbackEmailUseCase import com.tangem.domain.feedback.models.FeedbackEmailType +import com.tangem.features.onboarding.v2.multiwallet.impl.analytics.OnboardingEvent import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model.builder.GenerateSeedPhraseUiStateBuilder import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model.builder.ImportSeedPhraseUiStateBuilder @@ -41,6 +43,7 @@ internal class MultiWalletSeedPhraseModel @Inject constructor( private val cardRepository: CardRepository, private val getCardInfoUseCase: GetCardInfoUseCase, private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase, + private val analyticsHandler: AnalyticsEventHandler, ) : Model() { private val params = paramsContainer.require() @@ -76,6 +79,7 @@ internal class MultiWalletSeedPhraseModel @Inject constructor( state.value.generatedWords12 ?: return@importWallet }, passphrase = null, + generatedSeedPhrase = true, ) }, // ============================================= @@ -85,7 +89,13 @@ internal class MultiWalletSeedPhraseModel @Inject constructor( modelScope = modelScope, mnemonicRepository = mnemonicRepository, updateUiState = { block -> updateUiStateSpecific(block) }, - importWallet = ::importWallet, + importWallet = { mnemonic, passphrase -> + importWallet( + mnemonic = mnemonic, + passphrase = passphrase, + generatedSeedPhrase = false, + ) + }, ) val uiState = _uiState.asStateFlow() @@ -159,7 +169,7 @@ internal class MultiWalletSeedPhraseModel @Inject constructor( // ============================================= // | DON'T FIXME !!! MODIFY WITH CAUTION !!! | // ============================================= - private fun importWallet(mnemonic: Mnemonic, passphrase: String?) { + private fun importWallet(mnemonic: Mnemonic, passphrase: String?, generatedSeedPhrase: Boolean) { val currentState = state.value if (currentState.readyToImport.not()) return @@ -175,7 +185,17 @@ internal class MultiWalletSeedPhraseModel @Inject constructor( when (result) { is CompletionResult.Success -> { - // TODO on success send analytics event + analyticsHandler.send( + OnboardingEvent.CreateWallet.WalletCreatedSuccessfully( + creationType = if (generatedSeedPhrase) { + OnboardingEvent.CreateWallet.WalletCreationType.NewSeed + } else { + OnboardingEvent.CreateWallet.WalletCreationType.SeedImport + }, + seedPhraseLength = mnemonic.mnemonicComponents.size, + ), + ) + multiWalletState.update { it.copy( currentScanResponse = it.currentScanResponse.copy( diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletModel.kt index 8b85a47888..2ebc2f3867 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletModel.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletModel.kt @@ -1,5 +1,6 @@ package com.tangem.features.onboarding.v2.multiwallet.impl.model +import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.decompose.di.ComponentScoped import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer @@ -7,6 +8,7 @@ import com.tangem.core.decompose.navigation.Router import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.wallets.usecase.GetCardImageUseCase import com.tangem.features.onboarding.v2.multiwallet.api.OnboardingMultiWalletComponent +import com.tangem.features.onboarding.v2.multiwallet.impl.analytics.OnboardingEvent import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams import com.tangem.features.onboarding.v2.multiwallet.impl.common.ui.interruptBackupDialog import com.tangem.features.onboarding.v2.multiwallet.impl.ui.state.OnboardingMultiWalletUM @@ -20,6 +22,7 @@ internal class OnboardingMultiWalletModel @Inject constructor( paramsContainer: ParamsContainer, override val dispatchers: CoroutineDispatcherProvider, private val router: Router, + private val analyticsHandler: AnalyticsEventHandler, ) : Model() { private val params = paramsContainer.require() private val getCardImageUseCase = GetCardImageUseCase() @@ -38,10 +41,7 @@ internal class OnboardingMultiWalletModel @Inject constructor( val uiState = _uiState.asStateFlow() init { - // TODO add analytics - // if (!manager.isActivationStarted(notNullCard.cardId)) { - // Analytics.send(Onboarding.Started()) - // } + analyticsHandler.send(OnboardingEvent.Started) initScreenTitle() loadCardArtwork() subscribeToBackups() diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/stepper/impl/DefaultOnboardingStepperComponent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/stepper/impl/DefaultOnboardingStepperComponent.kt index 543671a35c..640ac88a7f 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/stepper/impl/DefaultOnboardingStepperComponent.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/stepper/impl/DefaultOnboardingStepperComponent.kt @@ -6,6 +6,8 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.arkivanov.essenty.instancekeeper.getOrCreateSimple +import com.tangem.core.analytics.api.AnalyticsEventHandler +import com.tangem.core.analytics.models.AnalyticsEvent import com.tangem.core.decompose.context.AppComponentContext import com.tangem.domain.feedback.GetCardInfoUseCase import com.tangem.domain.feedback.SendFeedbackEmailUseCase @@ -23,11 +25,19 @@ internal class DefaultOnboardingStepperComponent @AssistedInject constructor( @Assisted val params: OnboardingStepperComponent.Params, private val getCardInfoUseCase: GetCardInfoUseCase, private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase, + private val analyticsHandler: AnalyticsEventHandler, ) : OnboardingStepperComponent, AppComponentContext by context { override val state = instanceKeeper.getOrCreateSimple { MutableStateFlow(params.initState) } private fun openSupport() { + analyticsHandler.send( + AnalyticsEvent( + category = "Onboarding", + event = "Button - Chat", + ), + ) + componentScope.launch { val cardInfo = getCardInfoUseCase(params.scanResponse).getOrNull() ?: return@launch sendFeedbackEmailUseCase(FeedbackEmailType.DirectUserRequest(cardInfo))