From d37cbb4ece7b770f50f62be3d779826485833b86 Mon Sep 17 00:00:00 2001 From: Konstantin Ivanov <54908981+konstantiniiv@users.noreply.github.com> Date: Mon, 7 Oct 2024 10:07:26 +0200 Subject: [PATCH] DROID-2866 All content | Analytics (#1631) --- .../analytics/base/EventsDictionary.kt | 12 ++- .../models/AllContentModels.kt | 37 +++++++- .../presentation/AllContentViewModel.kt | 51 +++++++++- .../presentation/extension/AnalyticsExt.kt | 93 ++++++++++++++++++- .../presentation/library/LibraryViewModel.kt | 2 +- 5 files changed, 189 insertions(+), 6 deletions(-) diff --git a/analytics/src/main/java/com/anytypeio/anytype/analytics/base/EventsDictionary.kt b/analytics/src/main/java/com/anytypeio/anytype/analytics/base/EventsDictionary.kt index b24f66f28d..aaac0044d3 100644 --- a/analytics/src/main/java/com/anytypeio/anytype/analytics/base/EventsDictionary.kt +++ b/analytics/src/main/java/com/anytypeio/anytype/analytics/base/EventsDictionary.kt @@ -211,6 +211,15 @@ object EventsDictionary { const val screenHistoryVersion = "ScreenHistoryVersion" const val restoreFromHistory = "RestoreFromHistory" + //All content + const val screenAllContent = "ScreenLibrary"//+ + const val changeLibraryType = "ChangeLibraryType" + const val changeLibraryTypeLink = "ChangeLibraryTypeLink" + const val searchInput = "SearchInput" + const val libraryResult = "LibraryResult" + const val changeLibrarySort = "ChangeLibrarySort"//+ + const val screenBin = "ScreenBin"//+ + const val searchBacklink = "SearchBacklink" object SharingSpacesTypes { @@ -277,7 +286,7 @@ object EventsDictionary { const val objCreateSet = "Set" const val objCreateHome = "Home" const val objCreateCollection = "Collection" - const val objCreateLibrary = "Library" + const val allContentRoute = "Library" const val objCreateMention = "Mention" const val objPowerTool = "Powertool" const val objLink = "Link" @@ -349,4 +358,5 @@ object EventsPropertiesKey { const val name = "name" const val spaceType = "spaceType" const val permissions = "permissions" + const val sort = "sort" } \ No newline at end of file diff --git a/feature-all-content/src/main/java/com/anytypeio/anytype/feature_allcontent/models/AllContentModels.kt b/feature-all-content/src/main/java/com/anytypeio/anytype/feature_allcontent/models/AllContentModels.kt index e316a0bd00..25669b1c04 100644 --- a/feature-all-content/src/main/java/com/anytypeio/anytype/feature_allcontent/models/AllContentModels.kt +++ b/feature-all-content/src/main/java/com/anytypeio/anytype/feature_allcontent/models/AllContentModels.kt @@ -1,6 +1,7 @@ package com.anytypeio.anytype.feature_allcontent.models import androidx.compose.runtime.Immutable +import com.anytypeio.anytype.core_models.Block import com.anytypeio.anytype.core_models.DVSortType import com.anytypeio.anytype.core_models.Id import com.anytypeio.anytype.core_models.Key @@ -142,7 +143,7 @@ sealed class UiContentItem { // MENU @Immutable -sealed class UiMenuState{ +sealed class UiMenuState { data object Hidden : UiMenuState() @@ -245,4 +246,38 @@ fun ObjectWrapper.Basic.toAllContentType( editable = !obj.restrictions.contains(ObjectRestriction.DETAILS) ) } + +fun AllContentSort.toAnalyticsSortType(): Pair { + return when (this) { + is AllContentSort.ByName -> "Name" to sortType.toAnalyticsSortType() + is AllContentSort.ByDateUpdated -> "Updated" to sortType.toAnalyticsSortType() + is AllContentSort.ByDateCreated -> "Created" to sortType.toAnalyticsSortType() + } +} + +fun DVSortType.toAnalyticsSortType(): String { + return when (this) { + DVSortType.ASC -> "Asc" + DVSortType.DESC -> "Desc" + DVSortType.CUSTOM -> "Custom" + } +} + +fun AllContentTab.toAnalyticsTabType(): String { + return when (this) { + AllContentTab.PAGES -> "Pages" + AllContentTab.LISTS -> "Lists" + AllContentTab.MEDIA -> "Media" + AllContentTab.BOOKMARKS -> "Bookmarks" + AllContentTab.FILES -> "Files" + AllContentTab.TYPES -> "Types" + } +} + +fun AllContentMenuMode.toAnalyticsModeType(): String { + return when (this) { + is AllContentMenuMode.AllContent -> "All" + is AllContentMenuMode.Unlinked -> "Unlinked" + } +} //endregion \ No newline at end of file diff --git a/feature-all-content/src/main/java/com/anytypeio/anytype/feature_allcontent/presentation/AllContentViewModel.kt b/feature-all-content/src/main/java/com/anytypeio/anytype/feature_allcontent/presentation/AllContentViewModel.kt index 8aab7533ad..8b6a2ad053 100644 --- a/feature-all-content/src/main/java/com/anytypeio/anytype/feature_allcontent/presentation/AllContentViewModel.kt +++ b/feature-all-content/src/main/java/com/anytypeio/anytype/feature_allcontent/presentation/AllContentViewModel.kt @@ -30,9 +30,19 @@ import com.anytypeio.anytype.feature_allcontent.models.UiTitleState import com.anytypeio.anytype.feature_allcontent.models.createSubscriptionParams import com.anytypeio.anytype.feature_allcontent.models.filtersForSearch import com.anytypeio.anytype.feature_allcontent.models.mapRelationKeyToSort +import com.anytypeio.anytype.feature_allcontent.models.toAnalyticsModeType +import com.anytypeio.anytype.feature_allcontent.models.toAnalyticsSortType +import com.anytypeio.anytype.feature_allcontent.models.toAnalyticsTabType import com.anytypeio.anytype.feature_allcontent.models.toUiContentItems import com.anytypeio.anytype.feature_allcontent.models.toUiContentTypes import com.anytypeio.anytype.presentation.analytics.AnalyticSpaceHelperDelegate +import com.anytypeio.anytype.presentation.extension.sendAnalyticsAllContentChangeMode +import com.anytypeio.anytype.presentation.extension.sendAnalyticsAllContentChangeSort +import com.anytypeio.anytype.presentation.extension.sendAnalyticsAllContentChangeType +import com.anytypeio.anytype.presentation.extension.sendAnalyticsAllContentResult +import com.anytypeio.anytype.presentation.extension.sendAnalyticsAllContentScreen +import com.anytypeio.anytype.presentation.extension.sendAnalyticsAllContentSearchInput +import com.anytypeio.anytype.presentation.extension.sendAnalyticsAllContentToBin import com.anytypeio.anytype.presentation.extension.sendAnalyticsObjectCreateEvent import com.anytypeio.anytype.presentation.home.OpenObjectNavigation import com.anytypeio.anytype.presentation.home.navigation @@ -414,6 +424,12 @@ class AllContentViewModel( uiItemsState.value = emptyList() uiTabsState.value = uiTabsState.value.copy(selectedTab = tab) restartSubscription.value++ + viewModelScope.launch { + sendAnalyticsAllContentChangeType( + analytics = analytics, + type = tab.toAnalyticsTabType() + ) + } } fun onAllContentModeClicked(mode: AllContentMenuMode) { @@ -425,6 +441,12 @@ class AllContentViewModel( is AllContentMenuMode.Unlinked -> UiTitleState.OnlyUnlinked } restartSubscription.value++ + viewModelScope.launch { + sendAnalyticsAllContentChangeMode( + analytics = analytics, + type = mode.toAnalyticsModeType() + ) + } } fun onSortClicked(sort: AllContentSort) { @@ -445,6 +467,13 @@ class AllContentViewModel( sortState.value = newSort proceedWithSortSaving(newSort) restartSubscription.value++ + viewModelScope.launch { + sendAnalyticsAllContentChangeSort( + analytics = analytics, + type = sort.toAnalyticsSortType().first, + sort = sort.toAnalyticsSortType().second + ) + } } private fun proceedWithSortSaving(sort: AllContentSort) { @@ -466,10 +495,22 @@ class AllContentViewModel( fun onFilterChanged(filter: String) { Timber.d("onFilterChanged: $filter") + val currentFilter = userInput.value.isEmpty() + viewModelScope.launch { + if (currentFilter && filter.isNotEmpty()) { + sendAnalyticsAllContentSearchInput( + analytics = analytics, + route = EventsDictionary.Routes.allContentRoute + ) + } + } userInput.value = filter } fun onViewBinClicked() { + viewModelScope.launch { + sendAnalyticsAllContentToBin(analytics = analytics) + } viewModelScope.launch { commands.emit(Command.NavigateToBin(vmParams.spaceId.id)) } @@ -484,6 +525,9 @@ class AllContentViewModel( space = vmParams.spaceId.id ) ) + viewModelScope.launch { + sendAnalyticsAllContentResult(analytics = analytics) + } } private fun proceedWithNavigation(navigation: OpenObjectNavigation) { @@ -557,7 +601,7 @@ class AllContentViewModel( ) sendAnalyticsObjectCreateEvent( analytics = analytics, - route = EventsDictionary.Routes.objCreateLibrary, + route = EventsDictionary.Routes.allContentRoute, startTime = startTime, objType = objType ?: storeOfObjectTypes.getByKey(result.typeKey.key), view = EventsDictionary.View.viewHome, @@ -579,6 +623,11 @@ class AllContentViewModel( fun onStart() { Timber.d("onStart") setupUiStateFlow() + viewModelScope.launch { + sendAnalyticsAllContentScreen( + analytics = analytics + ) + } } fun onStop() { diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/extension/AnalyticsExt.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/extension/AnalyticsExt.kt index 1392900200..f71c67452c 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/extension/AnalyticsExt.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/extension/AnalyticsExt.kt @@ -54,7 +54,6 @@ import com.anytypeio.anytype.domain.config.ConfigStorage import com.anytypeio.anytype.domain.objects.StoreOfRelations import com.anytypeio.anytype.presentation.analytics.AnalyticSpaceHelperDelegate import com.anytypeio.anytype.presentation.editor.editor.Markup -import com.anytypeio.anytype.presentation.relations.values import com.anytypeio.anytype.presentation.sets.isChangingDefaultTypeAvailable import com.anytypeio.anytype.presentation.sets.state.ObjectState import com.anytypeio.anytype.presentation.sets.viewerByIdOrFirst @@ -2121,4 +2120,94 @@ fun CoroutineScope.sendAnalyticsVersionHistoryRestore( eventName = EventsDictionary.restoreFromHistory ) } -//endregion \ No newline at end of file +//endregion + +//region AllContent +fun CoroutineScope.sendAnalyticsAllContentScreen( + analytics: Analytics +) { + sendEvent( + analytics = analytics, + eventName = EventsDictionary.screenAllContent + ) +} + +fun CoroutineScope.sendAnalyticsAllContentToBin( + analytics: Analytics +) { + sendEvent( + analytics = analytics, + eventName = EventsDictionary.screenBin + ) +} + +fun CoroutineScope.sendAnalyticsAllContentChangeType( + analytics: Analytics, + type: String +) { + sendEvent( + analytics = analytics, + eventName = EventsDictionary.changeLibraryType, + props = Props( + mapOf( + EventsPropertiesKey.type to type + ) + ) + ) +} + +fun CoroutineScope.sendAnalyticsAllContentChangeMode( + analytics: Analytics, + type: String +) { + sendEvent( + analytics = analytics, + eventName = EventsDictionary.changeLibraryTypeLink, + props = Props( + mapOf( + EventsPropertiesKey.type to type + ) + ) + ) +} + +fun CoroutineScope.sendAnalyticsAllContentSearchInput( + analytics: Analytics, + route: String +) { + sendEvent( + analytics = analytics, + eventName = EventsDictionary.searchInput, + props = Props( + mapOf( + EventsPropertiesKey.route to EventsDictionary.Routes.allContentRoute + ) + ) + ) +} + +fun CoroutineScope.sendAnalyticsAllContentResult( + analytics: Analytics +) { + sendEvent( + analytics = analytics, + eventName = EventsDictionary.libraryResult + ) +} + +fun CoroutineScope.sendAnalyticsAllContentChangeSort( + analytics: Analytics, + type: String, + sort: String +) { + sendEvent( + analytics = analytics, + eventName = EventsDictionary.changeLibrarySort, + props = Props( + mapOf( + EventsPropertiesKey.type to type, + EventsPropertiesKey.sort to sort + ) + ) + ) +} \ No newline at end of file diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/library/LibraryViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/library/LibraryViewModel.kt index 44e905026b..6dc032f96f 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/library/LibraryViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/library/LibraryViewModel.kt @@ -211,7 +211,7 @@ class LibraryViewModel( result -> proceedWithOpeningObject(result.obj) sendAnalyticsObjectCreateEvent( analytics = analytics, - route = EventsDictionary.Routes.objCreateLibrary, + route = EventsDictionary.Routes.allContentRoute, startTime = startTime, objType = objType ?: storeOfObjectTypes.getByKey(result.typeKey.key), view = EventsDictionary.View.viewHome,