track room open and room join analytics events (#5696)

This commit is contained in:
fedrunov 2022-05-03 16:11:40 +02:00 committed by GitHub
parent 8dd87321da
commit 9f520d4e8a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 295 additions and 62 deletions

View file

@ -33,18 +33,20 @@ fun Int?.toAnalyticsRoomSize(): JoinedRoom.RoomSize {
} }
} }
fun RoomSummary?.toAnalyticsJoinedRoom(): JoinedRoom { fun RoomSummary?.toAnalyticsJoinedRoom(trigger: JoinedRoom.Trigger?): JoinedRoom {
return JoinedRoom( return JoinedRoom(
isDM = this?.isDirect.orFalse(), isDM = this?.isDirect.orFalse(),
isSpace = this?.roomType == RoomType.SPACE, 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( return JoinedRoom(
isDM = false, isDM = false,
isSpace = false, isSpace = false,
roomSize = numJoinedMembers.toAnalyticsRoomSize() roomSize = numJoinedMembers.toAnalyticsRoomSize(),
trigger = trigger
) )
} }

View file

@ -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
}

View file

@ -43,6 +43,7 @@ import im.vector.app.core.utils.checkPermissions
import im.vector.app.core.utils.onPermissionDeniedSnackbar import im.vector.app.core.utils.onPermissionDeniedSnackbar
import im.vector.app.core.utils.registerForPermissionsResult import im.vector.app.core.utils.registerForPermissionsResult
import im.vector.app.features.analytics.plan.MobileScreen 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.contactsbook.ContactsBookFragment
import im.vector.app.features.qrcode.QrCodeScannerEvents import im.vector.app.features.qrcode.QrCodeScannerEvents
import im.vector.app.features.qrcode.QrCodeScannerFragment import im.vector.app.features.qrcode.QrCodeScannerFragment
@ -206,7 +207,11 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() {
} }
private fun renderCreationSuccess(roomId: String) { private fun renderCreationSuccess(roomId: String) {
navigator.openRoom(this, roomId) navigator.openRoom(
context = this,
roomId = roomId,
trigger = ViewRoom.Trigger.MessageUser
)
finish() finish()
} }

View file

@ -18,6 +18,7 @@ package im.vector.app.features.crypto.verification
import android.content.Context import android.content.Context
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.platform.VectorBaseActivity 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.displayname.getBestName
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.detail.RoomDetailActivity import im.vector.app.features.home.room.detail.RoomDetailActivity
@ -156,7 +157,12 @@ class IncomingVerificationRequestHandler @Inject constructor(
if (roomId.isNullOrBlank()) { if (roomId.isNullOrBlank()) {
it.navigator.waitSessionVerification(it) it.navigator.waitSessionVerification(it)
} else { } else {
it.navigator.openRoom(it, roomId, pr.transactionId) it.navigator.openRoom(
context = it,
roomId = roomId,
eventId = pr.transactionId,
trigger = ViewRoom.Trigger.VerificationRequest
)
} }
} }
} }

View file

@ -49,8 +49,10 @@ import im.vector.app.features.MainActivity
import im.vector.app.features.MainActivityArgs import im.vector.app.features.MainActivityArgs
import im.vector.app.features.analytics.accountdata.AnalyticsAccountDataViewModel import im.vector.app.features.analytics.accountdata.AnalyticsAccountDataViewModel
import im.vector.app.features.analytics.plan.MobileScreen 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.disclaimer.showDisclaimerDialog
import im.vector.app.features.matrixto.MatrixToBottomSheet 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.navigation.Navigator
import im.vector.app.features.notifications.NotificationDrawerManager import im.vector.app.features.notifications.NotificationDrawerManager
import im.vector.app.features.permalink.NavigationInterceptor import im.vector.app.features.permalink.NavigationInterceptor
@ -243,7 +245,7 @@ class HomeActivity :
} }
if (args?.inviteNotificationRoomId != null) { if (args?.inviteNotificationRoomId != null) {
activeSessionHolder.getSafeActiveSession()?.permalinkService()?.createPermalink(args.inviteNotificationRoomId)?.let { 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() activeSessionHolder.getSafeActiveSession()
?.permalinkService() ?.permalinkService()
?.createPermalink(parcelableExtra.inviteNotificationRoomId)?.let { ?.createPermalink(parcelableExtra.inviteNotificationRoomId)?.let {
navigator.openMatrixToBottomSheet(this, it) navigator.openMatrixToBottomSheet(this, it, OriginOfMatrixTo.NOTIFICATION)
} }
} }
handleIntent(intent) handleIntent(intent)
@ -567,14 +569,14 @@ class HomeActivity :
override fun navToMemberProfile(userId: String, deepLink: Uri): Boolean { override fun navToMemberProfile(userId: String, deepLink: Uri): Boolean {
// TODO check if there is already one?? // TODO check if there is already one??
MatrixToBottomSheet.withLink(deepLink.toString()) MatrixToBottomSheet.withLink(deepLink.toString(), OriginOfMatrixTo.LINK)
.show(supportFragmentManager, "HA#MatrixToBottomSheet") .show(supportFragmentManager, "HA#MatrixToBottomSheet")
return true return true
} }
override fun navToRoom(roomId: String?, eventId: String?, deepLink: Uri?, rootThreadEventId: String?): Boolean { override fun navToRoom(roomId: String?, eventId: String?, deepLink: Uri?, rootThreadEventId: String?): Boolean {
if (roomId == null) return false if (roomId == null) return false
MatrixToBottomSheet.withLink(deepLink.toString()) MatrixToBottomSheet.withLink(deepLink.toString(), OriginOfMatrixTo.LINK)
.show(supportFragmentManager, "HA#MatrixToBottomSheet") .show(supportFragmentManager, "HA#MatrixToBottomSheet")
return true return true
} }
@ -608,8 +610,8 @@ class HomeActivity :
} }
} }
override fun mxToBottomSheetNavigateToRoom(roomId: String) { override fun mxToBottomSheetNavigateToRoom(roomId: String, trigger: ViewRoom.Trigger?) {
navigator.openRoom(this, roomId) navigator.openRoom(this, roomId, trigger = trigger)
} }
override fun mxToBottomSheetSwitchToSpace(spaceId: String) { override fun mxToBottomSheetSwitchToSpace(spaceId: String) {

View file

@ -36,6 +36,7 @@ import im.vector.app.core.extensions.replaceFragment
import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivityRoomDetailBinding import im.vector.app.databinding.ActivityRoomDetailBinding
import im.vector.app.features.analytics.plan.MobileScreen 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.breadcrumbs.BreadcrumbsFragment
import im.vector.app.features.home.room.detail.arguments.TimelineArgs import im.vector.app.features.home.room.detail.arguments.TimelineArgs
import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker
@ -205,8 +206,8 @@ class RoomDetailActivity :
} }
} }
override fun mxToBottomSheetNavigateToRoom(roomId: String) { override fun mxToBottomSheetNavigateToRoom(roomId: String, trigger: ViewRoom.Trigger?) {
navigator.openRoom(this, roomId) navigator.openRoom(this, roomId, trigger = trigger)
} }
override fun mxToBottomSheetSwitchToSpace(spaceId: String) { override fun mxToBottomSheetSwitchToSpace(spaceId: String) {

View file

@ -40,6 +40,7 @@ import im.vector.app.core.utils.BehaviorDataSource
import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.AnalyticsTracker
import im.vector.app.features.analytics.DecryptionFailureTracker import im.vector.app.features.analytics.DecryptionFailureTracker
import im.vector.app.features.analytics.extensions.toAnalyticsJoinedRoom 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.ConferenceEvent
import im.vector.app.features.call.conference.JitsiActiveConferenceHolder import im.vector.app.features.call.conference.JitsiActiveConferenceHolder
import im.vector.app.features.call.conference.JitsiService import im.vector.app.features.call.conference.JitsiService
@ -821,13 +822,22 @@ class TimelineViewModel @AssistedInject constructor(
viewModelScope.launch { viewModelScope.launch {
try { try {
session.roomService().joinRoom(room.roomId) session.roomService().joinRoom(room.roomId)
analyticsTracker.capture(room.roomSummary().toAnalyticsJoinedRoom()) trackRoomJoined()
} catch (throwable: Throwable) { } catch (throwable: Throwable) {
_viewEvents.post(RoomDetailViewEvents.Failure(throwable, showInDialog = true)) _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) { private fun handleOpenOrDownloadFile(action: RoomDetailAction.DownloadOrOpen) {
val mxcUrl = action.messageFileContent.getFileUrl() ?: return val mxcUrl = action.messageFileContent.getFileUrl() ?: return
val isLocalSendingFile = action.senderId == session.myUserId && val isLocalSendingFile = action.senderId == session.myUserId &&

View file

@ -28,6 +28,7 @@ import im.vector.app.core.resources.StringProvider
import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.AnalyticsTracker
import im.vector.app.features.analytics.extensions.toAnalyticsComposer import im.vector.app.features.analytics.extensions.toAnalyticsComposer
import im.vector.app.features.analytics.extensions.toAnalyticsJoinedRoom 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.attachments.toContentAttachmentData
import im.vector.app.features.command.CommandParser import im.vector.app.features.command.CommandParser
import im.vector.app.features.command.ParsedCommand import im.vector.app.features.command.ParsedCommand
@ -617,7 +618,7 @@ class MessageComposerViewModel @AssistedInject constructor(
return@launch return@launch
} }
session.getRoomSummary(command.roomAlias) session.getRoomSummary(command.roomAlias)
?.also { analyticsTracker.capture(it.toAnalyticsJoinedRoom()) } ?.also { analyticsTracker.capture(it.toAnalyticsJoinedRoom(JoinedRoom.Trigger.SlashCommand)) }
?.roomId ?.roomId
?.let { ?.let {
_viewEvents.post(MessageComposerViewEvents.JoinRoomCommandSuccess(it)) _viewEvents.post(MessageComposerViewEvents.JoinRoomCommandSuccess(it))

View file

@ -37,6 +37,7 @@ import im.vector.app.core.extensions.trackItemsVisibilityChange
import im.vector.app.core.platform.StateView import im.vector.app.core.platform.StateView
import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.databinding.FragmentSearchBinding 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 im.vector.app.features.home.room.threads.arguments.ThreadTimelineArgs
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.Event
@ -134,7 +135,16 @@ class SearchFragment @Inject constructor(
roomEncryptionTrustLevel = null, roomEncryptionTrustLevel = null,
rootThreadEventId = it) rootThreadEventId = it)
navigator.openThread(requireContext(), threadTimelineArgs, event.eventId) 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() { override fun loadMore() {

View file

@ -44,12 +44,14 @@ import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.resources.UserPreferencesProvider import im.vector.app.core.resources.UserPreferencesProvider
import im.vector.app.databinding.FragmentRoomListBinding import im.vector.app.databinding.FragmentRoomListBinding
import im.vector.app.features.analytics.plan.MobileScreen 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.RoomListDisplayMode
import im.vector.app.features.home.room.filtered.FilteredRoomFooterItem 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.RoomListQuickActionsBottomSheet
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedAction 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.actions.RoomListQuickActionsSharedActionViewModel
import im.vector.app.features.home.room.list.widget.NotifsFabMenuView 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 im.vector.app.features.notifications.NotificationDrawerManager
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
@ -179,7 +181,7 @@ class RoomListFragment @Inject constructor(
} }
private fun handleShowMxToLink(link: String) { private fun handleShowMxToLink(link: String) {
navigator.openMatrixToBottomSheet(requireContext(), link) navigator.openMatrixToBottomSheet(requireContext(), link, OriginOfMatrixTo.ROOM_LIST)
} }
override fun onDestroyView() { override fun onDestroyView() {
@ -196,7 +198,12 @@ class RoomListFragment @Inject constructor(
} }
private fun handleSelectRoom(event: RoomListViewEvents.SelectRoom, isInviteAlreadyAccepted: Boolean) { 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() { private fun setupCreateRoomButton() {

View file

@ -32,6 +32,8 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider import im.vector.app.core.resources.StringProvider
import im.vector.app.features.analytics.AnalyticsTracker 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.displayname.getBestName
import im.vector.app.features.invite.AutoAcceptInvites import im.vector.app.features.invite.AutoAcceptInvites
import im.vector.app.features.settings.VectorPreferences 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.query.QueryStringValue
import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.getRoom 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.UpdatableLivePageResult
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
import org.matrix.android.sdk.api.session.room.model.tag.RoomTag import org.matrix.android.sdk.api.session.room.model.tag.RoomTag
@ -276,6 +279,8 @@ class RoomListViewModel @AssistedInject constructor(
this[action.roomId] = Fail(failure) this[action.roomId] = Fail(failure)
}.toMap()) }.toMap())
} }
session.getRoomSummary(action.roomId)
?.let { analyticsTracker.capture(it.toAnalyticsJoinedRoom(JoinedRoom.Trigger.RoomDirectory)) }
} }
} }

View file

@ -32,6 +32,7 @@ import im.vector.app.R
import im.vector.app.core.extensions.commitTransaction import im.vector.app.core.extensions.commitTransaction
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
import im.vector.app.databinding.BottomSheetMatrixToCardBinding import im.vector.app.databinding.BottomSheetMatrixToCardBinding
import im.vector.app.features.analytics.plan.ViewRoom
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import org.matrix.android.sdk.api.session.permalinks.PermalinkData import org.matrix.android.sdk.api.session.permalinks.PermalinkData
@ -44,7 +45,8 @@ class MatrixToBottomSheet :
@Parcelize @Parcelize
data class MatrixToArgs( data class MatrixToArgs(
val matrixToLink: String val matrixToLink: String,
val origin: OriginOfMatrixTo
) : Parcelable ) : Parcelable
@Inject lateinit var avatarRenderer: AvatarRenderer @Inject lateinit var avatarRenderer: AvatarRenderer
@ -58,7 +60,7 @@ class MatrixToBottomSheet :
private val viewModel by fragmentViewModel(MatrixToBottomSheetViewModel::class) private val viewModel by fragmentViewModel(MatrixToBottomSheetViewModel::class)
interface InteractionListener { interface InteractionListener {
fun mxToBottomSheetNavigateToRoom(roomId: String) fun mxToBottomSheetNavigateToRoom(roomId: String, trigger: ViewRoom.Trigger?)
fun mxToBottomSheetSwitchToSpace(spaceId: String) fun mxToBottomSheetSwitchToSpace(spaceId: String)
} }
@ -97,7 +99,9 @@ class MatrixToBottomSheet :
viewModel.observeViewEvents { viewModel.observeViewEvents {
when (it) { when (it) {
is MatrixToViewEvents.NavigateToRoom -> { is MatrixToViewEvents.NavigateToRoom -> {
interactionListener?.mxToBottomSheetNavigateToRoom(it.roomId) withState(viewModel) { state ->
interactionListener?.mxToBottomSheetNavigateToRoom(it.roomId, state.origin.toViewRoomTrigger())
}
dismiss() dismiss()
} }
MatrixToViewEvents.Dismiss -> dismiss() MatrixToViewEvents.Dismiss -> dismiss()
@ -116,9 +120,9 @@ class MatrixToBottomSheet :
} }
companion object { companion object {
fun withLink(matrixToLink: String): MatrixToBottomSheet { fun withLink(matrixToLink: String, origin: OriginOfMatrixTo): MatrixToBottomSheet {
return MatrixToBottomSheet().apply { return MatrixToBottomSheet().apply {
setArguments(MatrixToArgs(matrixToLink = matrixToLink)) setArguments(MatrixToArgs(matrixToLink = matrixToLink, origin = origin))
} }
} }
} }

View file

@ -30,12 +30,14 @@ data class MatrixToBottomSheetState(
val matrixItem: Async<MatrixItem> = Uninitialized, val matrixItem: Async<MatrixItem> = Uninitialized,
val startChattingState: Async<Unit> = Uninitialized, val startChattingState: Async<Unit> = Uninitialized,
val roomPeekResult: Async<RoomInfoResult> = Uninitialized, val roomPeekResult: Async<RoomInfoResult> = Uninitialized,
val peopleYouKnow: Async<List<MatrixItem.UserItem>> = Uninitialized val peopleYouKnow: Async<List<MatrixItem.UserItem>> = Uninitialized,
val origin: OriginOfMatrixTo
) : MavericksState { ) : MavericksState {
constructor(args: MatrixToBottomSheet.MatrixToArgs) : this( constructor(args: MatrixToBottomSheet.MatrixToArgs) : this(
deepLink = args.matrixToLink, deepLink = args.matrixToLink,
linkType = PermalinkParser.parse(args.matrixToLink) linkType = PermalinkParser.parse(args.matrixToLink),
origin = args.origin
) )
} }

View file

@ -30,6 +30,8 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider 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 im.vector.app.features.createdirect.DirectRoomHelper
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch 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.extensions.tryOrNull
import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.getRoom 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.permalinks.PermalinkData
import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.peeking.PeekResult import org.matrix.android.sdk.api.session.room.peeking.PeekResult
@ -50,7 +53,8 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor(
private val session: Session, private val session: Session,
private val stringProvider: StringProvider, private val stringProvider: StringProvider,
private val directRoomHelper: DirectRoomHelper, private val directRoomHelper: DirectRoomHelper,
private val errorFormatter: ErrorFormatter private val errorFormatter: ErrorFormatter,
private val analyticsTracker: AnalyticsTracker
) : VectorViewModel<MatrixToBottomSheetState, MatrixToAction, MatrixToViewEvents>(initialState) { ) : VectorViewModel<MatrixToBottomSheetState, MatrixToAction, MatrixToViewEvents>(initialState) {
@AssistedFactory @AssistedFactory
@ -275,6 +279,11 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor(
viewModelScope.launch { viewModelScope.launch {
try { try {
val joinResult = session.spaceService().joinSpace(joinSpace.spaceID, null, joinSpace.viaServers?.take(3) ?: emptyList()) 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()) { if (joinResult.isSuccess()) {
_viewEvents.post(MatrixToViewEvents.NavigateToSpace(joinSpace.spaceID)) _viewEvents.post(MatrixToViewEvents.NavigateToSpace(joinSpace.spaceID))
} else { } else {
@ -303,7 +312,14 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor(
reason = null, reason = null,
viaServers = action.viaServers?.take(3) ?: emptyList() 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) { } catch (failure: Throwable) {
_viewEvents.post(MatrixToViewEvents.ShowModalError(errorFormatter.toHumanReadable(failure))) _viewEvents.post(MatrixToViewEvents.ShowModalError(errorFormatter.toHumanReadable(failure)))
} finally { } finally {

View file

@ -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
}
}

View file

@ -39,6 +39,9 @@ import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.utils.toast import im.vector.app.core.utils.toast
import im.vector.app.features.VectorFeatures import im.vector.app.features.VectorFeatures
import im.vector.app.features.VectorFeatures.OnboardingVariant 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.analytics.ui.consent.AnalyticsOptInActivity
import im.vector.app.features.call.conference.JitsiCallViewModel import im.vector.app.features.call.conference.JitsiCallViewModel
import im.vector.app.features.call.conference.VectorJitsiActivity 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.LoginActivity
import im.vector.app.features.login.LoginConfig import im.vector.app.features.login.LoginConfig
import im.vector.app.features.matrixto.MatrixToBottomSheet 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.AttachmentData
import im.vector.app.features.media.BigImageViewerActivity import im.vector.app.features.media.BigImageViewerActivity
import im.vector.app.features.media.VectorAttachmentViewerActivity import im.vector.app.features.media.VectorAttachmentViewerActivity
@ -118,7 +122,8 @@ class DefaultNavigator @Inject constructor(
private val widgetArgsBuilder: WidgetArgsBuilder, private val widgetArgsBuilder: WidgetArgsBuilder,
private val appStateHandler: AppStateHandler, private val appStateHandler: AppStateHandler,
private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider, private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider,
private val features: VectorFeatures private val features: VectorFeatures,
private val analyticsTracker: AnalyticsTracker
) : Navigator { ) : Navigator {
override fun openLogin(context: Context, loginConfig: LoginConfig?, flags: Int) { override fun openLogin(context: Context, loginConfig: LoginConfig?, flags: Int) {
@ -150,12 +155,23 @@ class DefaultNavigator @Inject constructor(
roomId: String, roomId: String,
eventId: String?, eventId: String?,
buildTask: Boolean, buildTask: Boolean,
isInviteAlreadyAccepted: Boolean isInviteAlreadyAccepted: Boolean,
trigger: ViewRoom.Trigger?
) { ) {
if (sessionHolder.getSafeActiveSession()?.getRoom(roomId) == null) { if (sessionHolder.getSafeActiveSession()?.getRoom(roomId) == null) {
fatalError("Trying to open an unknown room $roomId", vectorPreferences.failFast()) fatalError("Trying to open an unknown room $roomId", vectorPreferences.failFast())
return 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 args = TimelineArgs(roomId = roomId, eventId = eventId, isInviteAlreadyAccepted = isInviteAlreadyAccepted)
val intent = RoomDetailActivity.newIntent(context, args) val intent = RoomDetailActivity.newIntent(context, args)
startActivity(context, intent, buildTask) startActivity(context, intent, buildTask)
@ -296,13 +312,13 @@ class DefaultNavigator @Inject constructor(
context.startActivity(intent) 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 AppCompatActivity) {
if (context !is MatrixToBottomSheet.InteractionListener) { if (context !is MatrixToBottomSheet.InteractionListener) {
fatalError("Caller context should implement MatrixToBottomSheet.InteractionListener", vectorPreferences.failFast()) fatalError("Caller context should implement MatrixToBottomSheet.InteractionListener", vectorPreferences.failFast())
} }
// TODO check if there is already one?? // TODO check if there is already one??
MatrixToBottomSheet.withLink(link) MatrixToBottomSheet.withLink(link, origin)
.show(context.supportFragmentManager, "HA#MatrixToBottomSheet") .show(context.supportFragmentManager, "HA#MatrixToBottomSheet")
} }
} }

View file

@ -23,12 +23,14 @@ import android.net.Uri
import android.view.View import android.view.View
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.core.util.Pair 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.crypto.recover.SetupMode
import im.vector.app.features.displayname.getBestName import im.vector.app.features.displayname.getBestName
import im.vector.app.features.home.room.threads.arguments.ThreadTimelineArgs import im.vector.app.features.home.room.threads.arguments.ThreadTimelineArgs
import im.vector.app.features.location.LocationData import im.vector.app.features.location.LocationData
import im.vector.app.features.location.LocationSharingMode import im.vector.app.features.location.LocationSharingMode
import im.vector.app.features.login.LoginConfig 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.media.AttachmentData
import im.vector.app.features.pin.PinMode import im.vector.app.features.pin.PinMode
import im.vector.app.features.poll.PollMode import im.vector.app.features.poll.PollMode
@ -50,7 +52,12 @@ interface Navigator {
fun softLogout(context: Context) 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 { sealed class PostSwitchSpaceAction {
object None : PostSwitchSpaceAction() object None : PostSwitchSpaceAction()
@ -79,7 +86,7 @@ interface Navigator {
fun openRoomPreview(context: Context, roomPreviewData: RoomPreviewData, fromEmailInviteLink: PermalinkData.RoomEmailInviteLink? = null) 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) fun openCreateRoom(context: Context, initialName: String = "", openAfterCreate: Boolean = true)

View file

@ -25,6 +25,7 @@ import im.vector.app.R
import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.AnalyticsTracker
import im.vector.app.features.analytics.extensions.toAnalyticsJoinedRoom import im.vector.app.features.analytics.extensions.toAnalyticsJoinedRoom
import im.vector.app.features.analytics.plan.JoinedRoom
import im.vector.app.features.session.coroutineScope import im.vector.app.features.session.coroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.extensions.tryOrNull
@ -85,7 +86,7 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
session.coroutineScope.launch { session.coroutineScope.launch {
tryOrNull { tryOrNull {
session.roomService().joinRoom(room.roomId) session.roomService().joinRoom(room.roomId)
analyticsTracker.capture(room.roomSummary().toAnalyticsJoinedRoom()) analyticsTracker.capture(room.roomSummary().toAnalyticsJoinedRoom(JoinedRoom.Trigger.Notification))
} }
} }
} }

View file

@ -25,6 +25,7 @@ import im.vector.app.core.extensions.isIgnored
import im.vector.app.core.resources.UserPreferencesProvider import im.vector.app.core.resources.UserPreferencesProvider
import im.vector.app.core.utils.toast import im.vector.app.core.utils.toast
import im.vector.app.features.home.room.threads.arguments.ThreadTimelineArgs 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.navigation.Navigator
import im.vector.app.features.roomdirectory.roompreview.RoomPreviewData import im.vector.app.features.roomdirectory.roompreview.RoomPreviewData
import kotlinx.coroutines.Dispatchers 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) navigationInterceptor.openJoinedRoomScreen(buildTask, roomId, eventId, rawLink, context, rootThreadEventId, roomSummary)
} else { } else {
// maybe open space preview navigator.openSpacePreview(context, roomId)? if already joined? // maybe open space preview navigator.openSpacePreview(context, roomId)? if already joined?
navigator.openMatrixToBottomSheet(context, rawLink.toString()) navigator.openMatrixToBottomSheet(context, rawLink.toString(), OriginOfMatrixTo.LINK)
} }
} }
else -> { else -> {
// XXX this could trigger another server load // XXX this could trigger another server load
navigator.openMatrixToBottomSheet(context, rawLink.toString()) navigator.openMatrixToBottomSheet(context, rawLink.toString(), OriginOfMatrixTo.LINK)
} }
} }
} }

View file

@ -33,6 +33,7 @@ import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.platform.showOptimizedSnackbar import im.vector.app.core.platform.showOptimizedSnackbar
import im.vector.app.core.utils.toast import im.vector.app.core.utils.toast
import im.vector.app.databinding.FragmentPublicRoomsBinding 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.NavigationInterceptor
import im.vector.app.features.permalink.PermalinkHandler import im.vector.app.features.permalink.PermalinkHandler
import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.debounce
@ -143,7 +144,11 @@ class PublicRoomsFragment @Inject constructor(
withState(viewModel) { state -> withState(viewModel) { state ->
when (joinState) { when (joinState) {
JoinState.JOINED -> { JoinState.JOINED -> {
navigator.openRoom(requireActivity(), publicRoom.roomId) navigator.openRoom(
context = requireActivity(),
roomId = publicRoom.roomId,
trigger = ViewRoom.Trigger.RoomDirectory
)
} }
else -> { else -> {
// ROOM PREVIEW // ROOM PREVIEW

View file

@ -29,6 +29,7 @@ import im.vector.app.core.extensions.popBackstack
import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivitySimpleBinding import im.vector.app.databinding.ActivitySimpleBinding
import im.vector.app.features.analytics.plan.MobileScreen 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.matrixto.MatrixToBottomSheet
import im.vector.app.features.navigation.Navigator import im.vector.app.features.navigation.Navigator
import im.vector.app.features.roomdirectory.createroom.CreateRoomArgs import im.vector.app.features.roomdirectory.createroom.CreateRoomArgs
@ -88,8 +89,8 @@ class RoomDirectoryActivity : VectorBaseActivity<ActivitySimpleBinding>(), Matri
} }
} }
override fun mxToBottomSheetNavigateToRoom(roomId: String) { override fun mxToBottomSheetNavigateToRoom(roomId: String, trigger: ViewRoom.Trigger?) {
navigator.openRoom(this, roomId) navigator.openRoom(this, roomId, trigger = trigger)
} }
override fun mxToBottomSheetSwitchToSpace(spaceId: String) { override fun mxToBottomSheetSwitchToSpace(spaceId: String) {

View file

@ -29,6 +29,7 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.AnalyticsTracker
import im.vector.app.features.analytics.extensions.toAnalyticsJoinedRoom import im.vector.app.features.analytics.extensions.toAnalyticsJoinedRoom
import im.vector.app.features.analytics.plan.JoinedRoom
import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorPreferences
import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
@ -226,7 +227,7 @@ class RoomDirectoryViewModel @AssistedInject constructor(
viewModelScope.launch { viewModelScope.launch {
try { try {
session.roomService().joinRoom(action.publicRoom.roomId, viaServers = viaServers) 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. // 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 // Instead, we wait for the room to be joined
} catch (failure: Throwable) { } catch (failure: Throwable) {

View file

@ -38,6 +38,7 @@ import im.vector.app.core.platform.OnBackPressed
import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.ColorProvider
import im.vector.app.databinding.FragmentCreateRoomBinding 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.navigation.Navigator
import im.vector.app.features.roomdirectory.RoomDirectorySharedAction import im.vector.app.features.roomdirectory.RoomDirectorySharedAction
import im.vector.app.features.roomdirectory.RoomDirectorySharedActionViewModel import im.vector.app.features.roomdirectory.RoomDirectorySharedActionViewModel
@ -219,20 +220,25 @@ class CreateRoomFragment @Inject constructor(
val async = state.asyncCreateRoomRequest val async = state.asyncCreateRoomRequest
views.waitingView.root.isVisible = async is Loading views.waitingView.root.isVisible = async is Loading
if (async is Success) { if (async is Success) {
val roomId = async()
// Navigate to freshly created room // Navigate to freshly created room
if (state.openAfterCreate) { if (state.openAfterCreate) {
if (state.isSubSpace) { if (state.isSubSpace) {
navigator.switchToSpace( navigator.switchToSpace(
requireContext(), requireContext(),
async(), roomId,
Navigator.PostSwitchSpaceAction.None Navigator.PostSwitchSpaceAction.None
) )
} else { } 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) sharedActionViewModel.post(RoomDirectorySharedAction.Close)
} else { } else {
// Populate list with Epoxy // Populate list with Epoxy

View file

@ -38,6 +38,7 @@ import im.vector.app.core.utils.styleMatchingText
import im.vector.app.core.utils.tappableMatchingText import im.vector.app.core.utils.tappableMatchingText
import im.vector.app.databinding.FragmentRoomPreviewNoPreviewBinding import im.vector.app.databinding.FragmentRoomPreviewNoPreviewBinding
import im.vector.app.features.analytics.plan.MobileScreen 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.home.AvatarRenderer
import im.vector.app.features.navigation.Navigator import im.vector.app.features.navigation.Navigator
import im.vector.app.features.roomdirectory.JoinState import im.vector.app.features.roomdirectory.JoinState
@ -100,7 +101,13 @@ class RoomPreviewNoPreviewFragment @Inject constructor(
if (state.roomType == RoomType.SPACE) { if (state.roomType == RoomType.SPACE) {
navigator.switchToSpace(requireActivity(), state.roomId, Navigator.PostSwitchSpaceAction.None) navigator.switchToSpace(requireActivity(), state.roomId, Navigator.PostSwitchSpaceAction.None)
} else { } 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
)
} }
} }

View file

@ -27,7 +27,7 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.EmptyViewEvents
import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.analytics.AnalyticsTracker 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.analytics.plan.JoinedRoom
import im.vector.app.features.roomdirectory.JoinState import im.vector.app.features.roomdirectory.JoinState
import kotlinx.coroutines.Dispatchers 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.extensions.tryOrNull
import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.session.Session 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.SharedState
import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.identity.ThreePid
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
@ -248,17 +249,13 @@ class RoomPreviewViewModel @AssistedInject constructor(
viewModelScope.launch { viewModelScope.launch {
try { try {
session.roomService().joinRoom(state.roomId, viaServers = state.homeServers) 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. // 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 // Instead, we wait for the room to be joined
} catch (failure: Throwable) { } catch (failure: Throwable) {
setState { copy(lastError = failure) } setState { copy(lastError = failure) }
} }
session.getRoomSummary(state.roomId)
?.let { analyticsTracker.capture(it.toAnalyticsJoinedRoom(JoinedRoom.Trigger.RoomPreview)) }
} }
} }
} }

View file

@ -37,6 +37,7 @@ import im.vector.app.core.extensions.configureWith
import im.vector.app.core.extensions.registerStartForActivityResult import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.databinding.FragmentIncomingShareBinding 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.AttachmentsHelper
import im.vector.app.features.attachments.preview.AttachmentsPreviewActivity import im.vector.app.features.attachments.preview.AttachmentsPreviewActivity
import im.vector.app.features.attachments.preview.AttachmentsPreviewArgs import im.vector.app.features.attachments.preview.AttachmentsPreviewArgs
@ -125,7 +126,11 @@ class IncomingShareFragment @Inject constructor(
private fun handleMultipleRoomsShareDone(viewEvent: IncomingShareViewEvents.MultipleRoomsShareDone) { private fun handleMultipleRoomsShareDone(viewEvent: IncomingShareViewEvents.MultipleRoomsShareDone) {
requireActivity().let { requireActivity().let {
navigator.openRoom(it, viewEvent.roomId) navigator.openRoom(
context = it,
roomId = viewEvent.roomId,
trigger = ViewRoom.Trigger.MobileLinkShare
)
it.finish() it.finish()
} }
} }

View file

@ -30,7 +30,9 @@ import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.extensions.replaceFragment
import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivitySimpleBinding 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.MatrixToBottomSheet
import im.vector.app.features.matrixto.OriginOfMatrixTo
import im.vector.app.features.navigation.Navigator import im.vector.app.features.navigation.Navigator
import im.vector.app.features.roomdirectory.createroom.CreateRoomActivity import im.vector.app.features.roomdirectory.createroom.CreateRoomActivity
import im.vector.app.features.spaces.explore.SpaceDirectoryArgs import im.vector.app.features.spaces.explore.SpaceDirectoryArgs
@ -92,10 +94,14 @@ class SpaceExploreActivity : VectorBaseActivity<ActivitySimpleBinding>(), Matrix
finish() finish()
} }
is SpaceDirectoryViewEvents.NavigateToRoom -> { is SpaceDirectoryViewEvents.NavigateToRoom -> {
navigator.openRoom(this, it.roomId) navigator.openRoom(
context = this,
roomId = it.roomId,
trigger = ViewRoom.Trigger.SpaceHierarchy
)
} }
is SpaceDirectoryViewEvents.NavigateToMxToBottomSheet -> { is SpaceDirectoryViewEvents.NavigateToMxToBottomSheet -> {
MatrixToBottomSheet.withLink(it.link).show(supportFragmentManager, "ShowChild") MatrixToBottomSheet.withLink(it.link, OriginOfMatrixTo.SPACE_EXPLORE).show(supportFragmentManager, "ShowChild")
} }
is SpaceDirectoryViewEvents.NavigateToCreateNewRoom -> { is SpaceDirectoryViewEvents.NavigateToCreateNewRoom -> {
createRoomResultLauncher.launch(CreateRoomActivity.getIntent( createRoomResultLauncher.launch(CreateRoomActivity.getIntent(
@ -121,8 +127,8 @@ class SpaceExploreActivity : VectorBaseActivity<ActivitySimpleBinding>(), Matrix
} }
} }
override fun mxToBottomSheetNavigateToRoom(roomId: String) { override fun mxToBottomSheetNavigateToRoom(roomId: String, trigger: ViewRoom.Trigger?) {
navigator.openRoom(this, roomId) navigator.openRoom(this, roomId, trigger = trigger)
} }
override fun mxToBottomSheetSwitchToSpace(spaceId: String) { override fun mxToBottomSheetSwitchToSpace(spaceId: String) {

View file

@ -27,6 +27,9 @@ import dagger.assisted.AssistedInject
import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.MavericksAssistedViewModelFactory
import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory
import im.vector.app.core.platform.VectorViewModel 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 im.vector.app.features.powerlevel.PowerLevelsFlowFactory
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
@ -49,7 +52,8 @@ import timber.log.Timber
class SpaceDirectoryViewModel @AssistedInject constructor( class SpaceDirectoryViewModel @AssistedInject constructor(
@Assisted val initialState: SpaceDirectoryState, @Assisted val initialState: SpaceDirectoryState,
private val session: Session private val session: Session,
private val analyticsTracker: AnalyticsTracker
) : VectorViewModel<SpaceDirectoryState, SpaceDirectoryViewAction, SpaceDirectoryViewEvents>(initialState) { ) : VectorViewModel<SpaceDirectoryState, SpaceDirectoryViewAction, SpaceDirectoryViewEvents>(initialState) {
@AssistedFactory @AssistedFactory
@ -416,6 +420,9 @@ class SpaceDirectoryViewModel @AssistedInject constructor(
} catch (failure: Throwable) { } catch (failure: Throwable) {
Timber.e(failure, "## Space: Failed to join room or subspace") Timber.e(failure, "## Space: Failed to join room or subspace")
} }
session.getRoomSummary(childId)
?.let { analyticsTracker.capture(it.toAnalyticsJoinedRoom(JoinedRoom.Trigger.SpaceHierarchy)) }
} }
} }
} }

View file

@ -30,6 +30,7 @@ import im.vector.app.core.extensions.replaceFragment
import im.vector.app.core.platform.GenericIdArgs import im.vector.app.core.platform.GenericIdArgs
import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivitySimpleLoadingBinding import im.vector.app.databinding.ActivitySimpleLoadingBinding
import im.vector.app.features.analytics.plan.ViewRoom
import im.vector.app.features.spaces.share.ShareSpaceBottomSheet import im.vector.app.features.spaces.share.ShareSpaceBottomSheet
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
@ -90,7 +91,11 @@ class SpacePeopleActivity : VectorBaseActivity<ActivitySimpleLoadingBinding>() {
} }
private fun navigateToRooms(action: SpacePeopleSharedAction.NavigateToRoom) { private fun navigateToRooms(action: SpacePeopleSharedAction.NavigateToRoom) {
navigator.openRoom(this, action.roomId) navigator.openRoom(
context = this,
roomId = action.roomId,
trigger = ViewRoom.Trigger.MobileSpaceMembers
)
finish() finish()
} }

View file

@ -34,7 +34,9 @@ import im.vector.app.core.extensions.replaceFragment
import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.utils.onPermissionDeniedSnackbar import im.vector.app.core.utils.onPermissionDeniedSnackbar
import im.vector.app.databinding.ActivitySimpleBinding 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.MatrixToBottomSheet
import im.vector.app.features.matrixto.OriginOfMatrixTo
import im.vector.app.features.qrcode.QrCodeScannerEvents import im.vector.app.features.qrcode.QrCodeScannerEvents
import im.vector.app.features.qrcode.QrCodeScannerFragment import im.vector.app.features.qrcode.QrCodeScannerFragment
import im.vector.app.features.qrcode.QrCodeScannerViewModel import im.vector.app.features.qrcode.QrCodeScannerViewModel
@ -92,7 +94,7 @@ class UserCodeActivity : VectorBaseActivity<ActivitySimpleBinding>(),
} }
is UserCodeState.Mode.RESULT -> { is UserCodeState.Mode.RESULT -> {
showFragment(ShowUserCodeFragment::class) 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<ActivitySimpleBinding>(),
} }
} }
override fun mxToBottomSheetNavigateToRoom(roomId: String) { override fun mxToBottomSheetNavigateToRoom(roomId: String, trigger: ViewRoom.Trigger?) {
navigator.openRoom(this, roomId) navigator.openRoom(this, roomId, trigger = trigger)
} }
override fun mxToBottomSheetSwitchToSpace(spaceId: String) {} override fun mxToBottomSheetSwitchToSpace(spaceId: String) {}