mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-26 03:16:02 +03:00
added analytics for app layout (#7242)
This commit is contained in:
parent
8fd0107d84
commit
9f8c7688bf
17 changed files with 144 additions and 15 deletions
1
changelog.d/6508.misc
Normal file
1
changelog.d/6508.misc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
[AppLayout]: added tracking of new analytics events
|
|
@ -22,6 +22,7 @@ import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.core.utils.BehaviorDataSource
|
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.plan.UserProperties
|
import im.vector.app.features.analytics.plan.UserProperties
|
||||||
|
import im.vector.app.features.analytics.plan.ViewRoom
|
||||||
import im.vector.app.features.session.coroutineScope
|
import im.vector.app.features.session.coroutineScope
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
import im.vector.app.features.ui.UiStateRepository
|
import im.vector.app.features.ui.UiStateRepository
|
||||||
|
@ -82,6 +83,13 @@ class SpaceStateHandlerImpl @Inject constructor(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
analyticsTracker.capture(
|
||||||
|
ViewRoom(
|
||||||
|
isDM = false,
|
||||||
|
isSpace = true,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if (isForwardNavigation) {
|
if (isForwardNavigation) {
|
||||||
addToBackstack(spaceToLeave, spaceToSet)
|
addToBackstack(spaceToLeave, spaceToSet)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
package im.vector.app.features.analytics.extensions
|
package im.vector.app.features.analytics.extensions
|
||||||
|
|
||||||
import im.vector.app.features.analytics.plan.UserProperties
|
import im.vector.app.features.analytics.plan.UserProperties
|
||||||
|
import im.vector.app.features.home.room.list.home.header.HomeRoomFilter
|
||||||
import im.vector.app.features.onboarding.FtueUseCase
|
import im.vector.app.features.onboarding.FtueUseCase
|
||||||
|
|
||||||
fun FtueUseCase.toTrackingValue(): UserProperties.FtueUseCaseSelection {
|
fun FtueUseCase.toTrackingValue(): UserProperties.FtueUseCaseSelection {
|
||||||
|
@ -27,3 +28,12 @@ fun FtueUseCase.toTrackingValue(): UserProperties.FtueUseCaseSelection {
|
||||||
FtueUseCase.SKIP -> UserProperties.FtueUseCaseSelection.Skip
|
FtueUseCase.SKIP -> UserProperties.FtueUseCaseSelection.Skip
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun HomeRoomFilter.toTrackingValue(): UserProperties.AllChatsActiveFilter {
|
||||||
|
return when (this) {
|
||||||
|
HomeRoomFilter.ALL -> UserProperties.AllChatsActiveFilter.All
|
||||||
|
HomeRoomFilter.UNREADS -> UserProperties.AllChatsActiveFilter.Unreads
|
||||||
|
HomeRoomFilter.FAVOURITES -> UserProperties.AllChatsActiveFilter.Favourites
|
||||||
|
HomeRoomFilter.PEOPlE -> UserProperties.AllChatsActiveFilter.People
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -34,6 +34,9 @@ import im.vector.app.core.platform.StateView
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.core.resources.DrawableProvider
|
import im.vector.app.core.resources.DrawableProvider
|
||||||
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.toTrackingValue
|
||||||
|
import im.vector.app.features.analytics.plan.UserProperties
|
||||||
import im.vector.app.features.displayname.getBestName
|
import im.vector.app.features.displayname.getBestName
|
||||||
import im.vector.app.features.home.room.list.home.header.HomeRoomFilter
|
import im.vector.app.features.home.room.list.home.header.HomeRoomFilter
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
@ -74,6 +77,7 @@ class HomeRoomListViewModel @AssistedInject constructor(
|
||||||
private val preferencesStore: HomeLayoutPreferencesStore,
|
private val preferencesStore: HomeLayoutPreferencesStore,
|
||||||
private val stringProvider: StringProvider,
|
private val stringProvider: StringProvider,
|
||||||
private val drawableProvider: DrawableProvider,
|
private val drawableProvider: DrawableProvider,
|
||||||
|
private val analyticsTracker: AnalyticsTracker,
|
||||||
) : VectorViewModel<HomeRoomListViewState, HomeRoomListAction, HomeRoomListViewEvents>(initialState) {
|
) : VectorViewModel<HomeRoomListViewState, HomeRoomListAction, HomeRoomListViewEvents>(initialState) {
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
|
@ -358,6 +362,7 @@ class HomeRoomListViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
setState { copy(headersData = headersData.copy(currentFilter = newFilter)) }
|
setState { copy(headersData = headersData.copy(currentFilter = newFilter)) }
|
||||||
updateEmptyState()
|
updateEmptyState()
|
||||||
|
analyticsTracker.updateUserProperties(UserProperties(allChatsActiveFilter = newFilter.toTrackingValue()))
|
||||||
filteredPagedRoomSummariesLive?.let { liveResults ->
|
filteredPagedRoomSummariesLive?.let { liveResults ->
|
||||||
liveResults.queryParams = getFilteredQueryParams(newFilter, liveResults.queryParams)
|
liveResults.queryParams = getFilteredQueryParams(newFilter, liveResults.queryParams)
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import com.google.android.material.color.MaterialColors
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import im.vector.app.core.utils.FirstItemUpdatedObserver
|
import im.vector.app.core.utils.FirstItemUpdatedObserver
|
||||||
|
import im.vector.app.features.analytics.AnalyticsTracker
|
||||||
import im.vector.app.features.home.AvatarRenderer
|
import im.vector.app.features.home.AvatarRenderer
|
||||||
import im.vector.app.features.home.room.list.RoomListListener
|
import im.vector.app.features.home.room.list.RoomListListener
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
|
@ -38,6 +39,7 @@ class HomeRoomsHeadersController @Inject constructor(
|
||||||
val stringProvider: StringProvider,
|
val stringProvider: StringProvider,
|
||||||
private val avatarRenderer: AvatarRenderer,
|
private val avatarRenderer: AvatarRenderer,
|
||||||
resources: Resources,
|
resources: Resources,
|
||||||
|
private val analyticsTracker: AnalyticsTracker,
|
||||||
) : EpoxyController() {
|
) : EpoxyController() {
|
||||||
|
|
||||||
private var data: RoomsHeadersData = RoomsHeadersData()
|
private var data: RoomsHeadersData = RoomsHeadersData()
|
||||||
|
@ -73,7 +75,11 @@ class HomeRoomsHeadersController @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
host.data.filtersList?.let {
|
host.data.filtersList?.let {
|
||||||
addRoomFilterHeaderItem(host.onFilterChangedListener, it, host.data.currentFilter)
|
addRoomFilterHeaderItem(
|
||||||
|
filterChangedListener = host.onFilterChangedListener,
|
||||||
|
filtersList = it,
|
||||||
|
currentFilter = host.data.currentFilter,
|
||||||
|
analyticsTracker = analyticsTracker)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,12 +164,14 @@ class HomeRoomsHeadersController @Inject constructor(
|
||||||
filterChangedListener: ((HomeRoomFilter) -> Unit)?,
|
filterChangedListener: ((HomeRoomFilter) -> Unit)?,
|
||||||
filtersList: List<HomeRoomFilter>,
|
filtersList: List<HomeRoomFilter>,
|
||||||
currentFilter: HomeRoomFilter?,
|
currentFilter: HomeRoomFilter?,
|
||||||
|
analyticsTracker: AnalyticsTracker,
|
||||||
) {
|
) {
|
||||||
roomFilterHeaderItem {
|
roomFilterHeaderItem {
|
||||||
id("filter_header")
|
id("filter_header")
|
||||||
filtersData(filtersList)
|
filtersData(filtersList)
|
||||||
selectedFilter(currentFilter)
|
selectedFilter(currentFilter)
|
||||||
onFilterChangedListener(filterChangedListener)
|
onFilterChangedListener(filterChangedListener)
|
||||||
|
analyticsTracker(analyticsTracker)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ import com.google.android.material.tabs.TabLayout
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||||
|
import im.vector.app.features.analytics.AnalyticsTracker
|
||||||
|
import im.vector.app.features.analytics.plan.Interaction
|
||||||
|
|
||||||
@EpoxyModelClass
|
@EpoxyModelClass
|
||||||
abstract class RoomFilterHeaderItem : VectorEpoxyModel<RoomFilterHeaderItem.Holder>(R.layout.item_home_filter_tabs) {
|
abstract class RoomFilterHeaderItem : VectorEpoxyModel<RoomFilterHeaderItem.Holder>(R.layout.item_home_filter_tabs) {
|
||||||
|
@ -35,6 +37,9 @@ abstract class RoomFilterHeaderItem : VectorEpoxyModel<RoomFilterHeaderItem.Hold
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var selectedFilter: HomeRoomFilter? = null
|
var selectedFilter: HomeRoomFilter? = null
|
||||||
|
|
||||||
|
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
|
||||||
|
var analyticsTracker: AnalyticsTracker? = null
|
||||||
|
|
||||||
override fun bind(holder: Holder) {
|
override fun bind(holder: Holder) {
|
||||||
super.bind(holder)
|
super.bind(holder)
|
||||||
with(holder.tabLayout) {
|
with(holder.tabLayout) {
|
||||||
|
@ -51,6 +56,7 @@ abstract class RoomFilterHeaderItem : VectorEpoxyModel<RoomFilterHeaderItem.Hold
|
||||||
addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
|
addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
|
||||||
override fun onTabSelected(tab: TabLayout.Tab?) {
|
override fun onTabSelected(tab: TabLayout.Tab?) {
|
||||||
(tab?.tag as? HomeRoomFilter)?.let { filter ->
|
(tab?.tag as? HomeRoomFilter)?.let { filter ->
|
||||||
|
trackFilterChangeEvent(filter)
|
||||||
onFilterChangedListener?.invoke(filter)
|
onFilterChangedListener?.invoke(filter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,6 +67,23 @@ abstract class RoomFilterHeaderItem : VectorEpoxyModel<RoomFilterHeaderItem.Hold
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun trackFilterChangeEvent(filter: HomeRoomFilter) {
|
||||||
|
val interactionName = when (filter) {
|
||||||
|
HomeRoomFilter.ALL -> Interaction.Name.MobileAllChatsFilterAll
|
||||||
|
HomeRoomFilter.UNREADS -> Interaction.Name.MobileAllChatsFilterUnreads
|
||||||
|
HomeRoomFilter.FAVOURITES -> Interaction.Name.MobileAllChatsFilterFavourites
|
||||||
|
HomeRoomFilter.PEOPlE -> Interaction.Name.MobileAllChatsFilterPeople
|
||||||
|
}
|
||||||
|
|
||||||
|
analyticsTracker?.capture(
|
||||||
|
Interaction(
|
||||||
|
index = null,
|
||||||
|
interactionType = null,
|
||||||
|
name = interactionName
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override fun unbind(holder: Holder) {
|
override fun unbind(holder: Holder) {
|
||||||
holder.tabLayout.clearOnTabSelectedListeners()
|
holder.tabLayout.clearOnTabSelectedListeners()
|
||||||
super.unbind(holder)
|
super.unbind(holder)
|
||||||
|
|
|
@ -27,6 +27,7 @@ import im.vector.app.core.extensions.configureWith
|
||||||
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.FragmentInvitesBinding
|
import im.vector.app.databinding.FragmentInvitesBinding
|
||||||
|
import im.vector.app.features.analytics.plan.MobileScreen
|
||||||
import im.vector.app.features.analytics.plan.ViewRoom
|
import im.vector.app.features.analytics.plan.ViewRoom
|
||||||
import im.vector.app.features.home.room.list.RoomListListener
|
import im.vector.app.features.home.room.list.RoomListListener
|
||||||
import im.vector.app.features.notifications.NotificationDrawerManager
|
import im.vector.app.features.notifications.NotificationDrawerManager
|
||||||
|
@ -48,6 +49,11 @@ class InvitesFragment : VectorBaseFragment<FragmentInvitesBinding>(), RoomListLi
|
||||||
return FragmentInvitesBinding.inflate(inflater, container, false)
|
return FragmentInvitesBinding.inflate(inflater, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
analyticsScreenName = MobileScreen.ScreenName.Invites
|
||||||
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import dagger.hilt.android.AndroidEntryPoint
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||||
import im.vector.app.databinding.BottomSheetHomeLayoutSettingsBinding
|
import im.vector.app.databinding.BottomSheetHomeLayoutSettingsBinding
|
||||||
|
import im.vector.app.features.analytics.plan.Interaction
|
||||||
import im.vector.app.features.home.room.list.home.HomeLayoutPreferencesStore
|
import im.vector.app.features.home.room.list.home.HomeLayoutPreferencesStore
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
@ -54,9 +55,11 @@ class HomeLayoutSettingBottomDialogFragment : VectorBaseBottomSheetDialogFragmen
|
||||||
}
|
}
|
||||||
|
|
||||||
views.homeLayoutSettingsRecents.setOnCheckedChangeListener { _, isChecked ->
|
views.homeLayoutSettingsRecents.setOnCheckedChangeListener { _, isChecked ->
|
||||||
|
trackRecentsStateEvent(isChecked)
|
||||||
setRecentsEnabled(isChecked)
|
setRecentsEnabled(isChecked)
|
||||||
}
|
}
|
||||||
views.homeLayoutSettingsFilters.setOnCheckedChangeListener { _, isChecked ->
|
views.homeLayoutSettingsFilters.setOnCheckedChangeListener { _, isChecked ->
|
||||||
|
trackFiltersStateEvent(isChecked)
|
||||||
setFiltersEnabled(isChecked)
|
setFiltersEnabled(isChecked)
|
||||||
}
|
}
|
||||||
views.homeLayoutSettingsSortGroup.setOnCheckedChangeListener { _, checkedId ->
|
views.homeLayoutSettingsSortGroup.setOnCheckedChangeListener { _, checkedId ->
|
||||||
|
@ -64,10 +67,40 @@ class HomeLayoutSettingBottomDialogFragment : VectorBaseBottomSheetDialogFragmen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun trackRecentsStateEvent(areEnabled: Boolean) {
|
||||||
|
val interactionName = if (areEnabled) {
|
||||||
|
Interaction.Name.MobileAllChatsRecentsEnabled
|
||||||
|
} else {
|
||||||
|
Interaction.Name.MobileAllChatsRecentsDisabled
|
||||||
|
}
|
||||||
|
analyticsTracker.capture(
|
||||||
|
Interaction(
|
||||||
|
index = null,
|
||||||
|
interactionType = null,
|
||||||
|
name = interactionName
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun setRecentsEnabled(isEnabled: Boolean) = lifecycleScope.launch {
|
private fun setRecentsEnabled(isEnabled: Boolean) = lifecycleScope.launch {
|
||||||
preferencesStore.setRecentsEnabled(isEnabled)
|
preferencesStore.setRecentsEnabled(isEnabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun trackFiltersStateEvent(areEnabled: Boolean) {
|
||||||
|
val interactionName = if (areEnabled) {
|
||||||
|
Interaction.Name.MobileAllChatsFiltersEnabled
|
||||||
|
} else {
|
||||||
|
Interaction.Name.MobileAllChatsFiltersDisabled
|
||||||
|
}
|
||||||
|
analyticsTracker.capture(
|
||||||
|
Interaction(
|
||||||
|
index = null,
|
||||||
|
interactionType = null,
|
||||||
|
name = interactionName
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun setFiltersEnabled(isEnabled: Boolean) = lifecycleScope.launch {
|
private fun setFiltersEnabled(isEnabled: Boolean) = lifecycleScope.launch {
|
||||||
preferencesStore.setFiltersEnabled(isEnabled)
|
preferencesStore.setFiltersEnabled(isEnabled)
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ class NewSpaceSummaryController @Inject constructor(
|
||||||
text(host.stringProvider.getString(R.string.all_chats))
|
text(host.stringProvider.getString(R.string.all_chats))
|
||||||
selected(selected)
|
selected(selected)
|
||||||
countState(UnreadCounterBadgeView.State.Count(homeCount.totalCount, homeCount.isHighlight))
|
countState(UnreadCounterBadgeView.State.Count(homeCount.totalCount, homeCount.isHighlight))
|
||||||
listener { host.callback?.onSpaceSelected(null) }
|
listener { host.callback?.onSpaceSelected(null, isSubSpace = false) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ class NewSpaceSummaryController @Inject constructor(
|
||||||
hasChildren(hasChildren)
|
hasChildren(hasChildren)
|
||||||
matrixItem(spaceSummary.toMatrixItem())
|
matrixItem(spaceSummary.toMatrixItem())
|
||||||
onLongClickListener { host.callback?.onSpaceSettings(spaceSummary) }
|
onLongClickListener { host.callback?.onSpaceSettings(spaceSummary) }
|
||||||
onSpaceSelectedListener { host.callback?.onSpaceSelected(spaceSummary) }
|
onSpaceSelectedListener { host.callback?.onSpaceSelected(spaceSummary, isSubSpace = false) }
|
||||||
onToggleExpandListener { host.callback?.onToggleExpand(spaceSummary) }
|
onToggleExpandListener { host.callback?.onToggleExpand(spaceSummary) }
|
||||||
selected(isSelected)
|
selected(isSelected)
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ class NewSpaceSummaryController @Inject constructor(
|
||||||
indent(depth)
|
indent(depth)
|
||||||
matrixItem(childSummary.toMatrixItem())
|
matrixItem(childSummary.toMatrixItem())
|
||||||
onLongClickListener { host.callback?.onSpaceSettings(childSummary) }
|
onLongClickListener { host.callback?.onSpaceSettings(childSummary) }
|
||||||
onSubSpaceSelectedListener { host.callback?.onSpaceSelected(childSummary) }
|
onSubSpaceSelectedListener { host.callback?.onSpaceSelected(childSummary, isSubSpace = true) }
|
||||||
onToggleExpandListener { host.callback?.onToggleExpand(childSummary) }
|
onToggleExpandListener { host.callback?.onToggleExpand(childSummary) }
|
||||||
selected(isSelected)
|
selected(isSelected)
|
||||||
}
|
}
|
||||||
|
@ -184,8 +184,10 @@ class NewSpaceSummaryController @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a full duplicate of [SpaceSummaryController.Callback]. We need to merge them ASAP*/
|
||||||
interface Callback {
|
interface Callback {
|
||||||
fun onSpaceSelected(spaceSummary: RoomSummary?)
|
fun onSpaceSelected(spaceSummary: RoomSummary?, isSubSpace: Boolean)
|
||||||
fun onSpaceInviteSelected(spaceSummary: RoomSummary)
|
fun onSpaceInviteSelected(spaceSummary: RoomSummary)
|
||||||
fun onSpaceSettings(spaceSummary: RoomSummary)
|
fun onSpaceSettings(spaceSummary: RoomSummary)
|
||||||
fun onToggleExpand(spaceSummary: RoomSummary)
|
fun onToggleExpand(spaceSummary: RoomSummary)
|
||||||
|
|
|
@ -20,7 +20,7 @@ import im.vector.app.core.platform.VectorViewModelAction
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
|
|
||||||
sealed class SpaceListAction : VectorViewModelAction {
|
sealed class SpaceListAction : VectorViewModelAction {
|
||||||
data class SelectSpace(val spaceSummary: RoomSummary?) : SpaceListAction()
|
data class SelectSpace(val spaceSummary: RoomSummary?, val isSubSpace: Boolean) : SpaceListAction()
|
||||||
data class OpenSpaceInvite(val spaceSummary: RoomSummary) : SpaceListAction()
|
data class OpenSpaceInvite(val spaceSummary: RoomSummary) : SpaceListAction()
|
||||||
data class LeaveSpace(val spaceSummary: RoomSummary) : SpaceListAction()
|
data class LeaveSpace(val spaceSummary: RoomSummary) : SpaceListAction()
|
||||||
data class ToggleExpand(val spaceSummary: RoomSummary) : SpaceListAction()
|
data class ToggleExpand(val spaceSummary: RoomSummary) : SpaceListAction()
|
||||||
|
|
|
@ -25,6 +25,7 @@ import im.vector.app.R
|
||||||
import im.vector.app.core.extensions.replaceChildFragment
|
import im.vector.app.core.extensions.replaceChildFragment
|
||||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||||
import im.vector.app.databinding.FragmentSpacesBottomSheetBinding
|
import im.vector.app.databinding.FragmentSpacesBottomSheetBinding
|
||||||
|
import im.vector.app.features.analytics.plan.MobileScreen
|
||||||
|
|
||||||
class SpaceListBottomSheet : VectorBaseBottomSheetDialogFragment<FragmentSpacesBottomSheetBinding>() {
|
class SpaceListBottomSheet : VectorBaseBottomSheetDialogFragment<FragmentSpacesBottomSheetBinding>() {
|
||||||
|
|
||||||
|
@ -32,6 +33,11 @@ class SpaceListBottomSheet : VectorBaseBottomSheetDialogFragment<FragmentSpacesB
|
||||||
return FragmentSpacesBottomSheetBinding.inflate(inflater, container, false)
|
return FragmentSpacesBottomSheetBinding.inflate(inflater, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
analyticsScreenName = MobileScreen.ScreenName.SpaceBottomSheet
|
||||||
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
replaceChildFragment(R.id.space_list, SpaceListFragment::class.java)
|
replaceChildFragment(R.id.space_list, SpaceListFragment::class.java)
|
||||||
|
|
|
@ -176,8 +176,8 @@ class SpaceListFragment :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSpaceSelected(spaceSummary: RoomSummary?) {
|
override fun onSpaceSelected(spaceSummary: RoomSummary?, isSubSpace: Boolean) {
|
||||||
viewModel.handle(SpaceListAction.SelectSpace(spaceSummary))
|
viewModel.handle(SpaceListAction.SelectSpace(spaceSummary, isSubSpace = isSubSpace))
|
||||||
roomListSharedActionViewModel.post(RoomListSharedAction.CloseBottomSheet)
|
roomListSharedActionViewModel.post(RoomListSharedAction.CloseBottomSheet)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -215,7 +215,18 @@ class SpaceListViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
private fun handleSelectSpace(action: SpaceListAction.SelectSpace) = withState { state ->
|
private fun handleSelectSpace(action: SpaceListAction.SelectSpace) = withState { state ->
|
||||||
if (state.selectedSpace?.roomId != action.spaceSummary?.roomId) {
|
if (state.selectedSpace?.roomId != action.spaceSummary?.roomId) {
|
||||||
analyticsTracker.capture(Interaction(null, null, Interaction.Name.SpacePanelSwitchSpace))
|
val interactionName = if (action.isSubSpace) {
|
||||||
|
Interaction.Name.SpacePanelSwitchSubSpace
|
||||||
|
} else {
|
||||||
|
Interaction.Name.SpacePanelSwitchSpace
|
||||||
|
}
|
||||||
|
analyticsTracker.capture(
|
||||||
|
Interaction(
|
||||||
|
index = null,
|
||||||
|
interactionType = null,
|
||||||
|
name = interactionName
|
||||||
|
)
|
||||||
|
)
|
||||||
setState { copy(selectedSpace = action.spaceSummary) }
|
setState { copy(selectedSpace = action.spaceSummary) }
|
||||||
spaceStateHandler.setCurrentSpace(action.spaceSummary?.roomId)
|
spaceStateHandler.setCurrentSpace(action.spaceSummary?.roomId)
|
||||||
_viewEvents.post(SpaceListViewEvents.CloseDrawer)
|
_viewEvents.post(SpaceListViewEvents.CloseDrawer)
|
||||||
|
|
|
@ -88,7 +88,7 @@ class SpaceSummaryController @Inject constructor(
|
||||||
id("space_home")
|
id("space_home")
|
||||||
selected(selectedSpace == null)
|
selected(selectedSpace == null)
|
||||||
countState(UnreadCounterBadgeView.State.Count(homeCount.totalCount, homeCount.isHighlight))
|
countState(UnreadCounterBadgeView.State.Count(homeCount.totalCount, homeCount.isHighlight))
|
||||||
listener { host.callback?.onSpaceSelected(null) }
|
listener { host.callback?.onSpaceSelected(null, isSubSpace = false) }
|
||||||
}
|
}
|
||||||
|
|
||||||
rootSpaces
|
rootSpaces
|
||||||
|
@ -114,7 +114,7 @@ class SpaceSummaryController @Inject constructor(
|
||||||
selected(isSelected)
|
selected(isSelected)
|
||||||
canDrag(true)
|
canDrag(true)
|
||||||
onMore { host.callback?.onSpaceSettings(roomSummary) }
|
onMore { host.callback?.onSpaceSettings(roomSummary) }
|
||||||
listener { host.callback?.onSpaceSelected(roomSummary) }
|
listener { host.callback?.onSpaceSelected(roomSummary, isSubSpace = false) }
|
||||||
toggleExpand { host.callback?.onToggleExpand(roomSummary) }
|
toggleExpand { host.callback?.onToggleExpand(roomSummary) }
|
||||||
countState(
|
countState(
|
||||||
UnreadCounterBadgeView.State.Count(
|
UnreadCounterBadgeView.State.Count(
|
||||||
|
@ -165,7 +165,7 @@ class SpaceSummaryController @Inject constructor(
|
||||||
expanded(expanded)
|
expanded(expanded)
|
||||||
onMore { host.callback?.onSpaceSettings(childSummary) }
|
onMore { host.callback?.onSpaceSettings(childSummary) }
|
||||||
matrixItem(childSummary.toMatrixItem())
|
matrixItem(childSummary.toMatrixItem())
|
||||||
listener { host.callback?.onSpaceSelected(childSummary) }
|
listener { host.callback?.onSpaceSelected(childSummary, isSubSpace = true) }
|
||||||
toggleExpand { host.callback?.onToggleExpand(childSummary) }
|
toggleExpand { host.callback?.onToggleExpand(childSummary) }
|
||||||
indent(currentDepth)
|
indent(currentDepth)
|
||||||
countState(
|
countState(
|
||||||
|
@ -184,7 +184,7 @@ class SpaceSummaryController @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Callback {
|
interface Callback {
|
||||||
fun onSpaceSelected(spaceSummary: RoomSummary?)
|
fun onSpaceSelected(spaceSummary: RoomSummary?, isSubSpace: Boolean)
|
||||||
fun onSpaceInviteSelected(spaceSummary: RoomSummary)
|
fun onSpaceInviteSelected(spaceSummary: RoomSummary)
|
||||||
fun onSpaceSettings(spaceSummary: RoomSummary)
|
fun onSpaceSettings(spaceSummary: RoomSummary)
|
||||||
fun onToggleExpand(spaceSummary: RoomSummary)
|
fun onToggleExpand(spaceSummary: RoomSummary)
|
||||||
|
|
|
@ -25,6 +25,7 @@ import dagger.hilt.android.AndroidEntryPoint
|
||||||
import im.vector.app.core.epoxy.onClick
|
import im.vector.app.core.epoxy.onClick
|
||||||
import im.vector.app.core.platform.VectorBaseFragment
|
import im.vector.app.core.platform.VectorBaseFragment
|
||||||
import im.vector.app.databinding.FragmentSpaceCreateChooseTypeBinding
|
import im.vector.app.databinding.FragmentSpaceCreateChooseTypeBinding
|
||||||
|
import im.vector.app.features.analytics.plan.MobileScreen
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class ChooseSpaceTypeFragment :
|
class ChooseSpaceTypeFragment :
|
||||||
|
@ -35,6 +36,11 @@ class ChooseSpaceTypeFragment :
|
||||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?) =
|
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?) =
|
||||||
FragmentSpaceCreateChooseTypeBinding.inflate(layoutInflater, container, false)
|
FragmentSpaceCreateChooseTypeBinding.inflate(layoutInflater, container, false)
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
analyticsScreenName = MobileScreen.ScreenName.CreateSpace
|
||||||
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,8 @@ import im.vector.app.core.error.ErrorFormatter
|
||||||
import im.vector.app.core.extensions.isEmail
|
import im.vector.app.core.extensions.isEmail
|
||||||
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.plan.Interaction
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.MatrixPatterns
|
import org.matrix.android.sdk.api.MatrixPatterns
|
||||||
|
@ -46,7 +48,8 @@ class CreateSpaceViewModel @AssistedInject constructor(
|
||||||
private val session: Session,
|
private val session: Session,
|
||||||
private val stringProvider: StringProvider,
|
private val stringProvider: StringProvider,
|
||||||
private val createSpaceViewModelTask: CreateSpaceViewModelTask,
|
private val createSpaceViewModelTask: CreateSpaceViewModelTask,
|
||||||
private val errorFormatter: ErrorFormatter
|
private val errorFormatter: ErrorFormatter,
|
||||||
|
private val analyticsTracker: AnalyticsTracker,
|
||||||
) : VectorViewModel<CreateSpaceState, CreateSpaceAction, CreateSpaceEvents>(initialState) {
|
) : VectorViewModel<CreateSpaceState, CreateSpaceAction, CreateSpaceEvents>(initialState) {
|
||||||
|
|
||||||
private val identityService = session.identityService()
|
private val identityService = session.identityService()
|
||||||
|
@ -350,6 +353,13 @@ class CreateSpaceViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
|
analyticsTracker.capture(
|
||||||
|
Interaction(
|
||||||
|
index = null,
|
||||||
|
interactionType = null,
|
||||||
|
name = Interaction.Name.MobileSpaceCreationValidated
|
||||||
|
)
|
||||||
|
)
|
||||||
val alias = if (state.spaceType == SpaceType.Public) {
|
val alias = if (state.spaceType == SpaceType.Public) {
|
||||||
state.aliasLocalPart
|
state.aliasLocalPart
|
||||||
} else null
|
} else null
|
||||||
|
|
|
@ -19,4 +19,4 @@ package im.vector.app.test.fakes
|
||||||
import im.vector.app.features.analytics.AnalyticsTracker
|
import im.vector.app.features.analytics.AnalyticsTracker
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
|
|
||||||
class FakeAnalyticsTracker : AnalyticsTracker by mockk()
|
class FakeAnalyticsTracker : AnalyticsTracker by mockk(relaxUnitFun = true)
|
||||||
|
|
Loading…
Reference in a new issue