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 c13f8295f2..27ce3e9a23 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 @@ -33,18 +33,20 @@ fun Int?.toAnalyticsRoomSize(): JoinedRoom.RoomSize { } } -fun RoomSummary?.toAnalyticsJoinedRoom(): JoinedRoom { +fun RoomSummary?.toAnalyticsJoinedRoom(trigger: JoinedRoom.Trigger?): JoinedRoom { return JoinedRoom( isDM = this?.isDirect.orFalse(), isSpace = this?.roomType == RoomType.SPACE, - roomSize = this?.joinedMembersCount?.toAnalyticsRoomSize() ?: JoinedRoom.RoomSize.Two + roomSize = this?.joinedMembersCount?.toAnalyticsRoomSize() ?: JoinedRoom.RoomSize.Two, + trigger = trigger ) } -fun PublicRoom.toAnalyticsJoinedRoom(): JoinedRoom { +fun PublicRoom.toAnalyticsJoinedRoom(trigger: JoinedRoom.Trigger?): JoinedRoom { return JoinedRoom( isDM = false, isSpace = false, - roomSize = numJoinedMembers.toAnalyticsRoomSize() + roomSize = numJoinedMembers.toAnalyticsRoomSize(), + trigger = trigger ) } diff --git a/vector/src/main/java/im/vector/app/features/analytics/extensions/ViewRoomExt.kt b/vector/src/main/java/im/vector/app/features/analytics/extensions/ViewRoomExt.kt new file mode 100644 index 0000000000..ada936a3b5 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/analytics/extensions/ViewRoomExt.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022 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.extensions + +import im.vector.app.RoomGroupingMethod +import im.vector.app.features.analytics.plan.ViewRoom +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 + +fun RoomSummary?.toAnalyticsViewRoom(trigger: ViewRoom.Trigger?, groupingMethod: RoomGroupingMethod? = null, viaKeyboard: Boolean? = null): ViewRoom { + val activeSpace = groupingMethod?.let { + when (it) { + is RoomGroupingMethod.BySpace -> it.spaceSummary?.toActiveSpace() ?: ViewRoom.ActiveSpace.Home + else -> null + } + } + + return ViewRoom( + isDM = this?.isDirect.orFalse(), + isSpace = this?.roomType == RoomType.SPACE, + trigger = trigger, + activeSpace = activeSpace, + viaKeyboard = viaKeyboard + ) +} + +private fun RoomSummary.toActiveSpace(): ViewRoom.ActiveSpace { + return if (isPublic) ViewRoom.ActiveSpace.Public else ViewRoom.ActiveSpace.Private +} diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt index 0053ab0fc6..25fee28123 100644 --- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt @@ -43,6 +43,7 @@ import im.vector.app.core.utils.checkPermissions import im.vector.app.core.utils.onPermissionDeniedSnackbar import im.vector.app.core.utils.registerForPermissionsResult import im.vector.app.features.analytics.plan.MobileScreen +import im.vector.app.features.analytics.plan.ViewRoom import im.vector.app.features.contactsbook.ContactsBookFragment import im.vector.app.features.qrcode.QrCodeScannerEvents import im.vector.app.features.qrcode.QrCodeScannerFragment @@ -206,7 +207,11 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() { } private fun renderCreationSuccess(roomId: String) { - navigator.openRoom(this, roomId) + navigator.openRoom( + context = this, + roomId = roomId, + trigger = ViewRoom.Trigger.MessageUser + ) finish() } diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt index 2e9fe1bcf9..a57159075f 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/IncomingVerificationRequestHandler.kt @@ -18,6 +18,7 @@ package im.vector.app.features.crypto.verification import android.content.Context import im.vector.app.R import im.vector.app.core.platform.VectorBaseActivity +import im.vector.app.features.analytics.plan.ViewRoom import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.detail.RoomDetailActivity @@ -156,7 +157,12 @@ class IncomingVerificationRequestHandler @Inject constructor( if (roomId.isNullOrBlank()) { it.navigator.waitSessionVerification(it) } else { - it.navigator.openRoom(it, roomId, pr.transactionId) + it.navigator.openRoom( + context = it, + roomId = roomId, + eventId = pr.transactionId, + trigger = ViewRoom.Trigger.VerificationRequest + ) } } } diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index d0ae7581be..12ae67fe6e 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -49,8 +49,10 @@ import im.vector.app.features.MainActivity import im.vector.app.features.MainActivityArgs import im.vector.app.features.analytics.accountdata.AnalyticsAccountDataViewModel import im.vector.app.features.analytics.plan.MobileScreen +import im.vector.app.features.analytics.plan.ViewRoom import im.vector.app.features.disclaimer.showDisclaimerDialog import im.vector.app.features.matrixto.MatrixToBottomSheet +import im.vector.app.features.matrixto.OriginOfMatrixTo import im.vector.app.features.navigation.Navigator import im.vector.app.features.notifications.NotificationDrawerManager import im.vector.app.features.permalink.NavigationInterceptor @@ -243,7 +245,7 @@ class HomeActivity : } if (args?.inviteNotificationRoomId != null) { activeSessionHolder.getSafeActiveSession()?.permalinkService()?.createPermalink(args.inviteNotificationRoomId)?.let { - navigator.openMatrixToBottomSheet(this, it) + navigator.openMatrixToBottomSheet(this, it, OriginOfMatrixTo.NOTIFICATION) } } @@ -480,7 +482,7 @@ class HomeActivity : activeSessionHolder.getSafeActiveSession() ?.permalinkService() ?.createPermalink(parcelableExtra.inviteNotificationRoomId)?.let { - navigator.openMatrixToBottomSheet(this, it) + navigator.openMatrixToBottomSheet(this, it, OriginOfMatrixTo.NOTIFICATION) } } handleIntent(intent) @@ -567,14 +569,14 @@ class HomeActivity : override fun navToMemberProfile(userId: String, deepLink: Uri): Boolean { // TODO check if there is already one?? - MatrixToBottomSheet.withLink(deepLink.toString()) + MatrixToBottomSheet.withLink(deepLink.toString(), OriginOfMatrixTo.LINK) .show(supportFragmentManager, "HA#MatrixToBottomSheet") return true } override fun navToRoom(roomId: String?, eventId: String?, deepLink: Uri?, rootThreadEventId: String?): Boolean { if (roomId == null) return false - MatrixToBottomSheet.withLink(deepLink.toString()) + MatrixToBottomSheet.withLink(deepLink.toString(), OriginOfMatrixTo.LINK) .show(supportFragmentManager, "HA#MatrixToBottomSheet") return true } @@ -608,8 +610,8 @@ class HomeActivity : } } - override fun mxToBottomSheetNavigateToRoom(roomId: String) { - navigator.openRoom(this, roomId) + override fun mxToBottomSheetNavigateToRoom(roomId: String, trigger: ViewRoom.Trigger?) { + navigator.openRoom(this, roomId, trigger = trigger) } override fun mxToBottomSheetSwitchToSpace(spaceId: String) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt index 5784e6e264..ac4df411a8 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt @@ -36,6 +36,7 @@ import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityRoomDetailBinding import im.vector.app.features.analytics.plan.MobileScreen +import im.vector.app.features.analytics.plan.ViewRoom import im.vector.app.features.home.room.breadcrumbs.BreadcrumbsFragment import im.vector.app.features.home.room.detail.arguments.TimelineArgs import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker @@ -205,8 +206,8 @@ class RoomDetailActivity : } } - override fun mxToBottomSheetNavigateToRoom(roomId: String) { - navigator.openRoom(this, roomId) + override fun mxToBottomSheetNavigateToRoom(roomId: String, trigger: ViewRoom.Trigger?) { + navigator.openRoom(this, roomId, trigger = trigger) } override fun mxToBottomSheetSwitchToSpace(spaceId: String) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt index 91a4007ca6..9d1e3a358a 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt @@ -40,6 +40,7 @@ import im.vector.app.core.utils.BehaviorDataSource import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.DecryptionFailureTracker import im.vector.app.features.analytics.extensions.toAnalyticsJoinedRoom +import im.vector.app.features.analytics.plan.JoinedRoom import im.vector.app.features.call.conference.ConferenceEvent import im.vector.app.features.call.conference.JitsiActiveConferenceHolder import im.vector.app.features.call.conference.JitsiService @@ -821,13 +822,22 @@ class TimelineViewModel @AssistedInject constructor( viewModelScope.launch { try { session.roomService().joinRoom(room.roomId) - analyticsTracker.capture(room.roomSummary().toAnalyticsJoinedRoom()) + trackRoomJoined() } catch (throwable: Throwable) { _viewEvents.post(RoomDetailViewEvents.Failure(throwable, showInDialog = true)) } } } + private fun trackRoomJoined() { + val trigger = if (initialState.isInviteAlreadyAccepted) { + JoinedRoom.Trigger.Invite + } else { + JoinedRoom.Trigger.Timeline + } + analyticsTracker.capture(room.roomSummary().toAnalyticsJoinedRoom(trigger)) + } + private fun handleOpenOrDownloadFile(action: RoomDetailAction.DownloadOrOpen) { val mxcUrl = action.messageFileContent.getFileUrl() ?: return val isLocalSendingFile = action.senderId == session.myUserId && diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt index a67333e5d5..1f260cf70f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt @@ -28,6 +28,7 @@ import im.vector.app.core.resources.StringProvider import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.extensions.toAnalyticsComposer import im.vector.app.features.analytics.extensions.toAnalyticsJoinedRoom +import im.vector.app.features.analytics.plan.JoinedRoom import im.vector.app.features.attachments.toContentAttachmentData import im.vector.app.features.command.CommandParser import im.vector.app.features.command.ParsedCommand @@ -617,7 +618,7 @@ class MessageComposerViewModel @AssistedInject constructor( return@launch } session.getRoomSummary(command.roomAlias) - ?.also { analyticsTracker.capture(it.toAnalyticsJoinedRoom()) } + ?.also { analyticsTracker.capture(it.toAnalyticsJoinedRoom(JoinedRoom.Trigger.SlashCommand)) } ?.roomId ?.let { _viewEvents.post(MessageComposerViewEvents.JoinRoomCommandSuccess(it)) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchFragment.kt index b3543ae579..c11fa276f6 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchFragment.kt @@ -37,6 +37,7 @@ import im.vector.app.core.extensions.trackItemsVisibilityChange import im.vector.app.core.platform.StateView import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentSearchBinding +import im.vector.app.features.analytics.plan.ViewRoom import im.vector.app.features.home.room.threads.arguments.ThreadTimelineArgs import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.session.events.model.Event @@ -134,7 +135,16 @@ class SearchFragment @Inject constructor( roomEncryptionTrustLevel = null, rootThreadEventId = it) navigator.openThread(requireContext(), threadTimelineArgs, event.eventId) - } ?: navigator.openRoom(requireContext(), roomId, event.eventId) + } ?: openRoom(roomId, event.eventId) + } + + private fun openRoom(roomId: String, eventId: String?) { + navigator.openRoom( + context = requireContext(), + roomId = roomId, + eventId = eventId, + trigger = ViewRoom.Trigger.MessageSearch + ) } override fun loadMore() { diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt index aaa469f68d..426ceb5024 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt @@ -44,12 +44,14 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.resources.UserPreferencesProvider import im.vector.app.databinding.FragmentRoomListBinding import im.vector.app.features.analytics.plan.MobileScreen +import im.vector.app.features.analytics.plan.ViewRoom import im.vector.app.features.home.RoomListDisplayMode import im.vector.app.features.home.room.filtered.FilteredRoomFooterItem import im.vector.app.features.home.room.list.actions.RoomListQuickActionsBottomSheet import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedAction import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel import im.vector.app.features.home.room.list.widget.NotifsFabMenuView +import im.vector.app.features.matrixto.OriginOfMatrixTo import im.vector.app.features.notifications.NotificationDrawerManager import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.launchIn @@ -179,7 +181,7 @@ class RoomListFragment @Inject constructor( } private fun handleShowMxToLink(link: String) { - navigator.openMatrixToBottomSheet(requireContext(), link) + navigator.openMatrixToBottomSheet(requireContext(), link, OriginOfMatrixTo.ROOM_LIST) } override fun onDestroyView() { @@ -196,7 +198,12 @@ class RoomListFragment @Inject constructor( } private fun handleSelectRoom(event: RoomListViewEvents.SelectRoom, isInviteAlreadyAccepted: Boolean) { - navigator.openRoom(context = requireActivity(), roomId = event.roomSummary.roomId, isInviteAlreadyAccepted = isInviteAlreadyAccepted) + navigator.openRoom( + context = requireActivity(), + roomId = event.roomSummary.roomId, + isInviteAlreadyAccepted = isInviteAlreadyAccepted, + trigger = ViewRoom.Trigger.RoomList + ) } private fun setupCreateRoomButton() { diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt index 9fb13084d1..b97bcc2dff 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt @@ -32,6 +32,8 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider import im.vector.app.features.analytics.AnalyticsTracker +import im.vector.app.features.analytics.extensions.toAnalyticsJoinedRoom +import im.vector.app.features.analytics.plan.JoinedRoom import im.vector.app.features.displayname.getBestName import im.vector.app.features.invite.AutoAcceptInvites import im.vector.app.features.settings.VectorPreferences @@ -43,6 +45,7 @@ import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.getRoom +import org.matrix.android.sdk.api.session.getRoomSummary import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.tag.RoomTag @@ -276,6 +279,8 @@ class RoomListViewModel @AssistedInject constructor( this[action.roomId] = Fail(failure) }.toMap()) } + session.getRoomSummary(action.roomId) + ?.let { analyticsTracker.capture(it.toAnalyticsJoinedRoom(JoinedRoom.Trigger.RoomDirectory)) } } } diff --git a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt index 61dcd48779..57e48cac6d 100644 --- a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt @@ -32,6 +32,7 @@ import im.vector.app.R import im.vector.app.core.extensions.commitTransaction import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.databinding.BottomSheetMatrixToCardBinding +import im.vector.app.features.analytics.plan.ViewRoom import im.vector.app.features.home.AvatarRenderer import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.session.permalinks.PermalinkData @@ -44,7 +45,8 @@ class MatrixToBottomSheet : @Parcelize data class MatrixToArgs( - val matrixToLink: String + val matrixToLink: String, + val origin: OriginOfMatrixTo ) : Parcelable @Inject lateinit var avatarRenderer: AvatarRenderer @@ -58,7 +60,7 @@ class MatrixToBottomSheet : private val viewModel by fragmentViewModel(MatrixToBottomSheetViewModel::class) interface InteractionListener { - fun mxToBottomSheetNavigateToRoom(roomId: String) + fun mxToBottomSheetNavigateToRoom(roomId: String, trigger: ViewRoom.Trigger?) fun mxToBottomSheetSwitchToSpace(spaceId: String) } @@ -97,7 +99,9 @@ class MatrixToBottomSheet : viewModel.observeViewEvents { when (it) { is MatrixToViewEvents.NavigateToRoom -> { - interactionListener?.mxToBottomSheetNavigateToRoom(it.roomId) + withState(viewModel) { state -> + interactionListener?.mxToBottomSheetNavigateToRoom(it.roomId, state.origin.toViewRoomTrigger()) + } dismiss() } MatrixToViewEvents.Dismiss -> dismiss() @@ -116,9 +120,9 @@ class MatrixToBottomSheet : } companion object { - fun withLink(matrixToLink: String): MatrixToBottomSheet { + fun withLink(matrixToLink: String, origin: OriginOfMatrixTo): MatrixToBottomSheet { return MatrixToBottomSheet().apply { - setArguments(MatrixToArgs(matrixToLink = matrixToLink)) + setArguments(MatrixToArgs(matrixToLink = matrixToLink, origin = origin)) } } } diff --git a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetState.kt b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetState.kt index 0fff2495f9..a6eb2a9afc 100644 --- a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetState.kt +++ b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetState.kt @@ -30,12 +30,14 @@ data class MatrixToBottomSheetState( val matrixItem: Async = Uninitialized, val startChattingState: Async = Uninitialized, val roomPeekResult: Async = Uninitialized, - val peopleYouKnow: Async> = Uninitialized + val peopleYouKnow: Async> = Uninitialized, + val origin: OriginOfMatrixTo ) : MavericksState { constructor(args: MatrixToBottomSheet.MatrixToArgs) : this( deepLink = args.matrixToLink, - linkType = PermalinkParser.parse(args.matrixToLink) + linkType = PermalinkParser.parse(args.matrixToLink), + origin = args.origin ) } diff --git a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt index b6db5f487d..18070c8e6c 100644 --- a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt @@ -30,6 +30,8 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.resources.StringProvider +import im.vector.app.features.analytics.AnalyticsTracker +import im.vector.app.features.analytics.extensions.toAnalyticsJoinedRoom import im.vector.app.features.createdirect.DirectRoomHelper import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -37,6 +39,7 @@ import org.matrix.android.sdk.api.MatrixPatterns import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.getRoom +import org.matrix.android.sdk.api.session.getRoomSummary import org.matrix.android.sdk.api.session.permalinks.PermalinkData import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.peeking.PeekResult @@ -50,7 +53,8 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor( private val session: Session, private val stringProvider: StringProvider, private val directRoomHelper: DirectRoomHelper, - private val errorFormatter: ErrorFormatter + private val errorFormatter: ErrorFormatter, + private val analyticsTracker: AnalyticsTracker ) : VectorViewModel(initialState) { @AssistedFactory @@ -275,6 +279,11 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor( viewModelScope.launch { try { val joinResult = session.spaceService().joinSpace(joinSpace.spaceID, null, joinSpace.viaServers?.take(3) ?: emptyList()) + withState { state -> + session.getRoomSummary(joinSpace.spaceID)?.let { summary -> + analyticsTracker.capture(summary.toAnalyticsJoinedRoom(state.origin.toJoinedRoomTrigger())) + } + } if (joinResult.isSuccess()) { _viewEvents.post(MatrixToViewEvents.NavigateToSpace(joinSpace.spaceID)) } else { @@ -303,7 +312,14 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor( reason = null, viaServers = action.viaServers?.take(3) ?: emptyList() ) - _viewEvents.post(MatrixToViewEvents.NavigateToRoom(getRoomIdFromRoomIdOrAlias(action.roomIdOrAlias))) + + val roomId = getRoomIdFromRoomIdOrAlias(action.roomIdOrAlias) + withState { state -> + session.getRoomSummary(roomId)?.let { summary -> + analyticsTracker.capture(summary.toAnalyticsJoinedRoom(state.origin.toJoinedRoomTrigger())) + } + } + _viewEvents.post(MatrixToViewEvents.NavigateToRoom(roomId)) } catch (failure: Throwable) { _viewEvents.post(MatrixToViewEvents.ShowModalError(errorFormatter.toHumanReadable(failure))) } finally { diff --git a/vector/src/main/java/im/vector/app/features/matrixto/OriginOfMatrixTo.kt b/vector/src/main/java/im/vector/app/features/matrixto/OriginOfMatrixTo.kt new file mode 100644 index 0000000000..297c8e7723 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/matrixto/OriginOfMatrixTo.kt @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022 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.matrixto + +import im.vector.app.features.analytics.plan.JoinedRoom +import im.vector.app.features.analytics.plan.ViewRoom + +enum class OriginOfMatrixTo { + LINK, + NOTIFICATION, + TIMELINE, + SPACE_EXPLORE, + ROOM_LIST, + USER_CODE +} + +fun OriginOfMatrixTo.toJoinedRoomTrigger(): JoinedRoom.Trigger? { + return when (this) { + OriginOfMatrixTo.LINK -> JoinedRoom.Trigger.MobilePermalink + OriginOfMatrixTo.NOTIFICATION -> JoinedRoom.Trigger.Notification + OriginOfMatrixTo.TIMELINE -> JoinedRoom.Trigger.Timeline + OriginOfMatrixTo.SPACE_EXPLORE -> JoinedRoom.Trigger.SpaceHierarchy + OriginOfMatrixTo.ROOM_LIST -> JoinedRoom.Trigger.RoomDirectory + OriginOfMatrixTo.USER_CODE -> null + } +} + +fun OriginOfMatrixTo.toViewRoomTrigger(): ViewRoom.Trigger? { + return when (this) { + OriginOfMatrixTo.LINK -> ViewRoom.Trigger.MobilePermalink + OriginOfMatrixTo.NOTIFICATION -> ViewRoom.Trigger.Notification + OriginOfMatrixTo.TIMELINE -> ViewRoom.Trigger.Timeline + OriginOfMatrixTo.SPACE_EXPLORE -> ViewRoom.Trigger.SpaceHierarchy + OriginOfMatrixTo.ROOM_LIST -> ViewRoom.Trigger.RoomDirectory + OriginOfMatrixTo.USER_CODE -> null + } +} diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt index 076b7be3ad..94aee1ba1a 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt @@ -39,6 +39,9 @@ import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.utils.toast import im.vector.app.features.VectorFeatures import im.vector.app.features.VectorFeatures.OnboardingVariant +import im.vector.app.features.analytics.AnalyticsTracker +import im.vector.app.features.analytics.extensions.toAnalyticsViewRoom +import im.vector.app.features.analytics.plan.ViewRoom import im.vector.app.features.analytics.ui.consent.AnalyticsOptInActivity import im.vector.app.features.call.conference.JitsiCallViewModel import im.vector.app.features.call.conference.VectorJitsiActivity @@ -68,6 +71,7 @@ import im.vector.app.features.location.LocationSharingMode import im.vector.app.features.login.LoginActivity import im.vector.app.features.login.LoginConfig import im.vector.app.features.matrixto.MatrixToBottomSheet +import im.vector.app.features.matrixto.OriginOfMatrixTo import im.vector.app.features.media.AttachmentData import im.vector.app.features.media.BigImageViewerActivity import im.vector.app.features.media.VectorAttachmentViewerActivity @@ -118,7 +122,8 @@ class DefaultNavigator @Inject constructor( private val widgetArgsBuilder: WidgetArgsBuilder, private val appStateHandler: AppStateHandler, private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider, - private val features: VectorFeatures + private val features: VectorFeatures, + private val analyticsTracker: AnalyticsTracker ) : Navigator { override fun openLogin(context: Context, loginConfig: LoginConfig?, flags: Int) { @@ -150,12 +155,23 @@ class DefaultNavigator @Inject constructor( roomId: String, eventId: String?, buildTask: Boolean, - isInviteAlreadyAccepted: Boolean + isInviteAlreadyAccepted: Boolean, + trigger: ViewRoom.Trigger? ) { if (sessionHolder.getSafeActiveSession()?.getRoom(roomId) == null) { fatalError("Trying to open an unknown room $roomId", vectorPreferences.failFast()) return } + + trigger?.let { + analyticsTracker.capture( + sessionHolder.getActiveSession().getRoomSummary(roomId).toAnalyticsViewRoom( + trigger = trigger, + groupingMethod = appStateHandler.getCurrentRoomGroupingMethod() + ) + ) + } + val args = TimelineArgs(roomId = roomId, eventId = eventId, isInviteAlreadyAccepted = isInviteAlreadyAccepted) val intent = RoomDetailActivity.newIntent(context, args) startActivity(context, intent, buildTask) @@ -296,13 +312,13 @@ class DefaultNavigator @Inject constructor( context.startActivity(intent) } - override fun openMatrixToBottomSheet(context: Context, link: String) { + override fun openMatrixToBottomSheet(context: Context, link: String, origin: OriginOfMatrixTo) { if (context is AppCompatActivity) { if (context !is MatrixToBottomSheet.InteractionListener) { fatalError("Caller context should implement MatrixToBottomSheet.InteractionListener", vectorPreferences.failFast()) } // TODO check if there is already one?? - MatrixToBottomSheet.withLink(link) + MatrixToBottomSheet.withLink(link, origin) .show(context.supportFragmentManager, "HA#MatrixToBottomSheet") } } diff --git a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt index 41b5374168..075b41daf3 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt @@ -23,12 +23,14 @@ import android.net.Uri import android.view.View import androidx.activity.result.ActivityResultLauncher import androidx.core.util.Pair +import im.vector.app.features.analytics.plan.ViewRoom import im.vector.app.features.crypto.recover.SetupMode import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.room.threads.arguments.ThreadTimelineArgs import im.vector.app.features.location.LocationData import im.vector.app.features.location.LocationSharingMode import im.vector.app.features.login.LoginConfig +import im.vector.app.features.matrixto.OriginOfMatrixTo import im.vector.app.features.media.AttachmentData import im.vector.app.features.pin.PinMode import im.vector.app.features.poll.PollMode @@ -50,7 +52,12 @@ interface Navigator { fun softLogout(context: Context) - fun openRoom(context: Context, roomId: String, eventId: String? = null, buildTask: Boolean = false, isInviteAlreadyAccepted: Boolean = false) + fun openRoom(context: Context, + roomId: String, + eventId: String? = null, + buildTask: Boolean = false, + isInviteAlreadyAccepted: Boolean = false, + trigger: ViewRoom.Trigger? = null) sealed class PostSwitchSpaceAction { object None : PostSwitchSpaceAction() @@ -79,7 +86,7 @@ interface Navigator { fun openRoomPreview(context: Context, roomPreviewData: RoomPreviewData, fromEmailInviteLink: PermalinkData.RoomEmailInviteLink? = null) - fun openMatrixToBottomSheet(context: Context, link: String) + fun openMatrixToBottomSheet(context: Context, link: String, origin: OriginOfMatrixTo) fun openCreateRoom(context: Context, initialName: String = "", openAfterCreate: Boolean = true) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt index 3d5bd7930c..f88f7927d8 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationBroadcastReceiver.kt @@ -25,6 +25,7 @@ import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.extensions.toAnalyticsJoinedRoom +import im.vector.app.features.analytics.plan.JoinedRoom import im.vector.app.features.session.coroutineScope import kotlinx.coroutines.launch import org.matrix.android.sdk.api.extensions.tryOrNull @@ -85,7 +86,7 @@ class NotificationBroadcastReceiver : BroadcastReceiver() { session.coroutineScope.launch { tryOrNull { session.roomService().joinRoom(room.roomId) - analyticsTracker.capture(room.roomSummary().toAnalyticsJoinedRoom()) + analyticsTracker.capture(room.roomSummary().toAnalyticsJoinedRoom(JoinedRoom.Trigger.Notification)) } } } diff --git a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt index cc2d712bb2..5ee1b54153 100644 --- a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt +++ b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt @@ -25,6 +25,7 @@ import im.vector.app.core.extensions.isIgnored import im.vector.app.core.resources.UserPreferencesProvider import im.vector.app.core.utils.toast import im.vector.app.features.home.room.threads.arguments.ThreadTimelineArgs +import im.vector.app.features.matrixto.OriginOfMatrixTo import im.vector.app.features.navigation.Navigator import im.vector.app.features.roomdirectory.roompreview.RoomPreviewData import kotlinx.coroutines.Dispatchers @@ -192,12 +193,12 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti navigationInterceptor.openJoinedRoomScreen(buildTask, roomId, eventId, rawLink, context, rootThreadEventId, roomSummary) } else { // maybe open space preview navigator.openSpacePreview(context, roomId)? if already joined? - navigator.openMatrixToBottomSheet(context, rawLink.toString()) + navigator.openMatrixToBottomSheet(context, rawLink.toString(), OriginOfMatrixTo.LINK) } } else -> { // XXX this could trigger another server load - navigator.openMatrixToBottomSheet(context, rawLink.toString()) + navigator.openMatrixToBottomSheet(context, rawLink.toString(), OriginOfMatrixTo.LINK) } } } diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt index b8bba347fd..4802e36c42 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt @@ -33,6 +33,7 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.platform.showOptimizedSnackbar import im.vector.app.core.utils.toast import im.vector.app.databinding.FragmentPublicRoomsBinding +import im.vector.app.features.analytics.plan.ViewRoom import im.vector.app.features.permalink.NavigationInterceptor import im.vector.app.features.permalink.PermalinkHandler import kotlinx.coroutines.flow.debounce @@ -143,7 +144,11 @@ class PublicRoomsFragment @Inject constructor( withState(viewModel) { state -> when (joinState) { JoinState.JOINED -> { - navigator.openRoom(requireActivity(), publicRoom.roomId) + navigator.openRoom( + context = requireActivity(), + roomId = publicRoom.roomId, + trigger = ViewRoom.Trigger.RoomDirectory + ) } else -> { // ROOM PREVIEW diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt index f0df31342e..afee8e2638 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt @@ -29,6 +29,7 @@ import im.vector.app.core.extensions.popBackstack import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivitySimpleBinding import im.vector.app.features.analytics.plan.MobileScreen +import im.vector.app.features.analytics.plan.ViewRoom import im.vector.app.features.matrixto.MatrixToBottomSheet import im.vector.app.features.navigation.Navigator import im.vector.app.features.roomdirectory.createroom.CreateRoomArgs @@ -88,8 +89,8 @@ class RoomDirectoryActivity : VectorBaseActivity(), Matri } } - override fun mxToBottomSheetNavigateToRoom(roomId: String) { - navigator.openRoom(this, roomId) + override fun mxToBottomSheetNavigateToRoom(roomId: String, trigger: ViewRoom.Trigger?) { + navigator.openRoom(this, roomId, trigger = trigger) } override fun mxToBottomSheetSwitchToSpace(spaceId: String) { diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryViewModel.kt index 2cebc96dac..e8540a6974 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryViewModel.kt @@ -29,6 +29,7 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.extensions.toAnalyticsJoinedRoom +import im.vector.app.features.analytics.plan.JoinedRoom import im.vector.app.features.settings.VectorPreferences import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Job @@ -226,7 +227,7 @@ class RoomDirectoryViewModel @AssistedInject constructor( viewModelScope.launch { try { session.roomService().joinRoom(action.publicRoom.roomId, viaServers = viaServers) - analyticsTracker.capture(action.publicRoom.toAnalyticsJoinedRoom()) + analyticsTracker.capture(action.publicRoom.toAnalyticsJoinedRoom(JoinedRoom.Trigger.RoomDirectory)) // We do not update the joiningRoomsIds here, because, the room is not joined yet regarding the sync data. // Instead, we wait for the room to be joined } catch (failure: Throwable) { diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt index 2871513c1f..891b1f6e89 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt @@ -38,6 +38,7 @@ import im.vector.app.core.platform.OnBackPressed import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.resources.ColorProvider import im.vector.app.databinding.FragmentCreateRoomBinding +import im.vector.app.features.analytics.plan.ViewRoom import im.vector.app.features.navigation.Navigator import im.vector.app.features.roomdirectory.RoomDirectorySharedAction import im.vector.app.features.roomdirectory.RoomDirectorySharedActionViewModel @@ -219,20 +220,25 @@ class CreateRoomFragment @Inject constructor( val async = state.asyncCreateRoomRequest views.waitingView.root.isVisible = async is Loading if (async is Success) { + val roomId = async() // Navigate to freshly created room if (state.openAfterCreate) { if (state.isSubSpace) { navigator.switchToSpace( requireContext(), - async(), + roomId, Navigator.PostSwitchSpaceAction.None ) } else { - navigator.openRoom(requireActivity(), async()) + navigator.openRoom( + context = requireActivity(), + roomId = roomId, + trigger = ViewRoom.Trigger.Created + ) } } - sharedActionViewModel.post(RoomDirectorySharedAction.CreateRoomSuccess(async())) + sharedActionViewModel.post(RoomDirectorySharedAction.CreateRoomSuccess(roomId)) sharedActionViewModel.post(RoomDirectorySharedAction.Close) } else { // Populate list with Epoxy diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt index baa6d0add1..6eed1cae36 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt @@ -38,6 +38,7 @@ import im.vector.app.core.utils.styleMatchingText import im.vector.app.core.utils.tappableMatchingText import im.vector.app.databinding.FragmentRoomPreviewNoPreviewBinding import im.vector.app.features.analytics.plan.MobileScreen +import im.vector.app.features.analytics.plan.ViewRoom import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.navigation.Navigator import im.vector.app.features.roomdirectory.JoinState @@ -100,7 +101,13 @@ class RoomPreviewNoPreviewFragment @Inject constructor( if (state.roomType == RoomType.SPACE) { navigator.switchToSpace(requireActivity(), state.roomId, Navigator.PostSwitchSpaceAction.None) } else { - navigator.openRoom(requireActivity(), state.roomId, roomPreviewData.eventId, roomPreviewData.buildTask) + navigator.openRoom( + context = requireActivity(), + roomId = state.roomId, + eventId = roomPreviewData.eventId, + buildTask = roomPreviewData.buildTask, + trigger = ViewRoom.Trigger.MobileRoomPreview + ) } } 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 88bfc32de9..e58feef5b3 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 @@ -27,7 +27,7 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel import im.vector.app.features.analytics.AnalyticsTracker -import im.vector.app.features.analytics.extensions.toAnalyticsRoomSize +import im.vector.app.features.analytics.extensions.toAnalyticsJoinedRoom import im.vector.app.features.analytics.plan.JoinedRoom import im.vector.app.features.roomdirectory.JoinState import kotlinx.coroutines.Dispatchers @@ -37,6 +37,7 @@ import kotlinx.coroutines.launch import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.getRoomSummary import org.matrix.android.sdk.api.session.identity.SharedState import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState @@ -248,17 +249,13 @@ class RoomPreviewViewModel @AssistedInject constructor( viewModelScope.launch { try { session.roomService().joinRoom(state.roomId, viaServers = state.homeServers) - 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. // Instead, we wait for the room to be joined } catch (failure: Throwable) { setState { copy(lastError = failure) } } + session.getRoomSummary(state.roomId) + ?.let { analyticsTracker.capture(it.toAnalyticsJoinedRoom(JoinedRoom.Trigger.RoomPreview)) } } } } diff --git a/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt b/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt index 199536b62b..a6f05c8191 100644 --- a/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt +++ b/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt @@ -37,6 +37,7 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.registerStartForActivityResult import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentIncomingShareBinding +import im.vector.app.features.analytics.plan.ViewRoom import im.vector.app.features.attachments.AttachmentsHelper import im.vector.app.features.attachments.preview.AttachmentsPreviewActivity import im.vector.app.features.attachments.preview.AttachmentsPreviewArgs @@ -125,7 +126,11 @@ class IncomingShareFragment @Inject constructor( private fun handleMultipleRoomsShareDone(viewEvent: IncomingShareViewEvents.MultipleRoomsShareDone) { requireActivity().let { - navigator.openRoom(it, viewEvent.roomId) + navigator.openRoom( + context = it, + roomId = viewEvent.roomId, + trigger = ViewRoom.Trigger.MobileLinkShare + ) it.finish() } } diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceExploreActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceExploreActivity.kt index f4610805bc..680124e091 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceExploreActivity.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceExploreActivity.kt @@ -30,7 +30,9 @@ import im.vector.app.core.extensions.registerStartForActivityResult import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivitySimpleBinding +import im.vector.app.features.analytics.plan.ViewRoom import im.vector.app.features.matrixto.MatrixToBottomSheet +import im.vector.app.features.matrixto.OriginOfMatrixTo import im.vector.app.features.navigation.Navigator import im.vector.app.features.roomdirectory.createroom.CreateRoomActivity import im.vector.app.features.spaces.explore.SpaceDirectoryArgs @@ -92,10 +94,14 @@ class SpaceExploreActivity : VectorBaseActivity(), Matrix finish() } is SpaceDirectoryViewEvents.NavigateToRoom -> { - navigator.openRoom(this, it.roomId) + navigator.openRoom( + context = this, + roomId = it.roomId, + trigger = ViewRoom.Trigger.SpaceHierarchy + ) } is SpaceDirectoryViewEvents.NavigateToMxToBottomSheet -> { - MatrixToBottomSheet.withLink(it.link).show(supportFragmentManager, "ShowChild") + MatrixToBottomSheet.withLink(it.link, OriginOfMatrixTo.SPACE_EXPLORE).show(supportFragmentManager, "ShowChild") } is SpaceDirectoryViewEvents.NavigateToCreateNewRoom -> { createRoomResultLauncher.launch(CreateRoomActivity.getIntent( @@ -121,8 +127,8 @@ class SpaceExploreActivity : VectorBaseActivity(), Matrix } } - override fun mxToBottomSheetNavigateToRoom(roomId: String) { - navigator.openRoom(this, roomId) + override fun mxToBottomSheetNavigateToRoom(roomId: String, trigger: ViewRoom.Trigger?) { + navigator.openRoom(this, roomId, trigger = trigger) } override fun mxToBottomSheetSwitchToSpace(spaceId: String) { diff --git a/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt index fe43ad7997..5993dd2c81 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryViewModel.kt @@ -27,6 +27,9 @@ import dagger.assisted.AssistedInject import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel +import im.vector.app.features.analytics.AnalyticsTracker +import im.vector.app.features.analytics.extensions.toAnalyticsJoinedRoom +import im.vector.app.features.analytics.plan.JoinedRoom import im.vector.app.features.powerlevel.PowerLevelsFlowFactory import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.launchIn @@ -49,7 +52,8 @@ import timber.log.Timber class SpaceDirectoryViewModel @AssistedInject constructor( @Assisted val initialState: SpaceDirectoryState, - private val session: Session + private val session: Session, + private val analyticsTracker: AnalyticsTracker ) : VectorViewModel(initialState) { @AssistedFactory @@ -416,6 +420,9 @@ class SpaceDirectoryViewModel @AssistedInject constructor( } catch (failure: Throwable) { Timber.e(failure, "## Space: Failed to join room or subspace") } + + session.getRoomSummary(childId) + ?.let { analyticsTracker.capture(it.toAnalyticsJoinedRoom(JoinedRoom.Trigger.SpaceHierarchy)) } } } } diff --git a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleActivity.kt index 23a76b4b68..09a0099fb7 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleActivity.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleActivity.kt @@ -30,6 +30,7 @@ import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.GenericIdArgs import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivitySimpleLoadingBinding +import im.vector.app.features.analytics.plan.ViewRoom import im.vector.app.features.spaces.share.ShareSpaceBottomSheet import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -90,7 +91,11 @@ class SpacePeopleActivity : VectorBaseActivity() { } private fun navigateToRooms(action: SpacePeopleSharedAction.NavigateToRoom) { - navigator.openRoom(this, action.roomId) + navigator.openRoom( + context = this, + roomId = action.roomId, + trigger = ViewRoom.Trigger.MobileSpaceMembers + ) finish() } diff --git a/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt b/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt index 9e0aa15297..aab83b48a0 100644 --- a/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt @@ -34,7 +34,9 @@ import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.utils.onPermissionDeniedSnackbar import im.vector.app.databinding.ActivitySimpleBinding +import im.vector.app.features.analytics.plan.ViewRoom import im.vector.app.features.matrixto.MatrixToBottomSheet +import im.vector.app.features.matrixto.OriginOfMatrixTo import im.vector.app.features.qrcode.QrCodeScannerEvents import im.vector.app.features.qrcode.QrCodeScannerFragment import im.vector.app.features.qrcode.QrCodeScannerViewModel @@ -92,7 +94,7 @@ class UserCodeActivity : VectorBaseActivity(), } is UserCodeState.Mode.RESULT -> { showFragment(ShowUserCodeFragment::class) - MatrixToBottomSheet.withLink(mode.rawLink).show(supportFragmentManager, "MatrixToBottomSheet") + MatrixToBottomSheet.withLink(mode.rawLink, OriginOfMatrixTo.USER_CODE).show(supportFragmentManager, "MatrixToBottomSheet") } } } @@ -141,8 +143,8 @@ class UserCodeActivity : VectorBaseActivity(), } } - override fun mxToBottomSheetNavigateToRoom(roomId: String) { - navigator.openRoom(this, roomId) + override fun mxToBottomSheetNavigateToRoom(roomId: String, trigger: ViewRoom.Trigger?) { + navigator.openRoom(this, roomId, trigger = trigger) } override fun mxToBottomSheetSwitchToSpace(spaceId: String) {}