From 1369d1fa2fd2eef30cecb44e3ac2e968ee7b57f7 Mon Sep 17 00:00:00 2001 From: bmarty Date: Mon, 7 Feb 2022 00:02:21 +0000 Subject: [PATCH 1/5] Sync analytics plan --- .../app/features/analytics/plan/Composer.kt | 53 +++++ .../features/analytics/plan/Interaction.kt | 172 ++++++++++++++++ .../app/features/analytics/plan/JoinedRoom.kt | 33 +++ .../analytics/plan/PerformanceTimer.kt | 6 +- .../app/features/analytics/plan/Screen.kt | 15 ++ .../plan/{Click.kt => SlashCommand.kt} | 22 +- .../plan/{Identity.kt => UserProperties.kt} | 21 +- .../app/features/analytics/plan/ViewRoom.kt | 190 ++++++++++++++++++ 8 files changed, 488 insertions(+), 24 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/analytics/plan/Composer.kt create mode 100644 vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt rename vector/src/main/java/im/vector/app/features/analytics/plan/{Click.kt => SlashCommand.kt} (70%) rename vector/src/main/java/im/vector/app/features/analytics/plan/{Identity.kt => UserProperties.kt} (72%) create mode 100644 vector/src/main/java/im/vector/app/features/analytics/plan/ViewRoom.kt diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/Composer.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/Composer.kt new file mode 100644 index 00000000000..a3b847a1bd3 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/Composer.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.analytics.plan + +import im.vector.app.features.analytics.itf.VectorAnalyticsEvent + +// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT +// https://github.com/matrix-org/matrix-analytics-events/ + +/** + * Triggered when the user sends a message via the composer. + */ +data class Composer( + /** + * Whether the user was using the composer inside of a thread. + */ + val inThread: Boolean, + /** + * Whether the user's composer interaction was editing a previously sent + * event. + */ + val isEditing: Boolean, + /** + * Whether the user's composer interaction was a reply to a previously + * sent event. + */ + val isReply: Boolean, +) : VectorAnalyticsEvent { + + override fun getName() = "Composer" + + override fun getProperties(): Map? { + return mutableMapOf().apply { + put("inThread", inThread) + put("isEditing", isEditing) + put("isReply", isReply) + }.takeIf { it.isNotEmpty() } + } +} diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt new file mode 100644 index 00000000000..3d71b36c51d --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.analytics.plan + +import im.vector.app.features.analytics.itf.VectorAnalyticsEvent + +// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT +// https://github.com/matrix-org/matrix-analytics-events/ + +/** + * Triggered when the user clicks/taps/activates a UI element. + */ +data class Interaction( + /** + * The index of the element, if its in a list of elements. + */ + val index: Int? = null, + /** + * The manner with which the user activated the UI element. + */ + val interactionType: InteractionType? = null, + /** + * The unique name of this element. + */ + val name: Name, +) : VectorAnalyticsEvent { + + enum class Name { + /** + * User tapped the already selected space from the space list. + */ + SpacePanelSelectedSpace, + + /** + * User tapped an unselected space from the space list -> space + * switching should occur. + */ + SpacePanelSwitchSpace, + + /** + * User accessed the room invite flow using the button at the top of the + * room member list in the right panel of Element Web/Desktop. + */ + WebRightPanelMemberListInviteButton, + + /** + * User accessed room member list using the 'People' button in the right + * panel room summary card of Element Web/Desktop. + */ + WebRightPanelRoomInfoPeopleButton, + + /** + * User accessed room settings using the 'Settings' button in the right + * panel room summary card of Element Web/Desktop. + */ + WebRightPanelRoomInfoSettingsButton, + + /** + * User accessed room member list using the back button in the right + * panel user info card of Element Web/Desktop. + */ + WebRightPanelRoomUserInfoBackButton, + + /** + * User invited someone to room by clicking invite on the right panel + * user info card in Element Web/Desktop. + */ + WebRightPanelRoomUserInfoInviteButton, + + /** + * User adjusted their favourites using the context menu on the header + * of a room in Element Web/Desktop. + */ + WebRoomHeaderContextMenuFavouriteToggle, + + /** + * User accessed the room invite flow using the context menu on the + * header of a room in Element Web/Desktop. + */ + WebRoomHeaderContextMenuInviteItem, + + /** + * User interacted with leave action in the context menu on the header + * of a room in Element Web/Desktop. + */ + WebRoomHeaderContextMenuLeaveItem, + + /** + * User accessed their room notification settings via the context menu + * on the header of a room in Element Web/Desktop. + */ + WebRoomHeaderContextMenuNotificationsItem, + + /** + * User accessed room member list using the context menu on the header + * of a room in Element Web/Desktop. + */ + WebRoomHeaderContextMenuPeopleItem, + + /** + * User accessed room settings using the context menu on the header of a + * room in Element Web/Desktop. + */ + WebRoomHeaderContextMenuSettingsItem, + + /** + * User adjusted their favourites using the context menu on a room tile + * in the room list in Element Web/Desktop. + */ + WebRoomListRoomTileContextMenuFavouriteToggle, + + /** + * User accessed the room invite flow using the context menu on a room + * tile in the room list in Element Web/Desktop. + */ + WebRoomListRoomTileContextMenuInviteItem, + + /** + * User interacted with leave action in the context menu on a room tile + * in the room list in Element Web/Desktop. + */ + WebRoomListRoomTileContextMenuLeaveItem, + + /** + * User accessed room settings using the context menu on a room tile in + * the room list in Element Web/Desktop. + */ + WebRoomListRoomTileContextMenuSettingsItem, + + /** + * User accessed their room notification settings via the context menu + * on a room tile in the room list in Element Web/Desktop. + */ + WebRoomListRoomTileNotificationsMenu, + + /** + * User interacted with leave action in the general tab of the room + * settings dialog in Element Web/Desktop. + */ + WebRoomSettingsLeaveButton, + } + + enum class InteractionType { + Keyboard, + Pointer, + Touch, + } + + override fun getName() = "Interaction" + + override fun getProperties(): Map? { + return mutableMapOf().apply { + index?.let { put("index", it) } + interactionType?.let { put("interactionType", it.name) } + put("name", name.name) + }.takeIf { it.isNotEmpty() } + } +} diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/JoinedRoom.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/JoinedRoom.kt index 97ac19ec936..d2fb6832ba6 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/JoinedRoom.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/JoinedRoom.kt @@ -29,15 +29,46 @@ data class JoinedRoom( * Whether the room is a DM. */ val isDM: Boolean, + /** + * Whether the room is a Space. + */ + val isSpace: Boolean, /** * The size of the room. */ val roomSize: RoomSize, + /** + * The trigger for a room being joined if known. + */ + val trigger: Trigger? = null, ) : VectorAnalyticsEvent { + enum class Trigger { + /** + * Room joined via a push/desktop notification. + */ + Notification, + + /** + * Room joined via the public rooms directory. + */ + RoomDirectory, + + /** + * Room joined via the space hierarchy view. + */ + SpaceHierarchy, + + /** + * Room joined via a timeline pill or link in another room. + */ + Timeline, + } + enum class RoomSize { ElevenToOneHundred, MoreThanAThousand, + One, OneHundredAndOneToAThousand, ThreeToTen, Two, @@ -48,7 +79,9 @@ data class JoinedRoom( override fun getProperties(): Map? { return mutableMapOf().apply { put("isDM", isDM) + put("isSpace", isSpace) put("roomSize", roomSize.name) + trigger?.let { put("trigger", it.name) } }.takeIf { it.isNotEmpty() } } } diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/PerformanceTimer.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/PerformanceTimer.kt index 59dd997f92e..2770d668e54 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/PerformanceTimer.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/PerformanceTimer.kt @@ -83,13 +83,15 @@ data class PerformanceTimer( StartupLaunchScreen, /** - * The time to preload data in the MXStore on iOS. + * The time to preload data in the MXStore on iOS. In this case, + * `itemCount` should contain the number of rooms in the store. */ StartupStorePreload, /** * The time to load all data from the store (including - * StartupStorePreload time). + * StartupStorePreload time). In this case, `itemCount` should contain + * the number of rooms loaded into the session */ StartupStoreReady, } diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/Screen.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/Screen.kt index db4dcd0fac7..476c72fa30e 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/Screen.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/Screen.kt @@ -121,6 +121,16 @@ data class Screen( */ MobileSidebar, + /** + * Screen that displays the list of memebrs of a space + */ + MobileSpaceMembers, + + /** + * The bottom sheet that list all space options + */ + MobileSpaceMenu, + /** * The screen shown to select which room directory you'd like to use. */ @@ -206,6 +216,11 @@ data class Screen( */ SettingsSecurity, + /** + * Screen that displays the list of rooms and spaces of a space + */ + SpaceExploreRooms, + /** * The screen shown to create a new direct room. */ diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/Click.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/SlashCommand.kt similarity index 70% rename from vector/src/main/java/im/vector/app/features/analytics/plan/Click.kt rename to vector/src/main/java/im/vector/app/features/analytics/plan/SlashCommand.kt index fbc847165da..69c34bbc158 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/Click.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/SlashCommand.kt @@ -22,29 +22,25 @@ import im.vector.app.features.analytics.itf.VectorAnalyticsEvent // https://github.com/matrix-org/matrix-analytics-events/ /** - * Triggered when the user clicks/taps on a UI element. + * Triggered when the user runs a slash command in their composer. */ -data class Click( +data class SlashCommand( /** - * The index of the element, if its in a list of elements. + * The name of this command. */ - val index: Int? = null, - /** - * The unique name of this element. - */ - val name: Name, + val command: Command, ) : VectorAnalyticsEvent { - enum class Name { - SendMessageButton, + enum class Command { + invite, + part, } - override fun getName() = "Click" + override fun getName() = "SlashCommand" override fun getProperties(): Map? { return mutableMapOf().apply { - index?.let { put("index", it) } - put("name", name.name) + put("command", command.name) }.takeIf { it.isNotEmpty() } } } diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/Identity.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt similarity index 72% rename from vector/src/main/java/im/vector/app/features/analytics/plan/Identity.kt rename to vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt index 99f1fadfc48..453cd0ec9d0 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/Identity.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt @@ -16,20 +16,23 @@ package im.vector.app.features.analytics.plan -import im.vector.app.features.analytics.itf.VectorAnalyticsEvent - // GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT // https://github.com/matrix-org/matrix-analytics-events/ /** - * The user properties to apply when identifying + * The user properties to apply when identifying. This is not an event + * definition. These properties must all be device independent. */ -data class Identity( +data class UserProperties( /** * The selected messaging use case during the onboarding flow. */ val ftueUseCaseSelection: FtueUseCaseSelection? = null, -) : VectorAnalyticsEvent { + /** + * Number of spaces (and sub-spaces) the user is joined to + */ + val numSpaces: Int? = null, +) { enum class FtueUseCaseSelection { /** @@ -53,11 +56,11 @@ data class Identity( WorkMessaging, } - override fun getName() = "Identity" - override fun getProperties(): Map? { - return mutableMapOf().apply { - put("ftueUseCaseSelection", null) + fun getProperties(): Map? { + return mutableMapOf().apply { + ftueUseCaseSelection?.let { put("ftueUseCaseSelection", it.name) } + numSpaces?.let { put("numSpaces", it) } }.takeIf { it.isNotEmpty() } } } diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/ViewRoom.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/ViewRoom.kt new file mode 100644 index 00000000000..50c74a64c18 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/ViewRoom.kt @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.analytics.plan + +import im.vector.app.features.analytics.itf.VectorAnalyticsEvent + +// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT +// https://github.com/matrix-org/matrix-analytics-events/ + +/** + * Triggered when the user changes rooms. + */ +data class ViewRoom( + /** + * The reason for the room change if known. + */ + val trigger: Trigger? = null, + /** + * Whether the interaction was performed via the keyboard input. + */ + val viaKeyboard: Boolean? = null, +) : VectorAnalyticsEvent { + + enum class Trigger { + /** + * Room accessed due to being just created. + */ + Created, + + /** + * Room switched due to user interacting with a message search result. + */ + MessageSearch, + + /** + * Room switched due to user selecting a user to go to a DM with. + */ + MessageUser, + + /** + * Room accessed via a push/desktop notification. + */ + Notification, + + /** + * Room accessed via the predecessor link at the top of the upgraded + * room. + */ + Predecessor, + + /** + * Room accessed via the public rooms directory. + */ + RoomDirectory, + + /** + * Room accessed via the room list. + */ + RoomList, + + /** + * Room accessed via a slash command in Element Web/Desktop like /goto. + */ + SlashCommand, + + /** + * Room accessed via the space hierarchy view. + */ + SpaceHierarchy, + + /** + * Room accessed via a timeline pill or link in another room. + */ + Timeline, + + /** + * Room accessed via a tombstone at the bottom of a predecessor room. + */ + Tombstone, + + /** + * Room switched due to user interacting with incoming verification + * request. + */ + VerificationRequest, + + /** + * Room switched due to accepting a call in a different room in Element + * Web/Desktop. + */ + WebAcceptCall, + + /** + * Room switched due to making a call via the dial pad in Element + * Web/Desktop. + */ + WebDialPad, + + /** + * Room accessed via interacting with the floating call or Jitsi PIP in + * Element Web/Desktop. + */ + WebFloatingCallWindow, + + /** + * Room accessed via the shortcut in Element Web/Desktop's forward + * modal. + */ + WebForwardShortcut, + + /** + * Room accessed via the Element Web/Desktop horizontal breadcrumbs at + * the top of the room list. + */ + WebHorizontalBreadcrumbs, + + /** + * Room accessed via an Element Web/Desktop keyboard shortcut like go to + * next room with unread messages. + */ + WebKeyboardShortcut, + + /** + * Room accessed via Element Web/Desktop's notification panel. + */ + WebNotificationPanel, + + /** + * Room accessed via the predecessor link in Settings > Advanced in + * Element Web/Desktop. + */ + WebPredecessorSettings, + + /** + * Room accessed via clicking on a notifications badge on a room list + * sublist in Element Web/Desktop. + */ + WebRoomListNotificationBadge, + + /** + * Room switched due to the user changing space in Element Web/Desktop. + */ + WebSpaceContextSwitch, + + /** + * Room accessed via clicking on the notifications badge on the + * currently selected space in Element Web/Desktop. + */ + WebSpacePanelNotificationBadge, + + /** + * Room accessed via Element Web/Desktop's Unified Search modal. + */ + WebUnifiedSearch, + + /** + * Room accessed via the Element Web/Desktop vertical breadcrumb hover + * menu. + */ + WebVerticalBreadcrumbs, + + /** + * Room switched due to widget interaction. + */ + Widget, + } + + override fun getName() = "ViewRoom" + + override fun getProperties(): Map? { + return mutableMapOf().apply { + trigger?.let { put("trigger", it.name) } + viaKeyboard?.let { put("viaKeyboard", it) } + }.takeIf { it.isNotEmpty() } + } +} From f78446c1e7996b9de46c03345453fbb5404df4bf Mon Sep 17 00:00:00 2001 From: NIkita Fedrunov Date: Wed, 9 Feb 2022 14:23:45 +0100 Subject: [PATCH 2/5] Click replaced with Compose on message sent Identity replaced with UserProperty added missing param for JoinedRoom --- .../app/features/analytics/AnalyticsTracker.kt | 4 ++-- .../features/analytics/extensions/JoinedRoomExt.kt | 3 +++ .../{IdentityExt.kt => UserPropertiesExt.kt} | 12 ++++++------ .../analytics/impl/DefaultVectorAnalytics.kt | 6 +++--- .../features/home/room/detail/TimelineFragment.kt | 6 ++++-- .../app/features/onboarding/OnboardingViewModel.kt | 6 +++--- .../roompreview/RoomPreviewViewModel.kt | 1 + 7 files changed, 22 insertions(+), 16 deletions(-) rename vector/src/main/java/im/vector/app/features/analytics/extensions/{IdentityExt.kt => UserPropertiesExt.kt} (60%) diff --git a/vector/src/main/java/im/vector/app/features/analytics/AnalyticsTracker.kt b/vector/src/main/java/im/vector/app/features/analytics/AnalyticsTracker.kt index e85919a45f3..2389fbd724b 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/AnalyticsTracker.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/AnalyticsTracker.kt @@ -18,7 +18,7 @@ package im.vector.app.features.analytics import im.vector.app.features.analytics.itf.VectorAnalyticsEvent import im.vector.app.features.analytics.itf.VectorAnalyticsScreen -import im.vector.app.features.analytics.plan.Identity +import im.vector.app.features.analytics.plan.UserProperties interface AnalyticsTracker { /** @@ -34,5 +34,5 @@ interface AnalyticsTracker { /** * Update user specific properties */ - fun updateUserProperties(identity: Identity) + fun updateUserProperties(userProperties: UserProperties) } diff --git a/vector/src/main/java/im/vector/app/features/analytics/extensions/JoinedRoomExt.kt b/vector/src/main/java/im/vector/app/features/analytics/extensions/JoinedRoomExt.kt index ff23fd9a64a..c13f8295f2c 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/extensions/JoinedRoomExt.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/extensions/JoinedRoomExt.kt @@ -19,6 +19,7 @@ package im.vector.app.features.analytics.extensions import im.vector.app.features.analytics.plan.JoinedRoom import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.room.model.RoomSummary +import org.matrix.android.sdk.api.session.room.model.RoomType import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom fun Int?.toAnalyticsRoomSize(): JoinedRoom.RoomSize { @@ -35,6 +36,7 @@ fun Int?.toAnalyticsRoomSize(): JoinedRoom.RoomSize { fun RoomSummary?.toAnalyticsJoinedRoom(): JoinedRoom { return JoinedRoom( isDM = this?.isDirect.orFalse(), + isSpace = this?.roomType == RoomType.SPACE, roomSize = this?.joinedMembersCount?.toAnalyticsRoomSize() ?: JoinedRoom.RoomSize.Two ) } @@ -42,6 +44,7 @@ fun RoomSummary?.toAnalyticsJoinedRoom(): JoinedRoom { fun PublicRoom.toAnalyticsJoinedRoom(): JoinedRoom { return JoinedRoom( isDM = false, + isSpace = false, roomSize = numJoinedMembers.toAnalyticsRoomSize() ) } diff --git a/vector/src/main/java/im/vector/app/features/analytics/extensions/IdentityExt.kt b/vector/src/main/java/im/vector/app/features/analytics/extensions/UserPropertiesExt.kt similarity index 60% rename from vector/src/main/java/im/vector/app/features/analytics/extensions/IdentityExt.kt rename to vector/src/main/java/im/vector/app/features/analytics/extensions/UserPropertiesExt.kt index d87769fd363..7fad43783b5 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/extensions/IdentityExt.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/extensions/UserPropertiesExt.kt @@ -16,14 +16,14 @@ package im.vector.app.features.analytics.extensions -import im.vector.app.features.analytics.plan.Identity +import im.vector.app.features.analytics.plan.UserProperties import im.vector.app.features.onboarding.FtueUseCase -fun FtueUseCase.toTrackingValue(): Identity.FtueUseCaseSelection { +fun FtueUseCase.toTrackingValue(): UserProperties.FtueUseCaseSelection { return when (this) { - FtueUseCase.FRIENDS_FAMILY -> Identity.FtueUseCaseSelection.PersonalMessaging - FtueUseCase.TEAMS -> Identity.FtueUseCaseSelection.WorkMessaging - FtueUseCase.COMMUNITIES -> Identity.FtueUseCaseSelection.CommunityMessaging - FtueUseCase.SKIP -> Identity.FtueUseCaseSelection.Skip + FtueUseCase.FRIENDS_FAMILY -> UserProperties.FtueUseCaseSelection.PersonalMessaging + FtueUseCase.TEAMS -> UserProperties.FtueUseCaseSelection.WorkMessaging + FtueUseCase.COMMUNITIES -> UserProperties.FtueUseCaseSelection.CommunityMessaging + FtueUseCase.SKIP -> UserProperties.FtueUseCaseSelection.Skip } } diff --git a/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt b/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt index 62d360f5f79..83e21ced038 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/impl/DefaultVectorAnalytics.kt @@ -26,7 +26,7 @@ import im.vector.app.features.analytics.VectorAnalytics import im.vector.app.features.analytics.itf.VectorAnalyticsEvent import im.vector.app.features.analytics.itf.VectorAnalyticsScreen import im.vector.app.features.analytics.log.analyticsTag -import im.vector.app.features.analytics.plan.Identity +import im.vector.app.features.analytics.plan.UserProperties import im.vector.app.features.analytics.store.AnalyticsStore import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.flow.Flow @@ -175,8 +175,8 @@ class DefaultVectorAnalytics @Inject constructor( ?.screen(screen.getName(), screen.getProperties()?.toPostHogProperties()) } - override fun updateUserProperties(identity: Identity) { - posthog?.identify(REUSE_EXISTING_ID, identity.getProperties().toPostHogProperties(), IGNORED_OPTIONS) + override fun updateUserProperties(userProperties: UserProperties) { + posthog?.identify(REUSE_EXISTING_ID, userProperties.getProperties().toPostHogProperties(), IGNORED_OPTIONS) } private fun Map?.toPostHogProperties(): Properties? { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index 2da69bbe6cd..c757fd02bac 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -119,7 +119,7 @@ import im.vector.app.core.utils.startInstallFromSourceIntent import im.vector.app.core.utils.toast import im.vector.app.databinding.DialogReportContentBinding import im.vector.app.databinding.FragmentTimelineBinding -import im.vector.app.features.analytics.plan.Click +import im.vector.app.features.analytics.plan.Composer import im.vector.app.features.analytics.plan.Screen import im.vector.app.features.attachments.AttachmentTypeSelectorView import im.vector.app.features.attachments.AttachmentsHelper @@ -1499,7 +1499,9 @@ class TimelineFragment @Inject constructor( return } if (text.isNotBlank()) { - analyticsTracker.capture(Click(name = Click.Name.SendMessageButton)) + withState(messageComposerViewModel) { state -> + analyticsTracker.capture(Composer(isThreadTimeLine(), isEditing = state.sendMode is SendMode.Edit, isReply = state.sendMode is SendMode.Reply)) + } // We collapse ASAP, if not there will be a slight annoying delay views.composerLayout.collapse(true) lockSendButton = true diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index 8097e90206b..0d05a38dfa4 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -39,7 +39,7 @@ import im.vector.app.core.utils.ensureTrailingSlash import im.vector.app.features.VectorFeatures import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.extensions.toTrackingValue -import im.vector.app.features.analytics.plan.Identity +import im.vector.app.features.analytics.plan.UserProperties import im.vector.app.features.login.HomeServerConnectionConfigFactory import im.vector.app.features.login.LoginConfig import im.vector.app.features.login.LoginMode @@ -465,13 +465,13 @@ class OnboardingViewModel @AssistedInject constructor( private fun handleUpdateUseCase(action: OnboardingAction.UpdateUseCase) { setState { copy(useCase = action.useCase) } - analyticsTracker.updateUserProperties(Identity(ftueUseCaseSelection = action.useCase.toTrackingValue())) + analyticsTracker.updateUserProperties(UserProperties(ftueUseCaseSelection = action.useCase.toTrackingValue())) _viewEvents.post(OnboardingViewEvents.OpenServerSelection) } private fun resetUseCase() { setState { copy(useCase = null) } - analyticsTracker.updateUserProperties(Identity(ftueUseCaseSelection = null)) + analyticsTracker.updateUserProperties(UserProperties(ftueUseCaseSelection = null)) } private fun handleUpdateServerType(action: OnboardingAction.UpdateServerType) { diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt index b1fa0e974a3..42bec8c8b30 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewViewModel.kt @@ -251,6 +251,7 @@ class RoomPreviewViewModel @AssistedInject constructor( analyticsTracker.capture(JoinedRoom( // Always false in this case (?) isDM = false, + isSpace = false, roomSize = state.numJoinMembers.toAnalyticsRoomSize() )) // We do not update the joiningRoomsIds here, because, the room is not joined yet regarding the sync data. From e196b010388799f0948c5a5452c6d52f0dcf6c2d Mon Sep 17 00:00:00 2001 From: NIkita Fedrunov Date: Wed, 9 Feb 2022 15:55:22 +0100 Subject: [PATCH 3/5] synced with latest changes in analytics repo --- .../features/analytics/plan/Interaction.kt | 30 +++++ .../app/features/analytics/plan/Screen.kt | 116 ++++++++++++++---- .../features/analytics/plan/UserProperties.kt | 26 +++- 3 files changed, 146 insertions(+), 26 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt index 3d71b36c51d..feffa6d5c69 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt @@ -51,6 +51,18 @@ data class Interaction( */ SpacePanelSwitchSpace, + /** + * User interacted with pin to sidebar checkboxes in the quick settings + * menu of Element Web/Desktop. + */ + WebQuickSettingsPinToSidebarCheckbox, + + /** + * User interacted with the theme dropdown in the quick settings menu of + * Element Web/Desktop. + */ + WebQuickSettingsThemeDropdown, + /** * User accessed the room invite flow using the button at the top of the * room member list in the right panel of Element Web/Desktop. @@ -152,6 +164,24 @@ data class Interaction( * settings dialog in Element Web/Desktop. */ WebRoomSettingsLeaveButton, + + /** + * User interacted with the theme radio selector in the Appearance tab + * of Settings in Element Web/Desktop. + */ + WebSettingsAppearanceTabThemeSelector, + + /** + * User interacted with the pre-built space checkboxes in the Sidebar + * tab of Settings in Element Web/Desktop. + */ + WebSettingsSidebarTabSpacesCheckbox, + + /** + * User clicked the theme toggle button in the user menu of Element + * Web/Desktop. + */ + WebUserMenuThemeToggleButton, } enum class InteractionType { diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/Screen.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/Screen.kt index 476c72fa30e..710ae8f6f26 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/Screen.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/Screen.kt @@ -54,8 +54,8 @@ data class Screen( Group, /** - * The Home tab on iOS | possibly the same on Android? | The Home space - * on Web? + * The Home tab on iOS | possibly the same on Android? | Home page on + * Web */ Home, @@ -116,13 +116,33 @@ data class Screen( */ MobileSearchRooms, + /** + * The global settings screen shown in the app. + */ + MobileSettings, + + /** + * The settings screen to change the default notification options. + */ + MobileSettingsDefaultNotifications, + + /** + * The settings screen to manage notification mentions and keywords. + */ + MobileSettingsMentionsAndKeywords, + + /** + * The global security settings screen. + */ + MobileSettingsSecurity, + /** * The sidebar shown on mobile with spaces, settings etc. */ MobileSidebar, /** - * Screen that displays the list of memebrs of a space + * Screen that displays the list of members of a space */ MobileSpaceMembers, @@ -197,59 +217,105 @@ data class Screen( RoomUploads, /** - * The global settings screen shown in the app. + * Screen that displays the list of rooms and spaces of a space */ - Settings, + SpaceExploreRooms, /** - * The settings screen to change the default notification options. + * The screen shown to create a new direct room. */ - SettingsDefaultNotifications, + StartChat, /** - * The settings screen to manage notification mentions and keywords. + * A screen that shows information about a room member. */ - SettingsMentionsAndKeywords, + User, /** - * The global security settings screen. + * Element Web showing flow to trust this new device with cross-signing. */ - SettingsSecurity, + WebCompleteSecurity, /** - * Screen that displays the list of rooms and spaces of a space + * Element Web showing flow to setup SSSS / cross-signing on this + * account. */ - SpaceExploreRooms, + WebE2ESetup, /** - * The screen shown to create a new direct room. + * Element Web loading spinner. */ - StartChat, + WebLoading, /** - * A screen that shows information about a room member. + * Element Web device has been soft logged out by the server. */ - User, + WebSoftLogout, /** - * ? + * Legacy: Element Web User Settings Flair Tab. */ - WebCompleteSecurity, + WebUserSettingFlair, /** - * ? + * Element Web User Settings Mjolnir (labs) Tab. */ - WebE2ESetup, + WebUserSettingMjolnir, /** - * ? + * Element Web User Settings Appearance Tab. */ - WebLoading, + WebUserSettingsAppearance, /** - * ? + * Element Web User Settings General Tab. */ - WebSoftLogout, + WebUserSettingsGeneral, + + /** + * Element Web User Settings Help & About Tab. + */ + WebUserSettingsHelpAbout, + + /** + * Element Web User Settings Ignored Users Tab. + */ + WebUserSettingsIgnoredUsers, + + /** + * Element Web User Settings Keyboard Tab. + */ + WebUserSettingsKeyboard, + + /** + * Element Web User Settings Labs Tab. + */ + WebUserSettingsLabs, + + /** + * Element Web User Settings Notifications Tab. + */ + WebUserSettingsNotifications, + + /** + * Element Web User Settings Preferences Tab. + */ + WebUserSettingsPreferences, + + /** + * Element Web User Settings Security & Privacy Tab. + */ + WebUserSettingsSecurityPrivacy, + + /** + * Element Web User Settings Sidebar Tab. + */ + WebUserSettingsSidebar, + + /** + * Element Web User Settings Voice & Video Tab. + */ + WebUserSettingsVoiceVideo, /** * The splash screen. diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt index 453cd0ec9d0..bbe2c48fecf 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt @@ -24,6 +24,26 @@ package im.vector.app.features.analytics.plan * definition. These properties must all be device independent. */ data class UserProperties( + /** + * Whether the user has the favourites space enabled + */ + val WebMetaSpaceFavouritesEnabled: Boolean? = null, + /** + * Whether the user has the home space set to all rooms + */ + val WebMetaSpaceHomeAllRooms: Boolean? = null, + /** + * Whether the user has the home space enabled + */ + val WebMetaSpaceHomeEnabled: Boolean? = null, + /** + * Whether the user has the other rooms space enabled + */ + val WebMetaSpaceOrphansEnabled: Boolean? = null, + /** + * Whether the user has the people space enabled + */ + val WebMetaSpacePeopleEnabled: Boolean? = null, /** * The selected messaging use case during the onboarding flow. */ @@ -56,9 +76,13 @@ data class UserProperties( WorkMessaging, } - fun getProperties(): Map? { return mutableMapOf().apply { + WebMetaSpaceFavouritesEnabled?.let { put("WebMetaSpaceFavouritesEnabled", it) } + WebMetaSpaceHomeAllRooms?.let { put("WebMetaSpaceHomeAllRooms", it) } + WebMetaSpaceHomeEnabled?.let { put("WebMetaSpaceHomeEnabled", it) } + WebMetaSpaceOrphansEnabled?.let { put("WebMetaSpaceOrphansEnabled", it) } + WebMetaSpacePeopleEnabled?.let { put("WebMetaSpacePeopleEnabled", it) } ftueUseCaseSelection?.let { put("ftueUseCaseSelection", it.name) } numSpaces?.let { put("numSpaces", it) } }.takeIf { it.isNotEmpty() } From cc4228ed266781477064559b1730a0c810e13db0 Mon Sep 17 00:00:00 2001 From: NIkita Fedrunov Date: Wed, 9 Feb 2022 16:07:47 +0100 Subject: [PATCH 4/5] use new screen name constants --- .../vector/app/features/settings/VectorSettingsRootFragment.kt | 2 +- .../features/settings/VectorSettingsSecurityPrivacyFragment.kt | 2 +- .../VectorSettingsDefaultNotificationPreferenceFragment.kt | 2 +- ...rSettingsKeywordAndMentionsNotificationPreferenceFragment.kt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsRootFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsRootFragment.kt index fb5d83239bd..cd76efac58d 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsRootFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsRootFragment.kt @@ -29,7 +29,7 @@ class VectorSettingsRootFragment @Inject constructor() : VectorSettingsBaseFragm override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - analyticsScreenName = Screen.ScreenName.Settings + analyticsScreenName = Screen.ScreenName.MobileSettings } override fun bindPref() { diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt index 31fce00f3cb..e4e287e83ab 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt @@ -94,7 +94,7 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor( override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - analyticsScreenName = Screen.ScreenName.SettingsSecurity + analyticsScreenName = Screen.ScreenName.MobileSettingsSecurity } // cryptography diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsDefaultNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsDefaultNotificationPreferenceFragment.kt index b6f2098209a..27007744c86 100644 --- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsDefaultNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsDefaultNotificationPreferenceFragment.kt @@ -38,7 +38,7 @@ class VectorSettingsDefaultNotificationPreferenceFragment : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - analyticsScreenName = Screen.ScreenName.SettingsDefaultNotifications + analyticsScreenName = Screen.ScreenName.MobileSettingsDefaultNotifications } override fun bindPref() { diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt index b7cf7f6bbe9..dd3b899fcc9 100644 --- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsKeywordAndMentionsNotificationPreferenceFragment.kt @@ -45,7 +45,7 @@ class VectorSettingsKeywordAndMentionsNotificationPreferenceFragment : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - analyticsScreenName = Screen.ScreenName.SettingsMentionsAndKeywords + analyticsScreenName = Screen.ScreenName.MobileSettingsMentionsAndKeywords } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { From ba5c7a530c283a0add6a542300eb90fcbf7b581f Mon Sep 17 00:00:00 2001 From: NIkita Fedrunov Date: Thu, 10 Feb 2022 13:22:00 +0100 Subject: [PATCH 5/5] another sync with analytics repo --- .../features/analytics/plan/Interaction.kt | 48 +++++++++++++++++++ .../features/analytics/plan/SlashCommand.kt | 4 +- .../features/analytics/plan/UserProperties.kt | 5 ++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt index feffa6d5c69..7bdc7740e1a 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/Interaction.kt @@ -51,6 +51,18 @@ data class Interaction( */ SpacePanelSwitchSpace, + /** + * User clicked the create room button in the + context menu of the room + * list header in Element Web/Desktop. + */ + WebAddExistingToSpaceDialogCreateRoomButton, + + /** + * User clicked the create room button in the home page of Element + * Web/Desktop. + */ + WebHomeCreateRoomButton, + /** * User interacted with pin to sidebar checkboxes in the quick settings * menu of Element Web/Desktop. @@ -93,6 +105,12 @@ data class Interaction( */ WebRightPanelRoomUserInfoInviteButton, + /** + * User clicked the create room button in the room directory of Element + * Web/Desktop. + */ + WebRoomDirectoryCreateRoomButton, + /** * User adjusted their favourites using the context menu on the header * of a room in Element Web/Desktop. @@ -129,6 +147,12 @@ data class Interaction( */ WebRoomHeaderContextMenuSettingsItem, + /** + * User clicked the create room button in the + context menu of the room + * list header in Element Web/Desktop. + */ + WebRoomListHeaderPlusMenuCreateRoomItem, + /** * User adjusted their favourites using the context menu on a room tile * in the room list in Element Web/Desktop. @@ -159,12 +183,24 @@ data class Interaction( */ WebRoomListRoomTileNotificationsMenu, + /** + * User clicked the create room button in the + context menu of the + * rooms sublist in Element Web/Desktop. + */ + WebRoomListRoomsSublistPlusMenuCreateRoomItem, + /** * User interacted with leave action in the general tab of the room * settings dialog in Element Web/Desktop. */ WebRoomSettingsLeaveButton, + /** + * User interacted with the prompt to create a new room when adjusting + * security settings in an existing room in Element Web/Desktop. + */ + WebRoomSettingsSecurityTabCreateNewRoomButton, + /** * User interacted with the theme radio selector in the Appearance tab * of Settings in Element Web/Desktop. @@ -177,6 +213,18 @@ data class Interaction( */ WebSettingsSidebarTabSpacesCheckbox, + /** + * User clicked the create room button in the + context menu of the room + * list header in Element Web/Desktop. + */ + WebSpaceContextMenuNewRoomItem, + + /** + * User clicked the create room button in the + context menu of the room + * list header in Element Web/Desktop. + */ + WebSpaceHomeCreateRoomButton, + /** * User clicked the theme toggle button in the user menu of Element * Web/Desktop. diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/SlashCommand.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/SlashCommand.kt index 69c34bbc158..33d3545487a 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/SlashCommand.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/SlashCommand.kt @@ -32,8 +32,8 @@ data class SlashCommand( ) : VectorAnalyticsEvent { enum class Command { - invite, - part, + Invite, + Part, } override fun getName() = "SlashCommand" diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt index bbe2c48fecf..dea499edded 100644 --- a/vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/UserProperties.kt @@ -48,6 +48,10 @@ data class UserProperties( * The selected messaging use case during the onboarding flow. */ val ftueUseCaseSelection: FtueUseCaseSelection? = null, + /** + * Number of joined rooms the user has favourited + */ + val numFavouriteRooms: Int? = null, /** * Number of spaces (and sub-spaces) the user is joined to */ @@ -84,6 +88,7 @@ data class UserProperties( WebMetaSpaceOrphansEnabled?.let { put("WebMetaSpaceOrphansEnabled", it) } WebMetaSpacePeopleEnabled?.let { put("WebMetaSpacePeopleEnabled", it) } ftueUseCaseSelection?.let { put("ftueUseCaseSelection", it.name) } + numFavouriteRooms?.let { put("numFavouriteRooms", it) } numSpaces?.let { put("numSpaces", it) } }.takeIf { it.isNotEmpty() } }