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

DROID-1889 Analytics | CreateObject event (#760)

This commit is contained in:
Konstantin Ivanov 2024-01-11 12:54:54 +01:00 committed by GitHub
parent 5c7fe84a8f
commit eb87b1fa93
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 171 additions and 338 deletions

View file

@ -24,11 +24,6 @@ interface Analytics {
fun observeEvents(): Flow<EventAnalytics>
fun observeUserProperties(): Flow<UserProperty>
fun setContext(ctx: String?)
fun getContext(): String?
fun setOriginalId(originalId: String?)
fun getOriginalId(): String?
}
fun CoroutineScope.sendEvent(

View file

@ -12,19 +12,4 @@ class DefaultAnalytics : Analytics {
override suspend fun updateUserProperty(property: UserProperty) = userProps.emit(property)
override fun observeEvents(): Flow<EventAnalytics> = events
override fun observeUserProperties(): Flow<UserProperty> = userProps
private var analyticsContext: String? = null
private var analyticsOriginalId: String? = null
override fun setContext(ctx: String?) {
analyticsContext = ctx
}
override fun getContext(): String? = analyticsContext
override fun setOriginalId(originalId: String?) {
analyticsOriginalId = originalId
}
override fun getOriginalId(): String? = analyticsOriginalId
}

View file

@ -42,16 +42,12 @@ object EventsDictionary {
const val loginScreenShow = "ScreenLogin"
const val searchScreenShow = "ScreenSearch"
const val createObjectCollectionsNavBar = "CreateObjectCollectionsNavBar"
const val signupScreenShow = "ScreenAuthRegistration"
const val invitationScreenShow = "ScreenAuthInvitation"
const val aboutAnalyticsScreenShow = "ScreenDisclaimer"
const val deletionWarningShow = "ShowDeletionWarning"
const val keychainPhraseScreenShow = "ScreenKeychain"
const val relationsScreenShow = "ScreenObjectRelation"
const val personalisationSettingsShow = "ScreenSettingsPersonal"
const val wallpaperScreenShow = "ScreenSettingsWallpaper"
const val accountDataSettingsShow = "ScreenSettingsAccount"
const val aboutScreenShow = "ScreenSettingsAbout"
const val appearanceScreenShow = "ScreenSettingsAppearance"
const val screenSettingsStorage = "ScreenSettingsStorageIndex"
const val screenSettingsStorageManage = "ScreenSettingsStorageManager"
@ -223,9 +219,10 @@ object EventsDictionary {
const val objCreateSet = "Set"
const val objCreateHome = "Home"
const val objCreateCollection = "Collection"
const val objCreateLibrary = "Library"
const val objCreateMention = "Mention"
const val objPowerTool = "Powertool"
const val objTurnInto = "TurnInto"
const val objLink = "Link"
const val screenSettings = "ScreenSettings"
const val settings = "Settings"
const val screenDeletion = "ScreenDeletion"
@ -287,7 +284,6 @@ object EventsPropertiesKey {
const val relationKey = "relationKey"
const val condition = "condition"
const val align = "align"
const val originalId = "originalId"
const val view = "view"
const val step = "step"
}

View file

@ -14,6 +14,7 @@ import com.anytypeio.anytype.domain.launch.GetDefaultObjectType
import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.`object`.SetObjectDetails
import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.search.SubscriptionEventChannel
import com.anytypeio.anytype.domain.templates.GetTemplates
@ -216,4 +217,5 @@ interface LibraryDependencies : ComponentDependencies {
fun config(): ConfigStorage
fun logger(): Logger
fun container(): StorelessSubscriptionContainer
fun storeOfTypes (): StoreOfObjectTypes
}

View file

@ -7,9 +7,7 @@ import androidx.lifecycle.viewModelScope
import com.anytypeio.anytype.analytics.base.Analytics
import com.anytypeio.anytype.analytics.base.EventsDictionary
import com.anytypeio.anytype.analytics.base.EventsDictionary.searchScreenShow
import com.anytypeio.anytype.analytics.base.EventsPropertiesKey
import com.anytypeio.anytype.analytics.base.sendEvent
import com.anytypeio.anytype.analytics.props.Props
import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.Block.Content
import com.anytypeio.anytype.core_models.Block.Prototype
@ -398,9 +396,6 @@ class EditorViewModel(
var currentMediaUploadDescription: Media.Upload.Description? = null
private set
private var analyticsContext: String? = null
private var analyticsOriginalId: String? = null
override val navigation = MutableLiveData<EventWrapper<AppNavigation.Command>>()
override val commands = MutableLiveData<EventWrapper<Command>>()
@ -1038,16 +1033,11 @@ class EditorViewModel(
if (event.details.details[context]?.type?.contains(ObjectTypeIds.FILE) == true) {
isSyncStatusVisible.value = false
}
val block = event.blocks.firstOrNull { it.id == context }
analytics.setContext(block?.fields?.analyticsContext)
analytics.setOriginalId(block?.fields?.analyticsOriginalId)
analyticsContext = block?.fields?.analyticsContext
if (analyticsContext != null) {
analyticsOriginalId = block?.fields?.analyticsOriginalId
}
sendAnalyticsObjectShowEvent(
analytics = analytics,
startTime = startTime
startTime = startTime,
details = orchestrator.stores.details.current().details,
ctx = context,
)
}
}
@ -1166,7 +1156,7 @@ class EditorViewModel(
fun onBackButtonPressed() {
Timber.d("onBackButtonPressed, ")
viewModelScope.sendAnalyticsGoBackEvent(analytics, analyticsContext)
viewModelScope.sendAnalyticsGoBackEvent(analytics)
proceedWithExitingBack()
}
@ -1410,7 +1400,7 @@ class EditorViewModel(
range = range,
marks = emptyList()
)
viewModelScope.sendAnalyticsSetDescriptionEvent(analytics, analyticsContext)
viewModelScope.sendAnalyticsSetDescriptionEvent(analytics)
}
private fun proceedWithEnterEvent(
@ -1953,7 +1943,6 @@ class EditorViewModel(
)
sendAnalyticsBlockAlignEvent(
analytics = analytics,
context = analyticsContext,
count = targets.size,
align = alignment
)
@ -1975,8 +1964,7 @@ class EditorViewModel(
}
viewModelScope.sendAnalyticsUpdateTextMarkupEvent(
analytics = analytics,
type = Content.Text.Mark.Type.TEXT_COLOR,
context = analyticsContext
type = Content.Text.Mark.Type.TEXT_COLOR
)
}
@ -1993,8 +1981,7 @@ class EditorViewModel(
viewModelScope.sendAnalyticsBlockBackgroundEvent(
analytics = analytics,
count = ids.size,
color = color,
context = analyticsContext
color = color
)
}
@ -2029,8 +2016,7 @@ class EditorViewModel(
)
sendAnalyticsUpdateTextMarkupEvent(
analytics = analytics,
type = type,
context = analyticsContext
type = type
)
}
}
@ -2178,8 +2164,7 @@ class EditorViewModel(
viewModelScope.launch { renderCommand.send(Unit) }
viewModelScope.sendAnalyticsSearchWordsEvent(
analytics = analytics,
length = query.length,
context = analyticsContext
length = query.length
)
}
is SearchInDocEvent.Next -> {
@ -2761,8 +2746,7 @@ class EditorViewModel(
Intent.Text.TurnInto(
context = context,
targets = targets,
style = style,
analyticsContext = analyticsContext
style = style
)
)
}
@ -3196,10 +3180,9 @@ class EditorViewModel(
sendAnalyticsCreateLink(analytics)
sendAnalyticsObjectCreateEvent(
analytics = analytics,
type = objectTypeView.key,
storeOfObjectTypes = storeOfObjectTypes,
route = EventsDictionary.Routes.objPowerTool,
startTime = startTime
startTime = startTime,
objType = storeOfObjectTypes.getByKey(objectTypeView.key)
)
proceedWithOpeningObject(result.objectId)
}
@ -3241,10 +3224,10 @@ class EditorViewModel(
onSuccess = { result ->
sendAnalyticsObjectCreateEvent(
analytics = analytics,
type = result.typeKey.key,
storeOfObjectTypes = storeOfObjectTypes,
route = EventsDictionary.Routes.objPowerTool,
startTime = startTime
route = EventsDictionary.Routes.navigation,
startTime = startTime,
objType = objType ?: storeOfObjectTypes.getByKey(result.typeKey.key),
view = EventsDictionary.View.viewNavbar
)
proceedWithCloseCurrentAndOpenObject(result.obj)
},
@ -3525,8 +3508,7 @@ class EditorViewModel(
)
sendAnalyticsBlockReorder(
analytics = analytics,
count = blocks.size,
context = analyticsContext
count = blocks.size
)
}
} else {
@ -4201,8 +4183,7 @@ class EditorViewModel(
viewModelScope.sendEvent(
analytics = analytics,
eventName = searchScreenShow,
props = Props(mapOf(EventsPropertiesKey.context to analyticsContext))
eventName = searchScreenShow
)
navigation.postValue(EventWrapper(AppNavigation.Command.OpenPageSearch))
}
@ -4303,8 +4284,7 @@ class EditorViewModel(
success = {
dispatcher.send(it)
sendAnalyticsRelationValueEvent(
analytics = analytics,
context = analyticsContext
analytics = analytics
)
},
failure = {
@ -4747,8 +4727,7 @@ class EditorViewModel(
)
sendAnalyticsUpdateTextMarkupEvent(
analytics = analytics,
type = type,
context = analyticsContext
type = type
)
}
}
@ -5071,15 +5050,13 @@ class EditorViewModel(
is SlashItem.Color.Background -> {
sendAnalyticsBlockBackgroundEvent(
analytics = analytics,
color = item.themeColor.code,
context = analyticsContext
color = item.themeColor.code
)
}
is SlashItem.Color.Text -> {
sendAnalyticsUpdateTextMarkupEvent(
analytics = analytics,
type = Content.Text.Mark.Type.TEXT_COLOR,
context = analyticsContext
type = Content.Text.Mark.Type.TEXT_COLOR
)
}
}
@ -5471,7 +5448,7 @@ class EditorViewModel(
text = event.text,
range = event.range
)
viewModelScope.sendAnalyticsSetTitleEvent(analytics, analyticsContext)
viewModelScope.sendAnalyticsSetTitleEvent(analytics)
}
}
}
@ -5833,10 +5810,9 @@ class EditorViewModel(
)
sendAnalyticsObjectCreateEvent(
analytics = analytics,
type = typeKey.key,
storeOfObjectTypes = storeOfObjectTypes,
route = EventsDictionary.Routes.objCreateMention,
startTime = startTime
startTime = startTime,
objType = storeOfObjectTypes.getByKey(typeKey.key)
)
}
)
@ -5848,8 +5824,7 @@ class EditorViewModel(
viewModelScope.sendAnalyticsSearchResultEvent(
analytics = analytics,
pos = pos,
length = mentionTrigger.length - 1,
context = analyticsContext
length = mentionTrigger.length - 1
)
onCreateMentionInText(id = mention.id, name = mention.name, mentionTrigger = mentionTrigger)
}
@ -5989,8 +5964,7 @@ class EditorViewModel(
)
sendAnalyticsBlockReorder(
analytics = analytics,
count = 1,
context = analyticsContext
count = 1
)
}
}
@ -6159,7 +6133,6 @@ class EditorViewModel(
createObjectAddProceedToAddToTextAsLink(
name = name,
typeKey = response.type,
typeId = response.id,
templateId = response.defaultTemplate
)
}
@ -6191,7 +6164,6 @@ class EditorViewModel(
private suspend fun createObjectAddProceedToAddToTextAsLink(
name: String,
typeKey: TypeKey,
typeId: TypeId?,
templateId: Id?
) {
val startTime = System.currentTimeMillis()
@ -6206,10 +6178,9 @@ class EditorViewModel(
proceedToAddObjectToTextAsLink(id = result.id)
viewModelScope.sendAnalyticsObjectCreateEvent(
analytics = analytics,
type = typeKey.key,
storeOfObjectTypes = storeOfObjectTypes,
route = EventsDictionary.Routes.objTurnInto,
startTime = startTime
route = EventsDictionary.Routes.objLink,
startTime = startTime,
objType = storeOfObjectTypes.getByKey(typeKey.key)
)
}
)

View file

@ -5,7 +5,6 @@ import android.os.Parcelable
import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.Hash
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.Key
import com.anytypeio.anytype.core_models.Position
import com.anytypeio.anytype.core_utils.ext.Mimetype
import kotlinx.parcelize.Parcelize
@ -136,8 +135,7 @@ sealed class Intent {
class TurnInto(
val context: Id,
val targets: List<Id>,
val style: Block.Content.Text.Style,
val analyticsContext: String?
val style: Block.Content.Text.Style
) : Text()
class UpdateCheckbox(

View file

@ -325,8 +325,7 @@ class Orchestrator(
success = { payload ->
analytics.sendAnalyticsChangeTextBlockStyleEvent(
style = intent.style,
count = intent.targets.size,
analyticsContext = intent.analyticsContext
count = intent.targets.size
)
proxies.payloads.send(payload)
}

View file

@ -34,14 +34,11 @@ import com.anytypeio.anytype.analytics.base.sendEvent
import com.anytypeio.anytype.analytics.event.EventAnalytics
import com.anytypeio.anytype.analytics.features.WidgetAnalytics
import com.anytypeio.anytype.analytics.props.Props
import com.anytypeio.anytype.analytics.props.Props.Companion.OBJ_LAYOUT_NONE
import com.anytypeio.anytype.analytics.props.Props.Companion.OBJ_TYPE_CUSTOM
import com.anytypeio.anytype.analytics.props.UserProperty
import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.DVFilterCondition
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.Key
import com.anytypeio.anytype.core_models.ObjectType
import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_models.Relation
import com.anytypeio.anytype.core_models.TextStyle
@ -50,14 +47,12 @@ import com.anytypeio.anytype.core_models.WidgetLayout
import com.anytypeio.anytype.core_models.ext.mapToObjectWrapperType
import com.anytypeio.anytype.core_utils.ext.Mimetype
import com.anytypeio.anytype.domain.config.ConfigStorage
import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
import com.anytypeio.anytype.presentation.editor.editor.Markup
import com.anytypeio.anytype.presentation.sets.isChangingDefaultTypeAvailable
import com.anytypeio.anytype.presentation.sets.state.ObjectState
import com.anytypeio.anytype.presentation.widgets.Widget
import com.anytypeio.anytype.presentation.widgets.source.BundledWidgetSourceView
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
fun Block.Prototype.getAnalyticsEvent(
eventName: String,
@ -232,50 +227,31 @@ fun Relation.Format.getPropName() = when (this) {
Relation.Format.UNDEFINED -> "undefined"
}
/**
* ScreenObject - event code
* type - ObjectType
*/
fun CoroutineScope.sendAnalyticsObjectShowEvent(
ctx: Id,
details: Map<Id, Block.Fields>?,
analytics: Analytics,
startTime: Long
) {
val objType = getAnalyticsObjectType(
details = details,
ctx = ctx
)
val props = Props(
mapOf(
EventsPropertiesKey.objectType to objType,
)
)
sendEvent(
analytics = analytics,
eventName = objectScreenShow,
props = propsForObjectEvents(),
props = props,
startTime = startTime,
middleTime = System.currentTimeMillis(),
renderTime = System.currentTimeMillis()
)
}
private fun propsForObjectEvents(
layoutCode: Double? = null,
route: String? = null,
context: String? = null,
originalId: String? = null,
sourceObject: String? = null,
view: String? = null
): Props {
val objType = sourceObject ?: OBJ_TYPE_CUSTOM
val layout = layoutCode?.toInt()?.let { code ->
ObjectType.Layout.values().find { layout ->
layout.code == code
}
}?.name ?: OBJ_LAYOUT_NONE
return Props(
mapOf(
EventsPropertiesKey.objectType to objType,
EventsPropertiesKey.layout to layout,
EventsPropertiesKey.route to route,
EventsPropertiesKey.context to context,
EventsPropertiesKey.originalId to originalId,
EventsPropertiesKey.view to view
)
)
}
/**
* SearchResult - event code
* index - number of position of chosen item, started from 1
@ -284,8 +260,7 @@ private fun propsForObjectEvents(
fun CoroutineScope.sendAnalyticsSearchResultEvent(
analytics: Analytics,
pos: Int,
length: Int,
context: String? = null
length: Int
) {
sendEvent(
analytics = analytics,
@ -293,8 +268,7 @@ fun CoroutineScope.sendAnalyticsSearchResultEvent(
props = Props(
mapOf(
EventsPropertiesKey.index to pos,
EventsPropertiesKey.length to length,
EventsPropertiesKey.context to context
EventsPropertiesKey.length to length
)
)
)
@ -302,16 +276,14 @@ fun CoroutineScope.sendAnalyticsSearchResultEvent(
fun CoroutineScope.sendAnalyticsSearchWordsEvent(
analytics: Analytics,
length: Int,
context: String? = null
length: Int
) {
sendEvent(
analytics = analytics,
eventName = EventsDictionary.searchWords,
props = Props(
mapOf(
EventsPropertiesKey.length to length,
EventsPropertiesKey.context to context
EventsPropertiesKey.length to length
)
)
)
@ -359,8 +331,6 @@ fun CoroutineScope.sendAnalyticsBackLinkAddEvent(
) {
val props = Props(
buildMap {
analytics.getContext()?.let { put("context", it) }
analytics.getOriginalId()?.let { put("originalId", it) }
put("linkType", "Object")
}
)
@ -379,8 +349,6 @@ fun CoroutineScope.sendAnalyticsAddToCollectionEvent(
) {
val props = Props(
buildMap {
analytics.getContext()?.let { put("context", it) }
analytics.getOriginalId()?.let { put("originalId", it) }
put("linkType", "Collection")
}
)
@ -409,7 +377,10 @@ fun CoroutineScope.sendAnalyticsDuplicateEvent(
startTime: Long,
count: Int = 1
) {
val objType = if (details != null) getAnalyticsObjectType(details, ctx) else null
val objType = getAnalyticsObjectType(
details = details,
ctx = ctx
)
val props = Props(
mapOf(
EventsPropertiesKey.count to count,
@ -497,8 +468,7 @@ suspend fun Analytics.sendAnalyticsUpdateTextMarkupEvent(type: Block.Content.Tex
suspend fun Analytics.sendAnalyticsChangeTextBlockStyleEvent(
style: Block.Content.Text.Style,
count: Int,
analyticsContext: String?
count: Int
) {
val event = EventAnalytics.Anytype(
name = EventsDictionary.blockChangeBlockStyle,
@ -506,8 +476,7 @@ suspend fun Analytics.sendAnalyticsChangeTextBlockStyleEvent(
mapOf(
EventsPropertiesKey.type to "Text",
EventsPropertiesKey.style to style.getStyleName(),
EventsPropertiesKey.count to count,
EventsPropertiesKey.context to analyticsContext
EventsPropertiesKey.count to count
)
)
)
@ -582,7 +551,6 @@ suspend fun Analytics.sendAnalyticsRedoEvent() {
fun CoroutineScope.sendAnalyticsBlockAlignEvent(
analytics: Analytics,
context: String?,
count: Int,
align: Block.Align
) {
@ -592,30 +560,12 @@ fun CoroutineScope.sendAnalyticsBlockAlignEvent(
props = Props(
mapOf(
EventsPropertiesKey.align to align.getPropName(),
EventsPropertiesKey.context to context,
EventsPropertiesKey.count to count
)
)
)
}
fun CoroutineScope.sendAnalyticsObjectTypeChangeEvent(
analytics: Analytics,
objType: ObjectWrapper.Type?,
startTime: Long
) {
sendEvent(
analytics = analytics,
eventName = EventsDictionary.objectTypeChanged,
props = propsForObjectEvents(
context = analytics.getContext(),
originalId = analytics.getOriginalId(),
sourceObject = objType?.sourceObject
),
startTime = startTime
)
}
fun CoroutineScope.sendAnalyticsObjectTypeSelectOrChangeEvent(
analytics: Analytics,
startTime: Long,
@ -688,16 +638,14 @@ fun CoroutineScope.sendAnalyticsAddRelationEvent(
fun CoroutineScope.sendAnalyticsRelationValueEvent(
analytics: Analytics,
type: String = "",
context: String? = null
type: String = ""
) {
sendEvent(
analytics = analytics,
eventName = EventsDictionary.relationChangeValue,
props = Props(
mapOf(
EventsPropertiesKey.type to type,
EventsPropertiesKey.context to context
EventsPropertiesKey.type to type
)
)
)
@ -714,61 +662,59 @@ fun CoroutineScope.sendAnalyticsRelationDeleteEvent(
fun CoroutineScope.sendAnalyticsObjectCreateEvent(
analytics: Analytics,
storeOfObjectTypes: StoreOfObjectTypes,
type: Key?,
route: String,
startTime: Long? = null,
view: String? = null
view: String? = null,
objType: String?
) {
this.launch {
val objType = type?.let { storeOfObjectTypes.getByKey(it) }
analytics.sendEvent(
eventName = objectCreate,
props = propsForObjectEvents(
route = route,
sourceObject = objType?.sourceObject,
view = view
),
startTime = startTime,
middleTime = System.currentTimeMillis()
val props = Props(
mapOf(
EventsPropertiesKey.objectType to objType,
EventsPropertiesKey.route to route,
EventsPropertiesKey.view to view
)
}
)
sendEvent(
analytics = analytics,
eventName = objectCreate,
props = props,
startTime = startTime,
middleTime = System.currentTimeMillis()
)
}
fun CoroutineScope.sendAnalyticsObjectCreateEvent(
analytics: Analytics,
type: Key?,
route: String,
startTime: Long? = null,
view: String? = null
view: String? = null,
objType: ObjectWrapper.Type?
) {
launch {
analytics.sendEvent(
eventName = objectCreate,
props = propsForObjectEvents(
route = route,
sourceObject = type,
view = view
),
startTime = startTime,
middleTime = System.currentTimeMillis()
val objTypeParam = if (objType == null) null
else objType.sourceObject ?: OBJ_TYPE_CUSTOM
val props = Props(
mapOf(
EventsPropertiesKey.objectType to objTypeParam,
EventsPropertiesKey.route to route,
EventsPropertiesKey.view to view
)
}
)
sendEvent(
analytics = analytics,
eventName = objectCreate,
props = props,
startTime = startTime,
middleTime = System.currentTimeMillis()
)
}
fun CoroutineScope.sendAnalyticsSetTitleEvent(
analytics: Analytics,
context: String? = null
analytics: Analytics
) {
val props = if (context != null) {
Props(mapOf(EventsPropertiesKey.context to context))
} else {
Props.empty()
}
sendEvent(
analytics = analytics,
eventName = EventsDictionary.objectSetTitle,
props = props
props = Props.empty()
)
}
@ -784,33 +730,24 @@ fun CoroutineScope.sendAnalyticsBlockMoveToEvent(
}
fun CoroutineScope.sendAnalyticsSetDescriptionEvent(
analytics: Analytics,
context: String? = null
analytics: Analytics
) {
val props = if (context != null) {
Props(mapOf(EventsPropertiesKey.context to context))
} else {
Props.empty()
}
sendEvent(
analytics = analytics,
eventName = EventsDictionary.objectSetDescription,
props = props
eventName = EventsDictionary.objectSetDescription
)
}
fun CoroutineScope.sendAnalyticsUpdateTextMarkupEvent(
analytics: Analytics,
type: Block.Content.Text.Mark.Type,
context: String? = null
type: Block.Content.Text.Mark.Type
) {
sendEvent(
analytics = analytics,
eventName = EventsDictionary.blockChangeTextStyle,
props = Props(
mapOf(
EventsPropertiesKey.type to type.getPropName(),
EventsPropertiesKey.context to context
EventsPropertiesKey.type to type.getPropName()
)
)
)
@ -818,16 +755,14 @@ fun CoroutineScope.sendAnalyticsUpdateTextMarkupEvent(
fun CoroutineScope.sendAnalyticsUpdateTextMarkupEvent(
analytics: Analytics,
type: Markup.Type,
context: String? = null
type: Markup.Type
) {
sendEvent(
analytics = analytics,
eventName = EventsDictionary.blockChangeTextStyle,
props = Props(
mapOf(
EventsPropertiesKey.type to type.getPropName(),
EventsPropertiesKey.context to context
EventsPropertiesKey.type to type.getPropName()
)
)
)
@ -835,16 +770,14 @@ fun CoroutineScope.sendAnalyticsUpdateTextMarkupEvent(
fun CoroutineScope.sendAnalyticsBlockReorder(
analytics: Analytics,
count: Int,
context: String? = null
count: Int
) {
sendEvent(
analytics = analytics,
eventName = EventsDictionary.blockReorder,
props = Props(
mapOf(
EventsPropertiesKey.count to "$count",
EventsPropertiesKey.context to context
EventsPropertiesKey.count to "$count"
)
)
)
@ -871,16 +804,10 @@ fun CoroutineScope.sendAnalyticsBlockBackgroundEvent(
fun CoroutineScope.sendAnalyticsGoBackEvent(
analytics: Analytics,
context: String? = null
) {
sendEvent(
analytics = analytics,
eventName = EventsDictionary.goBack,
props = Props(
mapOf(
EventsPropertiesKey.context to context
)
)
eventName = EventsDictionary.goBack
)
}
@ -982,13 +909,6 @@ fun CoroutineScope.sendAnalyticsMentionMenuEvent(
)
}
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,
@ -1005,9 +925,6 @@ fun CoroutineScope.logEvent(
is ObjectState.DataView.Set -> "ot-set"
}
val scope = this
val params = state.getAnalyticsParams()
val analyticsContext = params.first
val analyticsObjectId = params.second
when (event) {
ObjectStateAnalyticsEvent.OPEN_OBJECT -> {
when (state) {
@ -1015,22 +932,14 @@ fun CoroutineScope.logEvent(
analytics = analytics,
eventName = collectionScreenShow,
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId
)
middleTime = middleTime
)
is ObjectState.DataView.Set -> scope.sendEvent(
analytics = analytics,
eventName = setScreenShow,
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
embedType = embedTypeDefault
)
props = buildProps(embedType = embedTypeDefault)
)
}
}
@ -1039,11 +948,7 @@ fun CoroutineScope.logEvent(
analytics = analytics,
eventName = turnIntoCollection,
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId
)
middleTime = middleTime
)
}
ObjectStateAnalyticsEvent.SELECT_QUERY -> {
@ -1052,11 +957,7 @@ fun CoroutineScope.logEvent(
eventName = setSelectQuery,
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
type = type
)
props = buildProps(type = type)
)
}
ObjectStateAnalyticsEvent.ADD_VIEW -> {
@ -1066,8 +967,6 @@ fun CoroutineScope.logEvent(
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
type = type,
embedType = embedTypeDefault,
objectType = objectTypeDefault
@ -1081,8 +980,6 @@ fun CoroutineScope.logEvent(
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
type = type,
embedType = embedTypeDefault,
objectType = objectTypeDefault
@ -1096,8 +993,6 @@ fun CoroutineScope.logEvent(
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
embedType = embedTypeDefault,
objectType = objectTypeDefault
)
@ -1110,8 +1005,6 @@ fun CoroutineScope.logEvent(
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
type = type,
embedType = embedTypeDefault,
objectType = objectTypeDefault
@ -1125,8 +1018,6 @@ fun CoroutineScope.logEvent(
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
type = type,
embedType = embedTypeDefault,
objectType = objectTypeDefault
@ -1140,8 +1031,6 @@ fun CoroutineScope.logEvent(
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
type = type,
embedType = embedTypeDefault,
objectType = objectTypeDefault
@ -1155,8 +1044,6 @@ fun CoroutineScope.logEvent(
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
embedType = embedTypeDefault,
objectType = objectTypeDefault,
condition = condition
@ -1170,8 +1057,6 @@ fun CoroutineScope.logEvent(
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
embedType = embedTypeDefault,
objectType = objectTypeDefault,
condition = condition
@ -1185,8 +1070,6 @@ fun CoroutineScope.logEvent(
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
embedType = embedTypeDefault,
objectType = objectTypeDefault
)
@ -1199,8 +1082,6 @@ fun CoroutineScope.logEvent(
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
embedType = embedTypeDefault,
objectType = objectTypeDefault,
type = type
@ -1214,8 +1095,6 @@ fun CoroutineScope.logEvent(
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
embedType = embedTypeDefault,
objectType = objectTypeDefault,
type = type
@ -1229,8 +1108,6 @@ fun CoroutineScope.logEvent(
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
embedType = embedTypeDefault,
objectType = objectTypeDefault
)
@ -1247,9 +1124,7 @@ fun CoroutineScope.logEvent(
startTime = startTime,
middleTime = middleTime,
props = buildProps(
analyticsContext = analyticsContext,
analyticsObjectId = analyticsObjectId,
objectType = type ?: OBJ_TYPE_CUSTOM,
objectType = type,
route = route
)
)
@ -1389,8 +1264,6 @@ fun CoroutineScope.logEvent(
}
private fun buildProps(
analyticsContext: String? = null,
analyticsObjectId: String? = null,
embedType: String? = null,
type: String? = null,
objectType: String? = null,
@ -1399,8 +1272,6 @@ private fun buildProps(
): 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)
@ -1918,7 +1789,10 @@ fun CoroutineScope.sendAnalyticsCreateTemplateEvent(
ctx: Id,
startTime: Long
) {
val objType = getAnalyticsObjectType(details, ctx)
val objType = getAnalyticsObjectType(
details = details,
ctx = ctx
)
sendEvent(
analytics = analytics,
eventName = createTemplate,
@ -1955,9 +1829,10 @@ fun CoroutineScope.sendAnalyticsDefaultTemplateEvent(
}
private fun getAnalyticsObjectType(
details: Map<Id, Block.Fields>,
details: Map<Id, Block.Fields>?,
ctx: Id
): String {
): String? {
if (details == null) return null
val objTypeId = details[ctx]?.type?.firstOrNull()
val typeStruct = details[objTypeId]?.map
val objType = typeStruct?.mapToObjectWrapperType()

View file

@ -1068,11 +1068,10 @@ class HomeScreenViewModel(
onSuccess = { result ->
sendAnalyticsObjectCreateEvent(
analytics = analytics,
type = result.typeKey.key,
storeOfObjectTypes = storeOfObjectTypes,
route = EventsDictionary.Routes.navigation,
startTime = startTime,
view = EventsDictionary.View.viewHome
view = EventsDictionary.View.viewHome,
objType = objType ?: storeOfObjectTypes.getByKey(result.typeKey.key),
)
if (objType != null) {
sendAnalyticsObjectTypeSelectOrChangeEvent(

View file

@ -4,6 +4,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.anytypeio.anytype.analytics.base.Analytics
import com.anytypeio.anytype.analytics.base.EventsDictionary
import com.anytypeio.anytype.analytics.base.EventsDictionary.libraryScreenRelation
import com.anytypeio.anytype.analytics.base.EventsDictionary.libraryScreenType
import com.anytypeio.anytype.analytics.base.EventsDictionary.libraryView
@ -22,11 +23,13 @@ import com.anytypeio.anytype.domain.library.StoreSearchByIdsParams
import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer
import com.anytypeio.anytype.domain.misc.UrlBuilder
import com.anytypeio.anytype.domain.`object`.SetObjectDetails
import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
import com.anytypeio.anytype.domain.page.CreateObject
import com.anytypeio.anytype.domain.workspace.AddObjectToWorkspace
import com.anytypeio.anytype.domain.workspace.RemoveObjectsFromWorkspace
import com.anytypeio.anytype.domain.workspace.SpaceManager
import com.anytypeio.anytype.presentation.BuildConfig
import com.anytypeio.anytype.presentation.extension.sendAnalyticsObjectCreateEvent
import com.anytypeio.anytype.presentation.home.HomeScreenViewModel.Companion.HOME_SCREEN_PROFILE_OBJECT_SUBSCRIPTION
import com.anytypeio.anytype.presentation.home.OpenObjectNavigation
import com.anytypeio.anytype.presentation.home.navigation
@ -68,7 +71,8 @@ class LibraryViewModel(
private val spaceManager: SpaceManager,
private val storelessSubscriptionContainer: StorelessSubscriptionContainer,
private val appCoroutineDispatchers: AppCoroutineDispatchers,
private val urlBuilder: UrlBuilder
private val urlBuilder: UrlBuilder,
private val storeOfObjectTypes: StoreOfObjectTypes
) : NavigationViewModel<LibraryViewModel.Navigation>() {
val icon = MutableStateFlow<ProfileIconView>(ProfileIconView.Loading)
@ -196,10 +200,20 @@ class LibraryViewModel(
private fun proceedWithCreateDoc(
objType: ObjectWrapper.Type? = null
) {
val startTime = System.currentTimeMillis()
val params = objType?.uniqueKey.getCreateObjectParams(objType?.defaultTemplateId)
viewModelScope.launch {
createObject.async(params).fold(
onSuccess = { result -> proceedWithOpeningObject(result.obj) },
onSuccess = {
result -> proceedWithOpeningObject(result.obj)
sendAnalyticsObjectCreateEvent(
analytics = analytics,
route = EventsDictionary.Routes.objCreateLibrary,
startTime = startTime,
objType = objType ?: storeOfObjectTypes.getByKey(result.typeKey.key),
view = EventsDictionary.View.viewHome
)
},
onFailure = { e -> Timber.e(e, "Error while creating a new object") }
)
}
@ -481,7 +495,8 @@ class LibraryViewModel(
private val spaceManager: SpaceManager,
private val storelessSubscriptionContainer: StorelessSubscriptionContainer,
private val appCoroutineDispatchers: AppCoroutineDispatchers,
private val urlBuilder: UrlBuilder
private val urlBuilder: UrlBuilder,
private val storeOfObjectTypes: StoreOfObjectTypes
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
@ -499,7 +514,8 @@ class LibraryViewModel(
spaceManager,
storelessSubscriptionContainer = storelessSubscriptionContainer,
appCoroutineDispatchers = appCoroutineDispatchers,
urlBuilder = urlBuilder
urlBuilder = urlBuilder,
storeOfObjectTypes = storeOfObjectTypes
) as T
}
}

View file

@ -5,6 +5,8 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.anytypeio.anytype.analytics.base.Analytics
import com.anytypeio.anytype.analytics.base.EventsDictionary
import com.anytypeio.anytype.analytics.props.Props
import com.anytypeio.anytype.analytics.props.Props.Companion.OBJ_TYPE_CUSTOM
import com.anytypeio.anytype.core_models.DVViewer
import com.anytypeio.anytype.core_models.DVViewerCardSize
import com.anytypeio.anytype.core_models.DVViewerType
@ -1125,24 +1127,22 @@ class ObjectSetViewModel(
}
}
private fun proceedWithCreatingDataViewObject(
private suspend fun proceedWithCreatingDataViewObject(
params: CreateDataViewObject.Params,
action: ((CreateDataViewObject.Result) -> Unit)? = null
) {
val startTime = System.currentTimeMillis()
viewModelScope.launch {
createDataViewObject.async(params).fold(
onFailure = { Timber.e(it, "Error while creating new record") },
onSuccess = { result ->
action?.invoke(result)
proceedWithNewDataViewObject(result)
sendAnalyticsObjectCreateEvent(
startTime = startTime,
typeKey = result.objectType.key,
)
}
)
}
createDataViewObject.async(params).fold(
onFailure = { Timber.e(it, "Error while creating new record") },
onSuccess = { result ->
action?.invoke(result)
proceedWithNewDataViewObject(result)
sendAnalyticsObjectCreateEvent(
startTime = startTime,
typeKey = result.objectType.key,
)
}
)
}
private suspend fun proceedWithNewDataViewObject(
@ -1298,20 +1298,18 @@ class ObjectSetViewModel(
return
}
isCustomizeViewPanelVisible.value = false
jobs += viewModelScope.launch {
val navigateCommand = when (layout) {
ObjectType.Layout.SET,
ObjectType.Layout.COLLECTION -> AppNavigation.Command.OpenSetOrCollection(target = target)
else -> AppNavigation.Command.OpenObject(id = target)
}
closeBlock.async(context).fold(
onSuccess = { navigate(EventWrapper(navigateCommand)) },
onFailure = {
Timber.e(it, "Error while closing object set: $context")
navigate(EventWrapper(navigateCommand))
}
)
val navigateCommand = when (layout) {
ObjectType.Layout.SET,
ObjectType.Layout.COLLECTION -> AppNavigation.Command.OpenSetOrCollection(target = target)
else -> AppNavigation.Command.OpenObject(id = target)
}
closeBlock.async(context).fold(
onSuccess = { navigate(EventWrapper(navigateCommand)) },
onFailure = {
Timber.e(it, "Error while closing object set: $context")
navigate(EventWrapper(navigateCommand))
}
)
}
private suspend fun proceedWithOpeningTemplate(target: Id, targetTypeId: Id, targetTypeKey: Id) {
@ -1433,11 +1431,10 @@ class ObjectSetViewModel(
)
sendAnalyticsObjectCreateEvent(
analytics = analytics,
startTime = startTime,
storeOfObjectTypes = storeOfObjectTypes,
type = result.typeKey.key,
route = EventsDictionary.Routes.navigation,
view = EventsDictionary.View.viewNavbar
startTime = startTime,
view = EventsDictionary.View.viewNavbar,
objType = objType ?: storeOfObjectTypes.getByKey(result.typeKey.key)
)
},
onFailure = { e ->
@ -1456,7 +1453,7 @@ class ObjectSetViewModel(
analytics = analytics,
event = ObjectStateAnalyticsEvent.OBJECT_CREATE,
startTime = startTime,
type = objType?.sourceObject
type = objType?.sourceObject ?: OBJ_TYPE_CUSTOM
)
}
}

View file

@ -128,7 +128,7 @@ class AddToAnytypeViewModel(
success = { obj ->
sendAnalyticsObjectCreateEvent(
analytics = analytics,
type = MarketplaceObjectTypeIds.BOOKMARK,
objType = MarketplaceObjectTypeIds.BOOKMARK,
route = EventsDictionary.Routes.sharingExtension,
startTime = startTime
)
@ -170,7 +170,7 @@ class AddToAnytypeViewModel(
onSuccess = { result ->
sendAnalyticsObjectCreateEvent(
analytics = analytics,
type = MarketplaceObjectTypeIds.NOTE,
objType = MarketplaceObjectTypeIds.NOTE,
route = EventsDictionary.Routes.sharingExtension,
startTime = startTime
)

View file

@ -838,10 +838,10 @@ class CollectionViewModel(
onSuccess = { result ->
sendAnalyticsObjectCreateEvent(
analytics = analytics,
type = result.typeKey.key,
storeOfObjectTypes = storeOfObjectTypes,
route = EventsDictionary.Routes.objCreateHome,
startTime = startTime
startTime = startTime,
objType = objType ?: storeOfObjectTypes.getByKey(result.typeKey.key),
view = EventsDictionary.View.viewHome
)
proceedWithOpeningObject(result.obj)
},