1
0
Fork 0
mirror of https://github.com/anyproto/anytype-kotlin.git synced 2025-06-08 05:47:05 +09:00

DROID-1017 Analytics | Enhancement | Update events for Sets and Collections (#3023)

* DROID-1017 move analytics context and objectId to state

* DROID-1017 switchView event

* DROID-1017 addView event

* DROID-1017 deleteView, duplicateView

* DROID-1017 switchView

* DROID-1017 analyticsOriginalId block field

* DROID-1017 sorts, filters events

* DROID-1017 refactoring

* DROID-1017 open, select query, turn into events

* DROID-1017 logEvent fun

* DROID-1017 types formattedName

* DROID-1017 events dictionary

* DROID-1017 add root to objectState

* DROID-1017 tests update

* DROID-1017 showObject event, root param

* DROID-1017 analytics params, refactoring
This commit is contained in:
Konstantin Ivanov 2023-03-21 13:21:02 +01:00 committed by GitHub
parent a574c6d9c8
commit a6b639cc85
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 561 additions and 214 deletions

View file

@ -38,7 +38,6 @@ object EventsDictionary {
const val keychainPhraseScreenShow = "ScreenKeychain"
const val fileOffloadScreenShow = "ScreenFileOffloadWarning"
const val relationsScreenShow = "ScreenObjectRelation"
const val setScreenShow = "ScreenSet"
const val settingsShow = "ScreenSettings"
const val personalisationSettingsShow = "ScreenSettingsPersonalisation"
const val wallpaperScreenShow = "ScreenSettingsWallpaper"
@ -96,18 +95,21 @@ object EventsDictionary {
const val relationUrlEdit = "RelationUrlEditMobile"
// Sets
const val setAddView = "AddView"
const val setSwitchView = "SwitchView"
const val setRepositionView = "RepositionView"
const val setRemoveView = "RemoveView"
const val setAddFilter = "AddFilter"
const val setChangeFilterValue = "ChangeFilterValue"
const val setRepositionFilter = "RepositionFilter"
const val setRemoveFilter = "RemoveFilter"
const val setAddSort = "AddSort"
const val setChangeSortValue = "ChangeSortValue"
const val setRepositionSort = "RepositionSort"
const val setRemoveSort = "RemoveSort"
const val setScreenShow = "ScreenSet"
const val collectionScreenShow = "ScreenCollection"
const val turnIntoCollection = "SetTurnIntoCollection"
const val setSelectQuery = "SetSelectQuery"
const val addView = "AddView"
const val switchView = "SwitchView"
const val removeView = "RemoveView"
const val changeViewType = "ChangeViewType"
const val duplicateView = "DuplicateView"
const val addFilter = "AddFilter"
const val changeFilterValue = "ChangeFilterValue"
const val removeFilter = "RemoveFilter"
const val addSort = "AddSort"
const val changeSortValue = "ChangeSortValue"
const val removeSort = "RemoveSort"
// Block Actions
const val blockAction = "BlockAction"

View file

@ -166,7 +166,7 @@ class AddRelationStatusValueTest {
)
)
state.value = ObjectState.DataView.Set(blocks = listOf(dv))
state.value = ObjectState.DataView.Set(root = ctx, blocks = listOf(dv))
stubCreateRelationOption()
@ -243,7 +243,7 @@ class AddRelationStatusValueTest {
)
)
state.value = ObjectState.DataView.Set(blocks = listOf(dv))
state.value = ObjectState.DataView.Set(root = ctx, blocks = listOf(dv))
stubCreateRelationOption()
@ -326,7 +326,7 @@ class AddRelationStatusValueTest {
)
)
state.value = ObjectState.DataView.Set(blocks = listOf(dv))
state.value = ObjectState.DataView.Set(root = ctx, blocks = listOf(dv))
// TESTING
@ -408,7 +408,7 @@ class AddRelationStatusValueTest {
)
)
state.value = ObjectState.DataView.Set(blocks = listOf(dv))
state.value = ObjectState.DataView.Set(root = ctx, blocks = listOf(dv))
// TESTING
@ -499,7 +499,7 @@ class AddRelationStatusValueTest {
)
)
state.value = ObjectState.DataView.Set(blocks = listOf(dv))
state.value = ObjectState.DataView.Set(root = ctx, blocks = listOf(dv))
// TESTING

View file

@ -161,7 +161,7 @@ class AddRelationTagValueTest {
)
)
state.value = ObjectState.DataView.Set(blocks = listOf(dv))
state.value = ObjectState.DataView.Set(root = ctx,blocks = listOf(dv))
stubCreateRelationOption()
@ -262,7 +262,7 @@ class AddRelationTagValueTest {
)
)
state.value = ObjectState.DataView.Set(blocks = listOf(dv))
state.value = ObjectState.DataView.Set(root = ctx, blocks = listOf(dv))
// TESTING
@ -344,7 +344,7 @@ class AddRelationTagValueTest {
)
)
state.value = ObjectState.DataView.Set(blocks = listOf(dv))
state.value = ObjectState.DataView.Set(root = ctx, blocks = listOf(dv))
// TESTING
@ -435,7 +435,7 @@ class AddRelationTagValueTest {
)
)
state.value = ObjectState.DataView.Set(blocks = listOf(dv))
state.value = ObjectState.DataView.Set(root = ctx, blocks = listOf(dv))
// TESTING

View file

@ -105,6 +105,7 @@ class DisplayObjectRelationTextValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -168,6 +169,7 @@ class DisplayObjectRelationTextValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -233,6 +235,7 @@ class DisplayObjectRelationTextValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -298,6 +301,7 @@ class DisplayObjectRelationTextValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -361,6 +365,7 @@ class DisplayObjectRelationTextValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -425,6 +430,7 @@ class DisplayObjectRelationTextValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),

View file

@ -103,6 +103,7 @@ class DisplayRelationNumberValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -153,6 +154,7 @@ class DisplayRelationNumberValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -203,6 +205,7 @@ class DisplayRelationNumberValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),

View file

@ -139,6 +139,7 @@ class DisplayRelationObjectValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -199,6 +200,7 @@ class DisplayRelationObjectValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -248,6 +250,7 @@ class DisplayRelationObjectValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -329,6 +332,7 @@ class DisplayRelationObjectValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -437,6 +441,7 @@ class DisplayRelationObjectValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -535,6 +540,7 @@ class DisplayRelationObjectValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),

View file

@ -138,6 +138,7 @@ class DisplayRelationStatusValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -192,6 +193,7 @@ class DisplayRelationStatusValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -248,6 +250,7 @@ class DisplayRelationStatusValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -297,6 +300,7 @@ class DisplayRelationStatusValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -345,6 +349,7 @@ class DisplayRelationStatusValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),

View file

@ -135,6 +135,7 @@ class DisplayRelationTagValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -189,6 +190,7 @@ class DisplayRelationTagValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -251,6 +253,7 @@ class DisplayRelationTagValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -309,6 +312,7 @@ class DisplayRelationTagValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -357,6 +361,7 @@ class DisplayRelationTagValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),

View file

@ -153,6 +153,7 @@ class EditRelationTagValueTest {
)
state.value = ObjectState.DataView.Set(
root = ctx,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -245,6 +246,7 @@ class EditRelationTagValueTest {
)
state.value = ObjectState.DataView.Set(
root = ctx,
blocks = listOf(dv)
)

View file

@ -95,6 +95,7 @@ class ObjectRelationDateValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -157,6 +158,7 @@ class ObjectRelationDateValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -215,6 +217,7 @@ class ObjectRelationDateValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -278,6 +281,7 @@ class ObjectRelationDateValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -336,6 +340,7 @@ class ObjectRelationDateValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -395,6 +400,7 @@ class ObjectRelationDateValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),
@ -467,6 +473,7 @@ class ObjectRelationDateValueTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),

View file

@ -150,6 +150,7 @@ class CreateSelectedFilterTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(dv)
)
@ -219,6 +220,7 @@ class CreateSelectedFilterTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(dv)
)

View file

@ -148,6 +148,7 @@ class FilterListTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(dv)
)
@ -232,6 +233,7 @@ class FilterListTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(dv)
)
@ -316,6 +318,7 @@ class FilterListTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(dv)
)

View file

@ -156,6 +156,7 @@ class ModifyInputValueFilterTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(dv)
)
@ -251,6 +252,7 @@ class ModifyInputValueFilterTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(dv)
)

View file

@ -173,6 +173,7 @@ class ModifyStatusFilterTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(dv)
)

View file

@ -164,6 +164,7 @@ class ModifyTagFilterTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),

View file

@ -118,6 +118,7 @@ class ViewerObjectSortTest {
)
state.value = ObjectState.DataView.Set(
root = root,
blocks = listOf(
Block(
id = MockDataFactory.randomUuid(),

View file

@ -6,11 +6,13 @@ import com.anytypeio.anytype.core_utils.di.scope.PerModal
import com.anytypeio.anytype.domain.block.repo.BlockRepository
import com.anytypeio.anytype.domain.dataview.interactor.AddDataViewViewer
import com.anytypeio.anytype.presentation.sets.CreateDataViewViewerViewModel
import com.anytypeio.anytype.presentation.sets.state.ObjectState
import com.anytypeio.anytype.presentation.util.Dispatcher
import com.anytypeio.anytype.ui.sets.modals.CreateDataViewViewerFragment
import dagger.Module
import dagger.Provides
import dagger.Subcomponent
import kotlinx.coroutines.flow.MutableStateFlow
@Subcomponent(modules = [CreateDataViewViewerModule::class])
@PerModal
@ -33,11 +35,13 @@ object CreateDataViewViewerModule {
fun provideCreateDataViewViewerViewModelFactory(
dispatcher: Dispatcher<Payload>,
addDataViewViewer: AddDataViewViewer,
analytics: Analytics
analytics: Analytics,
objectState: MutableStateFlow<ObjectState>
): CreateDataViewViewerViewModel.Factory = CreateDataViewViewerViewModel.Factory(
dispatcher = dispatcher,
addDataViewViewer = addDataViewViewer,
analytics = analytics
analytics = analytics,
objectState = objectState
)
@JvmStatic

View file

@ -61,6 +61,7 @@ data class Block(
val analyticsContext: String? by default
val analyticsOriginalId: String? by default
companion object {
fun empty(): Fields = Fields(emptyMap())
@ -338,7 +339,11 @@ data class Block(
val relationKey: String,
val type: Type
) {
enum class Type { ASC, DESC, CUSTOM }
enum class Type(val formattedName: String) {
ASC("ascending"),
DESC("descending"),
CUSTOM("custom")
}
}
/**

View file

@ -2,8 +2,23 @@ package com.anytypeio.anytype.presentation.extension
import com.anytypeio.anytype.analytics.base.Analytics
import com.anytypeio.anytype.analytics.base.EventsDictionary
import com.anytypeio.anytype.analytics.base.EventsDictionary.collectionScreenShow
import com.anytypeio.anytype.analytics.base.EventsDictionary.objectMoveToBin
import com.anytypeio.anytype.analytics.base.EventsDictionary.objectScreenShow
import com.anytypeio.anytype.analytics.base.EventsDictionary.addView
import com.anytypeio.anytype.analytics.base.EventsDictionary.changeViewType
import com.anytypeio.anytype.analytics.base.EventsDictionary.duplicateView
import com.anytypeio.anytype.analytics.base.EventsDictionary.removeView
import com.anytypeio.anytype.analytics.base.EventsDictionary.addFilter
import com.anytypeio.anytype.analytics.base.EventsDictionary.addSort
import com.anytypeio.anytype.analytics.base.EventsDictionary.changeFilterValue
import com.anytypeio.anytype.analytics.base.EventsDictionary.changeSortValue
import com.anytypeio.anytype.analytics.base.EventsDictionary.removeFilter
import com.anytypeio.anytype.analytics.base.EventsDictionary.removeSort
import com.anytypeio.anytype.analytics.base.EventsDictionary.switchView
import com.anytypeio.anytype.analytics.base.EventsDictionary.setScreenShow
import com.anytypeio.anytype.analytics.base.EventsDictionary.setSelectQuery
import com.anytypeio.anytype.analytics.base.EventsDictionary.turnIntoCollection
import com.anytypeio.anytype.analytics.base.EventsPropertiesKey
import com.anytypeio.anytype.analytics.base.sendEvent
import com.anytypeio.anytype.analytics.event.EventAnalytics
@ -18,6 +33,7 @@ import com.anytypeio.anytype.core_models.Relation
import com.anytypeio.anytype.core_models.TextStyle
import com.anytypeio.anytype.core_utils.ext.Mimetype
import com.anytypeio.anytype.presentation.editor.editor.Markup
import com.anytypeio.anytype.presentation.sets.state.ObjectState
import kotlinx.coroutines.CoroutineScope
fun Block.Prototype.getAnalyticsEvent(
@ -618,119 +634,6 @@ fun CoroutineScope.sendAnalyticsRelationDeleteEvent(
)
}
fun CoroutineScope.sendAnalyticsShowSetEvent(
analytics: Analytics,
context: String? = null
) {
sendEvent(
analytics = analytics,
eventName = EventsDictionary.setScreenShow,
props = Props(mapOf(EventsPropertiesKey.context to context))
)
}
fun CoroutineScope.sendAnalyticsAddViewEvent(
analytics: Analytics,
type: String
) {
sendEvent(
analytics = analytics,
eventName = EventsDictionary.setAddView,
props = Props(mapOf(EventsPropertiesKey.type to type))
)
}
fun CoroutineScope.sendAnalyticsSwitchViewEvent(
analytics: Analytics,
type: String
) {
sendEvent(
analytics = analytics,
eventName = EventsDictionary.setSwitchView,
props = Props(mapOf(EventsPropertiesKey.type to type))
)
}
fun CoroutineScope.sendAnalyticsRemoveViewEvent(
analytics: Analytics
) {
sendEvent(
analytics = analytics,
eventName = EventsDictionary.setRemoveView,
props = Props.empty()
)
}
fun CoroutineScope.sendAnalyticsAddFilterEvent(
analytics: Analytics,
condition: DVFilterCondition
) {
sendEvent(
analytics = analytics,
eventName = EventsDictionary.setAddFilter,
props = Props(
mapOf(
EventsPropertiesKey.condition to condition.getPropName()
)
)
)
}
fun CoroutineScope.sendAnalyticsChangeFilterValueEvent(
analytics: Analytics,
condition: DVFilterCondition
) {
sendEvent(
analytics = analytics,
eventName = EventsDictionary.setChangeFilterValue,
props = Props(
mapOf(
EventsPropertiesKey.condition to condition.getPropName()
)
)
)
}
fun CoroutineScope.sendAnalyticsRemoveFilterEvent(
analytics: Analytics
) {
sendEvent(
analytics = analytics,
eventName = EventsDictionary.setRemoveFilter,
props = Props.empty()
)
}
fun CoroutineScope.sendAnalyticsAddSortEvent(
analytics: Analytics
) {
sendEvent(
analytics = analytics,
eventName = EventsDictionary.setAddSort,
props = Props.empty()
)
}
fun CoroutineScope.sendAnalyticsChangeSortValueEvent(
analytics: Analytics
) {
sendEvent(
analytics = analytics,
eventName = EventsDictionary.setChangeSortValue,
props = Props.empty()
)
}
fun CoroutineScope.sendAnalyticsRemoveSortEvent(
analytics: Analytics
) {
sendEvent(
analytics = analytics,
eventName = EventsDictionary.setRemoveSort,
props = Props.empty()
)
}
fun CoroutineScope.sendAnalyticsObjectCreateEvent(
analytics: Analytics,
objType: String?,
@ -968,4 +871,283 @@ fun CoroutineScope.sendAnalyticsMentionMenuEvent(
analytics = analytics,
eventName = EventsDictionary.mentionMenu
)
}
private fun ObjectState.DataView.getAnalyticsParams(): Pair<String?, String?> {
val block = blocks.firstOrNull { it.id == root }
val analyticsContext = block?.fields?.analyticsContext
val analyticsObjectId = if (analyticsContext != null) block.fields.analyticsOriginalId else null
return Pair(analyticsContext, analyticsObjectId)
}
fun CoroutineScope.logEvent(
state: ObjectState,
analytics: Analytics,
event: ObjectStateAnalyticsEvent,
startTime: Long? = null,
type: String? = null,
condition: DVFilterCondition? = null
) {
if (state !is ObjectState.DataView) return
val middleTime = System.currentTimeMillis()
val embedTypeDefault = "object"
val objectTypeDefault = when (state) {
is ObjectState.DataView.Collection -> "collection"
is ObjectState.DataView.Set -> "set"
}
val scope = this
val params = state.getAnalyticsParams()
val analyticsContext = params.first
val analyticsObjectId = params.second
when (event) {
ObjectStateAnalyticsEvent.OPEN_OBJECT -> {
when (state) {
is ObjectState.DataView.Collection -> scope.sendEvent(
analytics = analytics,
eventName = collectionScreenShow,
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId
)
)
is ObjectState.DataView.Set -> scope.sendEvent(
analytics = analytics,
eventName = setScreenShow,
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
embedType = embedTypeDefault
)
)
}
}
ObjectStateAnalyticsEvent.TURN_INTO_COLLECTION -> {
scope.sendEvent(
analytics = analytics,
eventName = turnIntoCollection,
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId
)
)
}
ObjectStateAnalyticsEvent.SELECT_QUERY -> {
scope.sendEvent(
analytics = analytics,
eventName = setSelectQuery,
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
type = type
)
)
}
ObjectStateAnalyticsEvent.ADD_VIEW -> {
scope.sendEvent(
analytics = analytics,
eventName = addView,
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
type = type,
embedType = embedTypeDefault,
objectType = objectTypeDefault
)
)
}
ObjectStateAnalyticsEvent.CHANGE_VIEW_TYPE -> {
scope.sendEvent(
analytics = analytics,
eventName = changeViewType,
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
type = type,
embedType = embedTypeDefault,
objectType = objectTypeDefault
)
)
}
ObjectStateAnalyticsEvent.REMOVE_VIEW -> {
scope.sendEvent(
analytics = analytics,
eventName = removeView,
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
embedType = embedTypeDefault,
objectType = objectTypeDefault
)
)
}
ObjectStateAnalyticsEvent.SWITCH_VIEW -> {
scope.sendEvent(
analytics = analytics,
eventName = switchView,
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
type = type,
embedType = embedTypeDefault,
objectType = objectTypeDefault
)
)
}
ObjectStateAnalyticsEvent.DUPLICATE_VIEW -> {
scope.sendEvent(
analytics = analytics,
eventName = duplicateView,
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
type = type,
embedType = embedTypeDefault,
objectType = objectTypeDefault
)
)
}
ObjectStateAnalyticsEvent.ADD_FILTER -> {
scope.sendEvent(
analytics = analytics,
eventName = addFilter,
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
embedType = embedTypeDefault,
objectType = objectTypeDefault,
condition = condition
)
)
}
ObjectStateAnalyticsEvent.CHANGE_FILTER_VALUE -> {
scope.sendEvent(
analytics = analytics,
eventName = changeFilterValue,
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
embedType = embedTypeDefault,
objectType = objectTypeDefault,
condition = condition
)
)
}
ObjectStateAnalyticsEvent.REMOVE_FILTER -> {
scope.sendEvent(
analytics = analytics,
eventName = removeFilter,
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
embedType = embedTypeDefault,
objectType = objectTypeDefault
)
)
}
ObjectStateAnalyticsEvent.ADD_SORT -> {
scope.sendEvent(
analytics = analytics,
eventName = addSort,
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
embedType = embedTypeDefault,
objectType = objectTypeDefault,
type = type
)
)
}
ObjectStateAnalyticsEvent.CHANGE_SORT_VALUE -> {
scope.sendEvent(
analytics = analytics,
eventName = changeSortValue,
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
embedType = embedTypeDefault,
objectType = objectTypeDefault,
type = type
)
)
}
ObjectStateAnalyticsEvent.REMOVE_SORT -> {
scope.sendEvent(
analytics = analytics,
eventName = removeSort,
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
embedType = embedTypeDefault,
objectType = objectTypeDefault
)
)
}
}
}
private fun buildProps(
analyticsContext: String? = null,
analyticsObjectId: String? = null,
embedType: String? = null,
type: String? = null,
objectType: String? = null,
condition: DVFilterCondition? = null
): Props {
return Props(
map = buildMap {
if (analyticsContext != null) put("context", analyticsContext)
if (analyticsObjectId != null) put("originalId", analyticsObjectId)
if (embedType != null) put("embedType", embedType)
if (type != null) put("type", type)
if (objectType != null) put("objectType", objectType)
if (condition != null) put("condition", condition.getPropName())
}
)
}
enum class ObjectStateAnalyticsEvent {
OPEN_OBJECT,
TURN_INTO_COLLECTION,
SELECT_QUERY,
ADD_VIEW,
CHANGE_VIEW_TYPE,
REMOVE_VIEW,
SWITCH_VIEW,
DUPLICATE_VIEW,
ADD_FILTER,
CHANGE_FILTER_VALUE,
REMOVE_FILTER,
ADD_SORT,
CHANGE_SORT_VALUE,
REMOVE_SORT
}

View file

@ -8,7 +8,9 @@ import com.anytypeio.anytype.core_models.DVViewerType
import com.anytypeio.anytype.core_models.Payload
import com.anytypeio.anytype.domain.dataview.interactor.AddDataViewViewer
import com.anytypeio.anytype.presentation.common.BaseViewModel
import com.anytypeio.anytype.presentation.extension.sendAnalyticsAddViewEvent
import com.anytypeio.anytype.presentation.extension.ObjectStateAnalyticsEvent
import com.anytypeio.anytype.presentation.extension.logEvent
import com.anytypeio.anytype.presentation.sets.state.ObjectState
import com.anytypeio.anytype.presentation.util.Dispatcher
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
@ -17,7 +19,8 @@ import timber.log.Timber
class CreateDataViewViewerViewModel(
private val addDataViewViewer: AddDataViewViewer,
private val dispatcher: Dispatcher<Payload>,
private val analytics: Analytics
private val analytics: Analytics,
private val objectState: MutableStateFlow<ObjectState>
) : BaseViewModel() {
val state = MutableStateFlow<ViewState>(ViewState.Init)
@ -28,12 +31,13 @@ class CreateDataViewViewerViewModel(
ctx: String,
target: String,
) {
val startTime = System.currentTimeMillis()
viewModelScope.launch {
addDataViewViewer(
AddDataViewViewer.Params(
ctx = ctx,
target = target,
name = name.ifEmpty { "Untitled" },
name = name,
type = dvType
)
).process(
@ -44,7 +48,13 @@ class CreateDataViewViewerViewModel(
},
success = {
dispatcher.send(it).also {
sendAnalyticsAddViewEvent(analytics, dvType.formattedName)
logEvent(
state = objectState.value,
analytics = analytics,
event = ObjectStateAnalyticsEvent.ADD_VIEW,
startTime = startTime,
type = dvType.formattedName
)
state.value = ViewState.Completed
}
}
@ -71,14 +81,16 @@ class CreateDataViewViewerViewModel(
class Factory(
private val addDataViewViewer: AddDataViewViewer,
private val dispatcher: Dispatcher<Payload>,
private val analytics: Analytics
private val analytics: Analytics,
private val objectState: MutableStateFlow<ObjectState>
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return CreateDataViewViewerViewModel(
addDataViewViewer = addDataViewViewer,
dispatcher = dispatcher,
analytics = analytics
analytics = analytics,
objectState = objectState
) as T
}
}

View file

@ -7,7 +7,8 @@ import com.anytypeio.anytype.analytics.base.Analytics
import com.anytypeio.anytype.core_models.*
import com.anytypeio.anytype.domain.dataview.interactor.*
import com.anytypeio.anytype.presentation.common.BaseViewModel
import com.anytypeio.anytype.presentation.extension.sendAnalyticsRemoveViewEvent
import com.anytypeio.anytype.presentation.extension.ObjectStateAnalyticsEvent
import com.anytypeio.anytype.presentation.extension.logEvent
import com.anytypeio.anytype.presentation.sets.state.ObjectState
import com.anytypeio.anytype.presentation.util.Dispatcher
import kotlinx.coroutines.flow.MutableSharedFlow
@ -57,6 +58,7 @@ class EditDataViewViewerViewModel(
}
fun onDuplicateClicked(ctx: Id, viewer: Id) {
val startTime = System.currentTimeMillis()
val state = objectState.value.dataViewState() ?: return
viewModelScope.launch {
duplicateDataViewViewer(
@ -71,7 +73,16 @@ class EditDataViewViewerViewModel(
_toasts.emit("Error while deleting viewer: ${e.localizedMessage}")
},
success = {
dispatcher.send(it).also { isDismissed.emit(true) }
dispatcher.send(it).also {
logEvent(
state = objectState.value,
analytics = analytics,
event = ObjectStateAnalyticsEvent.DUPLICATE_VIEW,
startTime = startTime,
type = viewerType.formattedName
)
isDismissed.emit(true)
}
}
)
}
@ -112,6 +123,7 @@ class EditDataViewViewerViewModel(
viewer: Id,
nextViewerId: Id?
) {
val startTime = System.currentTimeMillis()
viewModelScope.launch {
deleteDataViewViewer(
DeleteDataViewViewer.Params(
@ -126,8 +138,11 @@ class EditDataViewViewerViewModel(
},
success = { firstPayload ->
dispatcher.send(firstPayload)
sendAnalyticsRemoveViewEvent(
analytics = analytics
logEvent(
state = objectState.value,
analytics = analytics,
event = ObjectStateAnalyticsEvent.REMOVE_VIEW,
startTime = startTime
)
if (nextViewerId != null) {
objectSetSession.currentViewerId.value = nextViewerId
@ -149,6 +164,7 @@ class EditDataViewViewerViewModel(
}
fun onDoneClicked(ctx: Id, viewerId: Id) {
Timber.d("onDoneClicked, ctx:[$ctx], viewerId:[$viewerId], viewerType:[${viewerType.formattedName}], viewerName:[$viewerName]")
if (initialName != viewerName || initialType != viewerType) {
updateDVViewerType(ctx, viewerId, viewerType, viewerName)
} else {
@ -169,6 +185,7 @@ class EditDataViewViewerViewModel(
}
private fun updateDVViewerType(ctx: Id, viewerId: Id, type: DVViewerType, name: String) {
val startTime = System.currentTimeMillis()
val state = objectState.value.dataViewState() ?: return
val viewer = state.viewers.find { it.id == viewerId }
if (viewer != null) {
@ -182,9 +199,17 @@ class EditDataViewViewerViewModel(
)
).process(
success = { payload ->
dispatcher.send(payload)
isLoading.value = false
isDismissed.emit(true)
dispatcher.send(payload).also {
logEvent(
state = objectState.value,
analytics = analytics,
event = ObjectStateAnalyticsEvent.CHANGE_VIEW_TYPE,
startTime = startTime,
type = type.formattedName
)
isLoading.value = false
isDismissed.emit(true)
}
},
failure = {
isLoading.value = false

View file

@ -8,6 +8,8 @@ import com.anytypeio.anytype.core_models.DVViewerType
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.Payload
import com.anytypeio.anytype.presentation.common.BaseListViewModel
import com.anytypeio.anytype.presentation.extension.ObjectStateAnalyticsEvent
import com.anytypeio.anytype.presentation.extension.logEvent
import com.anytypeio.anytype.presentation.sets.ManageViewerViewModel.ViewerView
import com.anytypeio.anytype.presentation.sets.state.ObjectState
import com.anytypeio.anytype.presentation.util.Dispatcher
@ -75,9 +77,17 @@ class ManageViewerViewModel(
ctx: Id,
view: ViewerView
) {
val startTime = System.currentTimeMillis()
if (!isEditEnabled.value)
viewModelScope.launch {
session.currentViewerId.value = view.id
logEvent(
state = objectState.value,
analytics = analytics,
event = ObjectStateAnalyticsEvent.SWITCH_VIEW,
startTime = startTime,
type = view.type.formattedName
)
isDismissed.emit(true)
}
else

View file

@ -49,8 +49,9 @@ import com.anytypeio.anytype.presentation.editor.cover.CoverImageHashProvider
import com.anytypeio.anytype.presentation.editor.editor.listener.ListenerType
import com.anytypeio.anytype.presentation.editor.editor.model.BlockView
import com.anytypeio.anytype.presentation.editor.model.TextUpdate
import com.anytypeio.anytype.presentation.extension.ObjectStateAnalyticsEvent
import com.anytypeio.anytype.presentation.extension.logEvent
import com.anytypeio.anytype.presentation.extension.sendAnalyticsObjectCreateEvent
import com.anytypeio.anytype.presentation.extension.sendAnalyticsShowSetEvent
import com.anytypeio.anytype.presentation.navigation.AppNavigation
import com.anytypeio.anytype.presentation.navigation.SupportNavigation
import com.anytypeio.anytype.presentation.relations.ObjectSetConfig.DEFAULT_LIMIT
@ -148,8 +149,6 @@ class ObjectSetViewModel(
@Deprecated("could be deleted")
val isLoading = MutableStateFlow(false)
private var analyticsContext: String? = null
private var context: Id = ""
init {
@ -352,6 +351,7 @@ class ObjectSetViewModel(
private fun proceedWithOpeningCurrentObject(ctx: Id) {
Timber.d("proceedWithOpeningCurrentObject, ctx:[$ctx]")
val startTime = System.currentTimeMillis()
viewModelScope.launch {
openObjectSet(ctx).process(
success = { result ->
@ -373,8 +373,12 @@ class ObjectSetViewModel(
is Result.Success -> {
Timber.d("proceedWithOpeningCurrentObject, ctx:[$ctx] SUCCESS")
defaultPayloadConsumer(result.data)
setAnalyticsContext(result.data.events)
sendAnalyticsShowSetEvent(analytics, analyticsContext)
logEvent(
state = stateReducer.state.value,
analytics = analytics,
event = ObjectStateAnalyticsEvent.OPEN_OBJECT,
startTime = startTime
)
}
}
},
@ -459,16 +463,6 @@ class ObjectSetViewModel(
}
}
private fun setAnalyticsContext(events: List<Event>) {
if (events.isNotEmpty()) {
val event = events[0]
if (event is Event.Command.ShowObject) {
val block = event.blocks.firstOrNull { it.id == event.context }
analyticsContext = block?.fields?.analyticsContext
}
}
}
fun onStop() {
Timber.d("onStop, ")
jobs.cancel()
@ -1094,7 +1088,6 @@ class ObjectSetViewModel(
viewModelScope.sendEvent(
analytics = analytics,
eventName = EventsDictionary.createObjectNavBar,
props = Props(mapOf(EventsPropertiesKey.context to analyticsContext))
)
jobs += viewModelScope.launch {
createObject.execute(CreateObject.Param(type = null)).fold(
@ -1104,7 +1097,6 @@ class ObjectSetViewModel(
analytics = analytics,
objType = result.type,
route = EventsDictionary.Routes.objCreateSet,
context = analyticsContext
)
}
proceedWithOpeningObject(result.objectId)
@ -1152,24 +1144,43 @@ class ObjectSetViewModel(
fun onObjectSetQueryPicked(query: Id) {
Timber.d("onObjectSetQueryPicked, query:[$query]")
val startTime = System.currentTimeMillis()
viewModelScope.launch {
val params = SetQueryToObjectSet.Params(
ctx = context,
query = query
)
setQueryToObjectSet.execute(params).fold(
onSuccess = { payload -> defaultPayloadConsumer(payload) },
onSuccess = { payload ->
logEvent(
state = stateReducer.state.value,
analytics = analytics,
event = ObjectStateAnalyticsEvent.SELECT_QUERY,
type = query,
startTime = startTime
)
defaultPayloadConsumer(payload)
},
onFailure = { e -> Timber.e(e, "Error while setting Set query") }
)
}
}
private fun proceedWithConvertingToCollection() {
val startTime = System.currentTimeMillis()
val params = ConvertObjectToCollection.Params(ctx = context)
viewModelScope.launch {
objectToCollection.execute(params).fold(
onFailure = { error -> Timber.e(error, "Error convert object to collection") },
onSuccess = { setId -> proceedWithOpeningCollection(target = setId) }
onSuccess = { setId ->
logEvent(
state = stateReducer.state.value,
analytics = analytics,
event = ObjectStateAnalyticsEvent.TURN_INTO_COLLECTION,
startTime = startTime
)
proceedWithOpeningCollection(target = setId)
}
)
}
}

View file

@ -10,7 +10,8 @@ import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.Payload
import com.anytypeio.anytype.domain.dataview.interactor.UpdateDataViewViewer
import com.anytypeio.anytype.domain.objects.StoreOfRelations
import com.anytypeio.anytype.presentation.extension.sendAnalyticsAddSortEvent
import com.anytypeio.anytype.presentation.extension.ObjectStateAnalyticsEvent
import com.anytypeio.anytype.presentation.extension.logEvent
import com.anytypeio.anytype.presentation.relations.simpleRelations
import com.anytypeio.anytype.presentation.sets.model.SimpleRelationView
import com.anytypeio.anytype.presentation.sets.state.ObjectState
@ -35,6 +36,7 @@ class SelectSortRelationViewModel(
fun onRelationClicked(ctx: Id, relation: SimpleRelationView) {
val state = objectState.value.dataViewState() ?: return
val viewer = state.viewerById(session.currentViewerId.value) ?: return
val startTime = System.currentTimeMillis()
viewModelScope.launch {
val params = UpdateDataViewViewer.Params.Sort.Add(
ctx = ctx,
@ -48,7 +50,13 @@ class SelectSortRelationViewModel(
updateDataViewViewer(params).process(
success = {
dispatcher.send(it).also {
sendAnalyticsAddSortEvent(analytics)
logEvent(
state = objectState.value,
analytics = analytics,
event = ObjectStateAnalyticsEvent.ADD_SORT,
startTime = startTime,
type = DVSortType.ASC.formattedName
)
isDismissed.emit(true)
}
},

View file

@ -23,11 +23,11 @@ import com.anytypeio.anytype.domain.objects.StoreOfRelations
import com.anytypeio.anytype.domain.objects.options.GetOptions
import com.anytypeio.anytype.domain.search.SearchObjects
import com.anytypeio.anytype.domain.workspace.WorkspaceManager
import com.anytypeio.anytype.presentation.extension.ObjectStateAnalyticsEvent
import com.anytypeio.anytype.presentation.extension.checkboxFilterValue
import com.anytypeio.anytype.presentation.extension.hasValue
import com.anytypeio.anytype.presentation.extension.index
import com.anytypeio.anytype.presentation.extension.sendAnalyticsAddFilterEvent
import com.anytypeio.anytype.presentation.extension.sendAnalyticsChangeFilterValueEvent
import com.anytypeio.anytype.presentation.extension.logEvent
import com.anytypeio.anytype.presentation.extension.toConditionView
import com.anytypeio.anytype.presentation.extension.type
import com.anytypeio.anytype.presentation.mapper.toDomain
@ -50,6 +50,7 @@ import com.anytypeio.anytype.presentation.sets.model.Viewer
import com.anytypeio.anytype.presentation.sets.state.ObjectState
import com.anytypeio.anytype.presentation.sets.viewerById
import com.anytypeio.anytype.presentation.util.Dispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
@ -605,10 +606,6 @@ open class FilterViewModel(
value = value
)
)
sendAnalyticsChangeFilterValueEvent(
analytics = analytics,
condition = condition.toDomain()
)
}
}
@ -649,10 +646,6 @@ open class FilterViewModel(
value = value
)
)
sendAnalyticsChangeFilterValueEvent(
analytics = analytics,
condition = condition.toDomain()
)
}
ColumnView.Format.STATUS -> {
val value = filterValueListState.value.mapNotNull { view ->
@ -672,10 +665,6 @@ open class FilterViewModel(
value = value
)
)
sendAnalyticsChangeFilterValueEvent(
analytics = analytics,
condition = condition.toDomain()
)
}
ColumnView.Format.DATE -> {
val date = filterValueListState.value
@ -693,10 +682,6 @@ open class FilterViewModel(
value = date?.value?.toDouble()
)
)
sendAnalyticsChangeFilterValueEvent(
analytics = analytics,
condition = condition.toDomain()
)
}
ColumnView.Format.OBJECT -> {
val value = filterValueListState.value.mapNotNull { view ->
@ -716,10 +701,6 @@ open class FilterViewModel(
value = value
)
)
sendAnalyticsChangeFilterValueEvent(
analytics = analytics,
condition = condition.toDomain()
)
}
ColumnView.Format.CHECKBOX -> {
val value = filterValueListState.value.checkboxFilterValue()
@ -734,10 +715,6 @@ open class FilterViewModel(
value = value
)
)
sendAnalyticsChangeFilterValueEvent(
analytics = analytics,
condition = condition.toDomain()
)
}
else -> {
Timber.e("Wrong selected relation format : $format")
@ -753,6 +730,7 @@ open class FilterViewModel(
viewer: DVViewer,
updatedFilter: DVFilter
) {
val startTime = System.currentTimeMillis()
val params = UpdateDataViewViewer.Params.Filter.Replace(
ctx = ctx,
dv = target,
@ -761,7 +739,18 @@ open class FilterViewModel(
)
updateDataViewViewer(params).process(
failure = { Timber.e(it, "Error while creating filter") },
success = { dispatcher.send(it).also { isCompleted.emit(true) } }
success = {
dispatcher.send(it).also {
viewModelScope.logEvent(
state = objectState.value,
analytics = analytics,
event = ObjectStateAnalyticsEvent.CHANGE_FILTER_VALUE,
startTime = startTime,
condition = updatedFilter.condition
)
isCompleted.emit(true)
}
}
)
}
@ -774,6 +763,7 @@ open class FilterViewModel(
quickOption: DVFilterQuickOption = DVFilterQuickOption.EXACT_DATE,
value: Any? = null
) {
val startTime = System.currentTimeMillis()
val state = objectState.value.dataViewState() ?: return
val viewer = state.viewerById(session.currentViewerId.value) ?: return
val params = UpdateDataViewViewer.Params.Filter.Add(
@ -791,8 +781,11 @@ open class FilterViewModel(
failure = { Timber.e(it, "Error while creating filter") },
success = {
dispatcher.send(it).also {
viewModelScope.sendAnalyticsAddFilterEvent(
viewModelScope.logEvent(
state = objectState.value,
analytics = analytics,
event = ObjectStateAnalyticsEvent.ADD_FILTER,
startTime = startTime,
condition = condition
)
isCompleted.emit(true)

View file

@ -9,7 +9,8 @@ import com.anytypeio.anytype.domain.dataview.interactor.UpdateDataViewViewer
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.objects.StoreOfRelations
import com.anytypeio.anytype.presentation.common.BaseListViewModel
import com.anytypeio.anytype.presentation.extension.sendAnalyticsRemoveFilterEvent
import com.anytypeio.anytype.presentation.extension.ObjectStateAnalyticsEvent
import com.anytypeio.anytype.presentation.extension.logEvent
import com.anytypeio.anytype.presentation.extension.toView
import com.anytypeio.anytype.presentation.relations.filterExpression
import com.anytypeio.anytype.presentation.sets.ObjectSetDatabase
@ -158,6 +159,7 @@ class ViewerFilterViewModel(
}
private fun onRemoveFilterClicked(ctx: Id, filterIndex: Int) {
val startTime = System.currentTimeMillis()
val state = objectState.value.dataViewState() ?: return
val viewer = state.viewerById(session.currentViewerId.value) ?: return
val filter = viewer.filters.getOrNull(filterIndex)
@ -173,10 +175,18 @@ class ViewerFilterViewModel(
ids = listOf(filter.id),
)
updateDataViewViewer(params).process(
success = { dispatcher.send(it) },
success = {
dispatcher.send(it).also {
logEvent(
state = objectState.value,
analytics = analytics,
event = ObjectStateAnalyticsEvent.REMOVE_FILTER,
startTime = startTime
)
}
},
failure = { Timber.e("Error while reset all filters") }
)
sendAnalyticsRemoveFilterEvent(analytics)
}
}

View file

@ -8,7 +8,8 @@ import com.anytypeio.anytype.core_models.*
import com.anytypeio.anytype.domain.dataview.interactor.UpdateDataViewViewer
import com.anytypeio.anytype.domain.objects.StoreOfRelations
import com.anytypeio.anytype.presentation.common.BaseViewModel
import com.anytypeio.anytype.presentation.extension.sendAnalyticsChangeSortValueEvent
import com.anytypeio.anytype.presentation.extension.ObjectStateAnalyticsEvent
import com.anytypeio.anytype.presentation.extension.logEvent
import com.anytypeio.anytype.presentation.sets.ObjectSetSession
import com.anytypeio.anytype.presentation.sets.dataViewState
import com.anytypeio.anytype.presentation.sets.state.ObjectState
@ -92,6 +93,7 @@ class ModifyViewerSortViewModel(
Timber.e("Couldn't find sort in view:[$viewer] by sortId:[$sortId]")
return
}
val startTime = System.currentTimeMillis()
viewModelScope.launch {
val params = UpdateDataViewViewer.Params.Sort.Replace(
ctx = ctx,
@ -102,7 +104,13 @@ class ModifyViewerSortViewModel(
updateDataViewViewer(params).process(
success = {
dispatcher.send(it).also {
sendAnalyticsChangeSortValueEvent(analytics)
logEvent(
state = objectState.value,
analytics = analytics,
event = ObjectStateAnalyticsEvent.CHANGE_SORT_VALUE,
startTime = startTime,
type = type.formattedName
)
isDismissed.emit(true)
}
},

View file

@ -9,7 +9,8 @@ import com.anytypeio.anytype.core_utils.diff.DefaultObjectDiffIdentifier
import com.anytypeio.anytype.domain.dataview.interactor.UpdateDataViewViewer
import com.anytypeio.anytype.domain.objects.StoreOfRelations
import com.anytypeio.anytype.presentation.common.BaseListViewModel
import com.anytypeio.anytype.presentation.extension.sendAnalyticsRemoveSortEvent
import com.anytypeio.anytype.presentation.extension.ObjectStateAnalyticsEvent
import com.anytypeio.anytype.presentation.extension.logEvent
import com.anytypeio.anytype.presentation.extension.toView
import com.anytypeio.anytype.presentation.sets.ObjectSetSession
import com.anytypeio.anytype.presentation.sets.dataViewState
@ -87,6 +88,7 @@ class ViewerSortViewModel(
fun onRemoveViewerSortClicked(ctx: Id, view: ViewerSortView) {
val state = objectState.value.dataViewState() ?: return
val viewer = state.viewerById(session.currentViewerId.value) ?: return
val startTime = System.currentTimeMillis()
viewModelScope.launch {
val params = UpdateDataViewViewer.Params.Sort.Remove(
ctx = ctx,
@ -96,9 +98,17 @@ class ViewerSortViewModel(
)
updateDataViewViewer(params).process(
failure = { Timber.e(it, "Error while removing a sort") },
success = { dispatcher.send(it) }
success = {
dispatcher.send(it).also {
logEvent(
state = objectState.value,
analytics = analytics,
event = ObjectStateAnalyticsEvent.REMOVE_SORT,
startTime = startTime,
)
}
}
)
sendAnalyticsRemoveSortEvent(analytics)
}
}

View file

@ -115,12 +115,14 @@ class DefaultObjectStateReducer : ObjectStateReducer {
private fun handleShowObject(event: Command.ShowObject): ObjectState {
val objectState = when (val layout = event.details.details[event.root]?.layout?.toInt()) {
ObjectType.Layout.COLLECTION.code -> ObjectState.DataView.Collection(
root = event.root,
blocks = event.blocks,
details = event.details.details,
objectRestrictions = event.objectRestrictions,
dataViewRestrictions = event.dataViewRestrictions
)
ObjectType.Layout.SET.code -> ObjectState.DataView.Set(
root = event.root,
blocks = event.blocks,
details = event.details.details,
objectRestrictions = event.objectRestrictions,

View file

@ -12,6 +12,7 @@ sealed class ObjectState {
abstract val isInitialized: Boolean
sealed class DataView : ObjectState() {
abstract val root: Id
abstract val blocks: List<Block>
abstract val details: Map<Id, Block.Fields>
abstract val objectRestrictions: List<ObjectRestriction>
@ -22,6 +23,7 @@ sealed class ObjectState {
abstract val viewers: List<DVViewer>
data class Set(
override val root: Id,
override val blocks: List<Block> = emptyList(),
override val details: Map<Id, Block.Fields> = emptyMap(),
override val objectRestrictions: List<ObjectRestriction> = emptyList(),
@ -35,6 +37,7 @@ sealed class ObjectState {
}
data class Collection(
override val root: Id,
override val blocks: List<Block> = emptyList(),
override val details: Map<Id, Block.Fields> = emptyMap(),
override val objectRestrictions: List<ObjectRestriction> = emptyList(),

View file

@ -190,6 +190,7 @@ class CollectionAddRelationTest : ObjectSetViewModelTestSetup() {
assertEquals(
expected = ObjectState.DataView.Collection(
root = root,
blocks = listOf(
objectCollection.header,
objectCollection.title,
@ -267,6 +268,7 @@ class CollectionAddRelationTest : ObjectSetViewModelTestSetup() {
assertEquals(
expected = ObjectState.DataView.Collection(
root = root,
blocks = listOf(
objectCollection.header,
objectCollection.title,

View file

@ -37,6 +37,7 @@ object MockObjectSetFactory {
)
fun makeDefaultSetObjectState(
root: String = MockDataFactory.randomUuid(),
viewerId: String? = null,
dataViewId: String? = null,
viewerRelations: List<Block.Content.DataView.Viewer.ViewerRelation>? = null,
@ -84,6 +85,6 @@ object MockObjectSetFactory {
val blocks = listOf(title, dataView)
return ObjectState.DataView.Set(blocks = blocks)
return ObjectState.DataView.Set(root = root, blocks = blocks)
}
}

View file

@ -180,7 +180,9 @@ class ObjectSetReducerTest {
)
val expected = ObjectState.DataView.Set(
blocks = listOf(title, expectedDataView), details = details.details
root = context,
blocks = listOf(title, expectedDataView),
details = details.details
)
assertEquals(expected, stateSetView)
@ -314,6 +316,7 @@ class ObjectSetReducerTest {
)
val expected = ObjectState.DataView.Set(
root = context,
blocks = listOf(title, expectedDataView),
details = details.details
)
@ -447,7 +450,9 @@ class ObjectSetReducerTest {
)
val expected = ObjectState.DataView.Set(
blocks = listOf(title, expectedDataView), details = details.details
root = context,
blocks = listOf(title, expectedDataView),
details = details.details
)
assertEquals(expected, stateUpdateView)
@ -557,6 +562,7 @@ class ObjectSetReducerTest {
)
val expected = ObjectState.DataView.Set(
root = context,
blocks = listOf(title, expectedDataView),
details = details.details
)
@ -663,7 +669,9 @@ class ObjectSetReducerTest {
)
val expected = ObjectState.DataView.Set(
blocks = listOf(title, expectedDataView), details = details.details
root = context,
blocks = listOf(title, expectedDataView),
details = details.details
)
assertEquals(expected, stateUpdateView)
@ -759,7 +767,9 @@ class ObjectSetReducerTest {
)
val expected = ObjectState.DataView.Set(
blocks = listOf(title, expectedDataView), details = details.details
root = context,
blocks = listOf(title, expectedDataView),
details = details.details
)
assertEquals(expected, stateUpdateView)
@ -836,7 +846,9 @@ class ObjectSetReducerTest {
)
val expected = ObjectState.DataView.Set(
blocks = listOf(title, expectedDataView), details = details.details
root = context,
blocks = listOf(title, expectedDataView),
details = details.details
)
assertEquals(expected, stateDeleteRelation)

View file

@ -106,6 +106,7 @@ class ObjectSetViewerDeleteTest {
val objectSetState = MutableStateFlow(
ObjectState.DataView.Set(
root = ctx,
blocks = listOf(
header,
title,
@ -177,6 +178,7 @@ class ObjectSetViewerDeleteTest {
val objectSetState = MutableStateFlow(
ObjectState.DataView.Set(
root = ctx,
blocks = listOf(
header,
title,
@ -248,6 +250,7 @@ class ObjectSetViewerDeleteTest {
val objectSetState = MutableStateFlow(
ObjectState.DataView.Set(
root = ctx,
blocks = listOf(
header,
title,