From 9932fc7ab948a41f1ba67adfd3248b560e392fbb Mon Sep 17 00:00:00 2001 From: ohassine Date: Fri, 13 Dec 2024 16:45:20 +0100 Subject: [PATCH 1/3] feat: update Countly events for personal to team migration --- .../userprofile/self/SelfUserProfileScreen.kt | 9 ++++- .../self/SelfUserProfileViewModel.kt | 10 ++++- .../teammigration/TeamMigrationScreen.kt | 18 ++++++++- .../teammigration/TeamMigrationViewModel.kt | 24 ++++++----- .../self/SelfUserProfileViewModelTest.kt | 19 ++++++++- .../TeamMigrationViewModelTest.kt | 21 ---------- .../feature/analytics/model/AnalyticsEvent.kt | 40 ++++++++++++++----- 7 files changed, 95 insertions(+), 46 deletions(-) diff --git a/app/src/main/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileScreen.kt b/app/src/main/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileScreen.kt index 628b9107c6b..8814568aff8 100644 --- a/app/src/main/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileScreen.kt +++ b/app/src/main/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileScreen.kt @@ -125,7 +125,12 @@ fun SelfUserProfileScreen( SelfUserProfileContent( state = viewModelSelf.userProfileState, - onCloseClick = navigator::navigateBack, + onCloseClick = { + if (viewModelSelf.userProfileState.isAbleToMigrateToTeamAccount) { + viewModelSelf.sendPersonalToTeamMigrationDismissed() + } + navigator.navigateBack() + }, logout = { viewModelSelf.logout(it, NavigationSwitchAccountActions(navigator::navigate)) }, onChangeUserProfilePicture = { navigator.navigate( @@ -154,7 +159,7 @@ fun SelfUserProfileScreen( navigator.navigate(NavigationCommand(SelfQRCodeScreenDestination(viewModelSelf.userProfileState.userName))) }, onCreateAccount = { - viewModelSelf.sendPersonalToTeamMigrationEvent() + viewModelSelf.sendPersonalToTeamMigrationEventCTAClicked() navigator.navigate(NavigationCommand(TeamMigrationScreenDestination)) }, onAccountDetailsClick = { navigator.navigate(NavigationCommand(MyAccountScreenDestination)) }, diff --git a/app/src/main/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileViewModel.kt b/app/src/main/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileViewModel.kt index d2cce6e052a..f90238bafeb 100644 --- a/app/src/main/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileViewModel.kt @@ -317,7 +317,7 @@ class SelfUserProfileViewModel @Inject constructor( anonymousAnalyticsManager.sendEvent(AnalyticsEvent.QrCode.Click(!userProfileState.teamName.isNullOrBlank())) } - fun sendPersonalToTeamMigrationEvent() { + fun sendPersonalToTeamMigrationEventCTAClicked() { anonymousAnalyticsManager.sendEvent( AnalyticsEvent.PersonalTeamMigration.ClickedPersonalTeamMigrationCta( createTeamButtonClicked = true @@ -325,6 +325,14 @@ class SelfUserProfileViewModel @Inject constructor( ) } + fun sendPersonalToTeamMigrationDismissed() { + anonymousAnalyticsManager.sendEvent( + AnalyticsEvent.PersonalTeamMigration.ClickedPersonalTeamMigrationCta( + dismissCreateTeamButtonClicked = true + ) + ) + } + sealed class ErrorCodes { data object DownloadUserInfoError : ErrorCodes() } diff --git a/app/src/main/kotlin/com/wire/android/ui/userprofile/teammigration/TeamMigrationScreen.kt b/app/src/main/kotlin/com/wire/android/ui/userprofile/teammigration/TeamMigrationScreen.kt index 1fb026631a7..acea62d7afc 100644 --- a/app/src/main/kotlin/com/wire/android/ui/userprofile/teammigration/TeamMigrationScreen.kt +++ b/app/src/main/kotlin/com/wire/android/ui/userprofile/teammigration/TeamMigrationScreen.kt @@ -113,7 +113,6 @@ fun TeamMigrationScreen( if (navController.currentDestination?.route == NavGraphs.personalToTeamMigration.destinations.last().route) { navigator.navigateBack() } else { - teamMigrationViewModel.sendPersonalToTeamMigrationDismissed() teamMigrationViewModel.showMigrationLeaveDialog() } } @@ -150,6 +149,23 @@ fun TeamMigrationScreen( teamMigrationViewModel.sendPersonalTeamCreationFlowCanceledEvent( modalLeaveClicked = true ) + when (teamMigrationViewModel.teamMigrationState.currentStep) { + TEAM_MIGRATION_TEAM_PLAN_STEP -> { + teamMigrationViewModel.sendPersonalTeamCreationFlowStoppedEvent(isOnDisclaimerStep = true) + } + + TEAM_MIGRATION_TEAM_NAME_STEP -> { + teamMigrationViewModel.sendPersonalTeamCreationFlowStoppedEvent(isOnTeamNameStep = true) + } + + TEAM_MIGRATION_CONFIRMATION_STEP -> { + teamMigrationViewModel.sendPersonalTeamCreationFlowStoppedEvent(isOnConfirmationStep = true) + } + + else -> { + // Nothing to send + } + } navigator.navigateBack() } } diff --git a/app/src/main/kotlin/com/wire/android/ui/userprofile/teammigration/TeamMigrationViewModel.kt b/app/src/main/kotlin/com/wire/android/ui/userprofile/teammigration/TeamMigrationViewModel.kt index 1c527b15d76..bf2b90fde04 100644 --- a/app/src/main/kotlin/com/wire/android/ui/userprofile/teammigration/TeamMigrationViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/userprofile/teammigration/TeamMigrationViewModel.kt @@ -57,14 +57,6 @@ class TeamMigrationViewModel @Inject constructor( teamMigrationState = teamMigrationState.copy(shouldShowMigrationLeaveDialog = false) } - fun sendPersonalToTeamMigrationDismissed() { - anonymousAnalyticsManager.sendEvent( - AnalyticsEvent.PersonalTeamMigration.ClickedPersonalTeamMigrationCta( - dismissCreateTeamButtonClicked = true - ) - ) - } - fun sendPersonalTeamCreationFlowStartedEvent(step: Int) { anonymousAnalyticsManager.sendEvent( AnalyticsEvent.PersonalTeamMigration.PersonalTeamCreationFlowStarted(step) @@ -81,20 +73,32 @@ class TeamMigrationViewModel @Inject constructor( ) { anonymousAnalyticsManager.sendEvent( AnalyticsEvent.PersonalTeamMigration.PersonalTeamCreationFlowCanceled( - teamName = teamMigrationState.teamNameTextState.text.toString(), modalLeaveClicked = modalLeaveClicked, modalContinueClicked = modalContinueClicked ) ) } + fun sendPersonalTeamCreationFlowStoppedEvent( + isOnDisclaimerStep: Boolean? = null, + isOnTeamNameStep: Boolean? = null, + isOnConfirmationStep: Boolean? = null + ) { + anonymousAnalyticsManager.sendEvent( + AnalyticsEvent.PersonalTeamMigration.PersonalTeamCreationFlowStopped( + isOnTeamNameStep = isOnTeamNameStep, + isOnConfirmationStep = isOnConfirmationStep, + isOnDisclaimerStep = isOnDisclaimerStep + ) + ) + } + fun sendPersonalTeamCreationFlowCompletedEvent( modalOpenTeamManagementButtonClicked: Boolean? = null, backToWireButtonClicked: Boolean? = null ) { anonymousAnalyticsManager.sendEvent( AnalyticsEvent.PersonalTeamMigration.PersonalTeamCreationFlowCompleted( - teamName = teamMigrationState.teamNameTextState.text.toString(), modalOpenTeamManagementButtonClicked = modalOpenTeamManagementButtonClicked, backToWireButtonClicked = backToWireButtonClicked ) diff --git a/app/src/test/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileViewModelTest.kt b/app/src/test/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileViewModelTest.kt index 74d035e56c5..cd30c6da341 100644 --- a/app/src/test/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileViewModelTest.kt +++ b/app/src/test/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileViewModelTest.kt @@ -72,7 +72,7 @@ class SelfUserProfileViewModelTest { .withLegalHoldStatus(LegalHoldStateForSelfUser.Disabled) .arrange() - viewModel.sendPersonalToTeamMigrationEvent() + viewModel.sendPersonalToTeamMigrationEventCTAClicked() verify(exactly = 1) { arrangement.anonymousAnalyticsManager.sendEvent( @@ -82,4 +82,21 @@ class SelfUserProfileViewModelTest { ) } } + @Test + fun `given close modal event, when sendPersonalToTeamMigrationDismissed is called, then send the event`() = + runTest { + val (arrangement, viewModel) = SelfUserProfileViewModelArrangement() + .withLegalHoldStatus(LegalHoldStateForSelfUser.Disabled) + .arrange() + + viewModel.sendPersonalToTeamMigrationDismissed() + + verify(exactly = 1) { + arrangement.anonymousAnalyticsManager.sendEvent( + AnalyticsEvent.PersonalTeamMigration.ClickedPersonalTeamMigrationCta( + dismissCreateTeamButtonClicked = true + ) + ) + } + } } diff --git a/app/src/test/kotlin/com/wire/android/ui/userprofile/teammigration/TeamMigrationViewModelTest.kt b/app/src/test/kotlin/com/wire/android/ui/userprofile/teammigration/TeamMigrationViewModelTest.kt index fcaf3011bb8..8fb30394cc2 100644 --- a/app/src/test/kotlin/com/wire/android/ui/userprofile/teammigration/TeamMigrationViewModelTest.kt +++ b/app/src/test/kotlin/com/wire/android/ui/userprofile/teammigration/TeamMigrationViewModelTest.kt @@ -65,23 +65,6 @@ class TeamMigrationViewModelTest { assertEquals(false, viewModel.teamMigrationState.shouldShowMigrationLeaveDialog) } - @Test - fun `given close modal event, when sendPersonalToTeamMigrationDismissed is called, then send the event`() = - runTest { - val (arrangement, viewModel) = Arrangement() - .arrange() - - viewModel.sendPersonalToTeamMigrationDismissed() - - verify(exactly = 1) { - arrangement.anonymousAnalyticsManager.sendEvent( - AnalyticsEvent.PersonalTeamMigration.ClickedPersonalTeamMigrationCta( - dismissCreateTeamButtonClicked = true - ) - ) - } - } - @Test fun `given the step of migration flow, when sendPersonalTeamCreationFlowStartedEvent is called, then send the event`() = runTest { @@ -109,7 +92,6 @@ class TeamMigrationViewModelTest { verify(exactly = 1) { arrangement.anonymousAnalyticsManager.sendEvent( AnalyticsEvent.PersonalTeamMigration.PersonalTeamCreationFlowCanceled( - teamName = viewModel.teamMigrationState.teamNameTextState.text.toString(), modalLeaveClicked = true ) ) @@ -127,7 +109,6 @@ class TeamMigrationViewModelTest { verify(exactly = 1) { arrangement.anonymousAnalyticsManager.sendEvent( AnalyticsEvent.PersonalTeamMigration.PersonalTeamCreationFlowCanceled( - teamName = viewModel.teamMigrationState.teamNameTextState.text.toString(), modalContinueClicked = true ) ) @@ -147,7 +128,6 @@ class TeamMigrationViewModelTest { verify(exactly = 1) { arrangement.anonymousAnalyticsManager.sendEvent( AnalyticsEvent.PersonalTeamMigration.PersonalTeamCreationFlowCompleted( - teamName = viewModel.teamMigrationState.teamNameTextState.text.toString(), modalOpenTeamManagementButtonClicked = true ) ) @@ -165,7 +145,6 @@ class TeamMigrationViewModelTest { verify(exactly = 1) { arrangement.anonymousAnalyticsManager.sendEvent( AnalyticsEvent.PersonalTeamMigration.PersonalTeamCreationFlowCompleted( - teamName = viewModel.teamMigrationState.teamNameTextState.text.toString(), backToWireButtonClicked = true ) ) diff --git a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/model/AnalyticsEvent.kt b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/model/AnalyticsEvent.kt index b08eb4585b5..b5fe97b7946 100644 --- a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/model/AnalyticsEvent.kt +++ b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/model/AnalyticsEvent.kt @@ -29,17 +29,20 @@ import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CLICKED_ import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CLICKED_PERSONAL_MIGRATION_CTA_EVENT import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CONTRIBUTED_LOCATION import com.wire.android.feature.analytics.model.AnalyticsEventConstants.MESSAGE_ACTION_KEY -import com.wire.android.feature.analytics.model.AnalyticsEventConstants.QR_CODE_SEGMENTATION_USER_TYPE_PERSONAL -import com.wire.android.feature.analytics.model.AnalyticsEventConstants.QR_CODE_SEGMENTATION_USER_TYPE_TEAM import com.wire.android.feature.analytics.model.AnalyticsEventConstants.MIGRATION_DOT_ACTIVE import com.wire.android.feature.analytics.model.AnalyticsEventConstants.MODAL_BACK_TO_WIRE_CLICKED +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.MODAL_CONFIRMATION import com.wire.android.feature.analytics.model.AnalyticsEventConstants.MODAL_CONTINUE_CLICKED +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.MODAL_DISCLAIMERS import com.wire.android.feature.analytics.model.AnalyticsEventConstants.MODAL_LEAVE_CLICKED import com.wire.android.feature.analytics.model.AnalyticsEventConstants.MODAL_OPEN_TEAM_MANAGEMENT_CLICKED import com.wire.android.feature.analytics.model.AnalyticsEventConstants.MODAL_TEAM_NAME import com.wire.android.feature.analytics.model.AnalyticsEventConstants.PERSONAL_TEAM_CREATION_FLOW_CANCELLED import com.wire.android.feature.analytics.model.AnalyticsEventConstants.PERSONAL_TEAM_CREATION_FLOW_COMPLETED import com.wire.android.feature.analytics.model.AnalyticsEventConstants.PERSONAL_TEAM_CREATION_FLOW_STARTED_EVENT +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.PERSONAL_TEAM_CREATION_FLOW_STOPPED_EVENT +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.QR_CODE_SEGMENTATION_USER_TYPE_PERSONAL +import com.wire.android.feature.analytics.model.AnalyticsEventConstants.QR_CODE_SEGMENTATION_USER_TYPE_TEAM import com.wire.android.feature.analytics.model.AnalyticsEventConstants.STEP_MODAL_CREATE_TEAM import com.wire.android.feature.analytics.model.AnalyticsEventConstants.USER_PROFILE_OPENED @@ -278,8 +281,29 @@ interface AnalyticsEvent { } } + data class PersonalTeamCreationFlowStopped( + val isOnTeamNameStep: Boolean?, + val isOnConfirmationStep: Boolean?, + val isOnDisclaimerStep: Boolean?, + ) : AnalyticsEvent { + override val key: String = PERSONAL_TEAM_CREATION_FLOW_STOPPED_EVENT + + override fun toSegmentation(): Map { + val segmentations = mutableMapOf() + isOnTeamNameStep?.let { + segmentations.put(MODAL_TEAM_NAME, it) + } + isOnConfirmationStep?.let { + segmentations.put(MODAL_CONFIRMATION, it) + } + isOnDisclaimerStep?.let { + segmentations.put(MODAL_DISCLAIMERS, it) + } + return segmentations + } + } + data class PersonalTeamCreationFlowCanceled( - val teamName: String?, val modalLeaveClicked: Boolean? = null, val modalContinueClicked: Boolean? = null ) : AnalyticsEvent { @@ -293,15 +317,11 @@ interface AnalyticsEvent { modalContinueClicked?.let { segmentations.put(MODAL_CONTINUE_CLICKED, it) } - teamName?.let { - segmentations.put(MODAL_TEAM_NAME, it) - } return segmentations } } data class PersonalTeamCreationFlowCompleted( - val teamName: String? = null, val modalOpenTeamManagementButtonClicked: Boolean? = null, val backToWireButtonClicked: Boolean? = null ) : AnalyticsEvent { @@ -309,9 +329,6 @@ interface AnalyticsEvent { override fun toSegmentation(): Map { val segmentations = mutableMapOf() - teamName?.let { - segmentations.put(MODAL_TEAM_NAME, it) - } modalOpenTeamManagementButtonClicked?.let { segmentations.put(MODAL_OPEN_TEAM_MANAGEMENT_CLICKED, it) } @@ -393,12 +410,15 @@ object AnalyticsEventConstants { */ const val CLICKED_PERSONAL_MIGRATION_CTA_EVENT = "ui.clicked-personal-migration-cta" const val PERSONAL_TEAM_CREATION_FLOW_STARTED_EVENT = "user.personal-team-creation-flow-started" + const val PERSONAL_TEAM_CREATION_FLOW_STOPPED_EVENT = "personal-team-creation-flow-stopped" const val PERSONAL_TEAM_CREATION_FLOW_CANCELLED = "user.personal-team-creation-flow-cancelled" const val PERSONAL_TEAM_CREATION_FLOW_COMPLETED = "user.personal-team-creation-flow-completed" const val MIGRATION_DOT_ACTIVE = "migration_dot_active" const val CLICKED_CREATE_TEAM = "clicked_create_team" const val CLICKED_DISMISS_CTA = "clicked_dismiss_cta" const val STEP_MODAL_CREATE_TEAM = "step_modalcreateteam" + const val MODAL_DISCLAIMERS = "modal_disclaimers" + const val MODAL_CONFIRMATION = "modal_confirmation" const val MODAL_TEAM_NAME = "modal_team-name" const val MODAL_CONTINUE_CLICKED = "modal_continue-clicked" const val MODAL_LEAVE_CLICKED = "modal_leave-clicked" From 70b6dc84a35c4abf32554ae37dd3460e72b80108 Mon Sep 17 00:00:00 2001 From: ohassine Date: Fri, 13 Dec 2024 17:06:33 +0100 Subject: [PATCH 2/3] chore: detekt --- .../android/ui/userprofile/self/SelfUserProfileViewModelTest.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/test/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileViewModelTest.kt b/app/src/test/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileViewModelTest.kt index cd30c6da341..79d58e2c378 100644 --- a/app/src/test/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileViewModelTest.kt +++ b/app/src/test/kotlin/com/wire/android/ui/userprofile/self/SelfUserProfileViewModelTest.kt @@ -82,6 +82,7 @@ class SelfUserProfileViewModelTest { ) } } + @Test fun `given close modal event, when sendPersonalToTeamMigrationDismissed is called, then send the event`() = runTest { From 34b4c14c197540e601d8b30e41131ae691e2f5f4 Mon Sep 17 00:00:00 2001 From: ohassine Date: Fri, 13 Dec 2024 17:07:11 +0100 Subject: [PATCH 3/3] chore: kalium reference --- kalium | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kalium b/kalium index c9f091b3923..6518915d0ac 160000 --- a/kalium +++ b/kalium @@ -1 +1 @@ -Subproject commit c9f091b392378afa02a1ca0df92d41052b0439a1 +Subproject commit 6518915d0ac5ab78f9e34d7ab676c686e0c14d2f