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

DROID-3512 Widgets | Analytics | Add analytics for auto-widget creation property (#2285)

This commit is contained in:
Evgenii Kozlov 2025-04-11 12:56:36 +02:00 committed by GitHub
parent 0c46744963
commit 842e502b21
Signed by: github
GPG key ID: B5690EEEBB952194
13 changed files with 281 additions and 105 deletions

View file

@ -154,7 +154,9 @@ object EventsDictionary {
const val reorderWidget = "ReorderWidget"
const val deleteWidget = "DeleteWidget"
const val screenHome = "ScreenHome"
const val selectHomeTab = "SelectHomeTab"
const val clickWidgetTitle = "ClickWidgetTitle"
const val screenWidgetMenu = "ScreenWidgetMenu"
const val openSidebarObject = "OpenSidebarObject"
//Templates
const val selectTemplate = "SelectTemplate"

View file

@ -10,6 +10,7 @@ object WidgetAnalytics {
const val VIEW = "view"
const val CONTEXT = "context"
const val ROUTE = "route"
const val WIDGET_TYPE = "widgetType"
// Values
@ -35,4 +36,7 @@ object WidgetAnalytics {
const val CUSTOM_OBJECT_TYPE = "custom"
const val ROUTE_ADD_WIDGET = "AddWidget"
const val WIDGET_TYPE_AUTO = "Auto"
const val WIDGET_TYPE_MANUAL = "Manual"
}

View file

@ -79,8 +79,9 @@ fun HomeScreen(
mode: InteractionMode,
widgets: List<WidgetView>,
onExpand: (TreePath) -> Unit,
onWidgetObjectClicked: (ObjectWrapper.Basic) -> Unit,
onWidgetSourceClicked: (Widget.Source) -> Unit,
onWidgetElementClicked: (WidgetId, ObjectWrapper.Basic) -> Unit,
onWidgetMenuTriggered: (WidgetId) -> Unit,
onWidgetSourceClicked: (WidgetId, Widget.Source) -> Unit,
onBundledWidgetClicked: (WidgetId) -> Unit,
onCreateWidget: () -> Unit,
onEditWidgets: () -> Unit,
@ -108,7 +109,7 @@ fun HomeScreen(
widgets = widgets,
onExpand = onExpand,
onWidgetMenuAction = onWidgetMenuAction,
onWidgetObjectClicked = onWidgetObjectClicked,
onWidgetElementClicked = onWidgetElementClicked,
onWidgetSourceClicked = onWidgetSourceClicked,
onBundledWidgetHeaderClicked = onBundledWidgetClicked,
onToggleExpandedWidgetState = onToggleExpandedWidgetState,
@ -123,7 +124,8 @@ fun HomeScreen(
onCreateWidget = onCreateWidget,
onCreateObjectInsideWidget = onCreateObjectInsideWidget,
onCreateDataViewObject = onCreateDataViewObject,
onCreateElement = onCreateElement
onCreateElement = onCreateElement,
onWidgetMenuTriggered = onWidgetMenuTriggered
)
AnimatedVisibility(
visible = mode is InteractionMode.Edit,
@ -180,8 +182,9 @@ private fun WidgetList(
widgets: List<WidgetView>,
onExpand: (TreePath) -> Unit,
onWidgetMenuAction: (WidgetId, DropDownMenuAction) -> Unit,
onWidgetObjectClicked: (ObjectWrapper.Basic) -> Unit,
onWidgetSourceClicked: (Widget.Source) -> Unit,
onWidgetElementClicked: (WidgetId, ObjectWrapper.Basic) -> Unit,
onWidgetSourceClicked: (WidgetId, Widget.Source) -> Unit,
onWidgetMenuTriggered: (WidgetId) -> Unit,
onBundledWidgetHeaderClicked: (WidgetId) -> Unit,
onToggleExpandedWidgetState: (WidgetId) -> Unit,
mode: InteractionMode,
@ -250,11 +253,14 @@ private fun WidgetList(
item = item,
onExpand = onExpand,
onWidgetMenuAction = onWidgetMenuAction,
onWidgetObjectClicked = onWidgetObjectClicked,
onWidgetElementClicked = { obj ->
onWidgetElementClicked(item.id, obj)
},
onObjectCheckboxClicked = onObjectCheckboxClicked,
onWidgetSourceClicked = onWidgetSourceClicked,
onToggleExpandedWidgetState = onToggleExpandedWidgetState,
onCreateObjectInsideWidget = onCreateObjectInsideWidget
onCreateObjectInsideWidget = onCreateObjectInsideWidget,
onWidgetMenuTriggered = onWidgetMenuTriggered
)
}
} else {
@ -266,11 +272,14 @@ private fun WidgetList(
item = item,
onExpand = onExpand,
onWidgetMenuAction = onWidgetMenuAction,
onWidgetObjectClicked = onWidgetObjectClicked,
onWidgetElementClicked = { obj ->
onWidgetElementClicked(item.id, obj)
},
onObjectCheckboxClicked = onObjectCheckboxClicked,
onWidgetSourceClicked = onWidgetSourceClicked,
onToggleExpandedWidgetState = onToggleExpandedWidgetState,
onCreateObjectInsideWidget = onCreateObjectInsideWidget
onCreateObjectInsideWidget = onCreateObjectInsideWidget,
onWidgetMenuTriggered = onWidgetMenuTriggered
)
}
}
@ -285,7 +294,8 @@ private fun WidgetList(
alpha = alpha.value,
item = item,
onWidgetMenuAction = onWidgetMenuAction,
onWidgetSourceClicked = onWidgetSourceClicked
onWidgetSourceClicked = onWidgetSourceClicked,
onWidgetMenuTriggered = onWidgetMenuTriggered
)
}
} else {
@ -296,7 +306,8 @@ private fun WidgetList(
alpha = 1.0f,
item = item,
onWidgetMenuAction = onWidgetMenuAction,
onWidgetSourceClicked = onWidgetSourceClicked
onWidgetSourceClicked = onWidgetSourceClicked,
onWidgetMenuTriggered = onWidgetMenuTriggered
)
}
}
@ -312,7 +323,10 @@ private fun WidgetList(
lazyListState = lazyListState,
alpha = alpha.value,
item = item,
onWidgetObjectClicked = onWidgetObjectClicked,
onWidgetElementClicked = { obj ->
onWidgetElementClicked(item.id, obj)
},
onWidgetMenuTriggered = onWidgetMenuTriggered,
onWidgetSourceClicked = onWidgetSourceClicked,
onWidgetMenuAction = onWidgetMenuAction,
onChangeWidgetView = onChangeWidgetView,
@ -329,7 +343,10 @@ private fun WidgetList(
lazyListState = lazyListState,
alpha = 1.0f,
item = item,
onWidgetObjectClicked = onWidgetObjectClicked,
onWidgetElementClicked = { obj ->
onWidgetElementClicked(item.id, obj)
},
onWidgetMenuTriggered = onWidgetMenuTriggered,
onWidgetSourceClicked = onWidgetSourceClicked,
onWidgetMenuAction = onWidgetMenuAction,
onChangeWidgetView = onChangeWidgetView,
@ -352,13 +369,16 @@ private fun WidgetList(
lazyListState = lazyListState,
alpha = alpha.value,
item = item,
onWidgetObjectClicked = onWidgetObjectClicked,
onWidgetElementClicked = { obj ->
onWidgetElementClicked(item.id, obj)
},
onWidgetSourceClicked = onWidgetSourceClicked,
onWidgetMenuAction = onWidgetMenuAction,
onChangeWidgetView = onChangeWidgetView,
onToggleExpandedWidgetState = onToggleExpandedWidgetState,
onObjectCheckboxClicked = onObjectCheckboxClicked,
onSeeAllObjectsClicked = onSeeAllObjectsClicked
onSeeAllObjectsClicked = onSeeAllObjectsClicked,
onWidgetMenuTriggered = onWidgetMenuTriggered
)
}
} else {
@ -368,13 +388,16 @@ private fun WidgetList(
lazyListState = lazyListState,
alpha = 1.0f,
item = item,
onWidgetObjectClicked = onWidgetObjectClicked,
onWidgetElementClicked = { obj ->
onWidgetElementClicked(item.id, obj)
},
onWidgetSourceClicked = onWidgetSourceClicked,
onWidgetMenuAction = onWidgetMenuAction,
onChangeWidgetView = onChangeWidgetView,
onToggleExpandedWidgetState = onToggleExpandedWidgetState,
onObjectCheckboxClicked = onObjectCheckboxClicked,
onSeeAllObjectsClicked = onSeeAllObjectsClicked
onSeeAllObjectsClicked = onSeeAllObjectsClicked,
onWidgetMenuTriggered = onWidgetMenuTriggered
)
}
}
@ -390,8 +413,11 @@ private fun WidgetList(
lazyListState = lazyListState,
alpha = alpha.value,
item = item,
onWidgetObjectClicked = onWidgetObjectClicked,
onWidgetElementClicked = { obj ->
onWidgetElementClicked(item.id, obj)
},
onWidgetSourceClicked = onWidgetSourceClicked,
onWidgetMenuTriggered = onWidgetMenuTriggered,
onWidgetMenuAction = onWidgetMenuAction,
onToggleExpandedWidgetState = onToggleExpandedWidgetState,
onObjectCheckboxClicked = onObjectCheckboxClicked,
@ -405,8 +431,11 @@ private fun WidgetList(
lazyListState = lazyListState,
alpha = 1.0f,
item = item,
onWidgetObjectClicked = onWidgetObjectClicked,
onWidgetElementClicked = { obj ->
onWidgetElementClicked(item.id, obj)
},
onWidgetSourceClicked = onWidgetSourceClicked,
onWidgetMenuTriggered = onWidgetMenuTriggered,
onWidgetMenuAction = onWidgetMenuAction,
onToggleExpandedWidgetState = onToggleExpandedWidgetState,
onObjectCheckboxClicked = onObjectCheckboxClicked,
@ -433,7 +462,10 @@ private fun WidgetList(
index = index,
mode = mode,
onWidgetClicked = {
onWidgetSourceClicked(Widget.Source.Bundled.AllObjects)
onWidgetSourceClicked(
item.id,
Widget.Source.Bundled.AllObjects
)
},
onDropDownMenuAction = { action ->
onWidgetMenuAction(item.id, action)
@ -447,7 +479,10 @@ private fun WidgetList(
index = index,
mode = mode,
onWidgetClicked = {
onWidgetSourceClicked(Widget.Source.Bundled.AllObjects)
onWidgetSourceClicked(
item.id,
Widget.Source.Bundled.AllObjects
)
},
onDropDownMenuAction = { action ->
onWidgetMenuAction(item.id, action)
@ -524,8 +559,9 @@ private fun ListOfObjectsItem(
lazyListState: ReorderableLazyListState,
alpha: Float,
item: WidgetView.ListOfObjects,
onWidgetObjectClicked: (ObjectWrapper.Basic) -> Unit,
onWidgetSourceClicked: (Widget.Source) -> Unit,
onWidgetElementClicked: (ObjectWrapper.Basic) -> Unit,
onWidgetSourceClicked: (WidgetId, Widget.Source) -> Unit,
onWidgetMenuTriggered: (WidgetId) -> Unit,
onWidgetMenuAction: (WidgetId, DropDownMenuAction) -> Unit,
onToggleExpandedWidgetState: (WidgetId) -> Unit,
onObjectCheckboxClicked: (Id, Boolean) -> Unit,
@ -547,14 +583,15 @@ private fun ListOfObjectsItem(
ListWidgetCard(
item = item,
mode = mode,
onWidgetObjectClicked = onWidgetObjectClicked,
onWidgetObjectClicked = onWidgetElementClicked,
onWidgetSourceClicked = onWidgetSourceClicked,
onDropDownMenuAction = { action ->
onWidgetMenuAction(item.id, action)
},
onToggleExpandedWidgetState = onToggleExpandedWidgetState,
onObjectCheckboxClicked = onObjectCheckboxClicked,
onCreateElement = onCreateElement
onCreateElement = onCreateElement,
onWidgetMenuTriggered = onWidgetMenuTriggered
)
AnimatedVisibility(
visible = mode is InteractionMode.Edit,
@ -587,8 +624,9 @@ private fun SetOfObjectsItem(
lazyListState: ReorderableLazyListState,
alpha: Float,
item: WidgetView.SetOfObjects,
onWidgetObjectClicked: (ObjectWrapper.Basic) -> Unit,
onWidgetSourceClicked: (Widget.Source) -> Unit,
onWidgetElementClicked: (ObjectWrapper.Basic) -> Unit,
onWidgetSourceClicked: (WidgetId, Widget.Source) -> Unit,
onWidgetMenuTriggered: (WidgetId) -> Unit,
onWidgetMenuAction: (WidgetId, DropDownMenuAction) -> Unit,
onChangeWidgetView: (WidgetId, ViewId) -> Unit,
onToggleExpandedWidgetState: (WidgetId) -> Unit,
@ -611,8 +649,9 @@ private fun SetOfObjectsItem(
) {
DataViewListWidgetCard(
item = item,
onWidgetObjectClicked = onWidgetObjectClicked,
onWidgetObjectClicked = onWidgetElementClicked,
onWidgetSourceClicked = onWidgetSourceClicked,
onWidgetMenuTriggered = onWidgetMenuTriggered,
onDropDownMenuAction = { action ->
onWidgetMenuAction(item.id, action)
},
@ -654,8 +693,9 @@ private fun GalleryWidgetItem(
lazyListState: ReorderableLazyListState,
alpha: Float,
item: WidgetView.Gallery,
onWidgetObjectClicked: (ObjectWrapper.Basic) -> Unit,
onWidgetSourceClicked: (Widget.Source) -> Unit,
onWidgetElementClicked: (ObjectWrapper.Basic) -> Unit,
onWidgetSourceClicked: (WidgetId, Widget.Source) -> Unit,
onWidgetMenuTriggered: (WidgetId) -> Unit,
onWidgetMenuAction: (WidgetId, DropDownMenuAction) -> Unit,
onChangeWidgetView: (WidgetId, ViewId) -> Unit,
onToggleExpandedWidgetState: (WidgetId) -> Unit,
@ -677,7 +717,7 @@ private fun GalleryWidgetItem(
) {
GalleryWidgetCard(
item = item,
onWidgetObjectClicked = onWidgetObjectClicked,
onWidgetObjectClicked = onWidgetElementClicked,
onWidgetSourceClicked = onWidgetSourceClicked,
onDropDownMenuAction = { action ->
onWidgetMenuAction(item.id, action)
@ -686,7 +726,8 @@ private fun GalleryWidgetItem(
onToggleExpandedWidgetState = onToggleExpandedWidgetState,
mode = mode,
onObjectCheckboxClicked = onObjectCheckboxClicked,
onSeeAllObjectsClicked = onSeeAllObjectsClicked
onSeeAllObjectsClicked = onSeeAllObjectsClicked,
onWidgetMenuTriggered = onWidgetMenuTriggered
)
AnimatedVisibility(
visible = mode is InteractionMode.Edit,
@ -720,7 +761,8 @@ private fun LinkWidgetItem(
alpha: Float,
item: WidgetView.Link,
onWidgetMenuAction: (WidgetId, DropDownMenuAction) -> Unit,
onWidgetSourceClicked: (Widget.Source) -> Unit
onWidgetSourceClicked: (WidgetId, Widget.Source) -> Unit,
onWidgetMenuTriggered: (WidgetId) -> Unit,
) {
Box(
modifier = Modifier
@ -741,7 +783,8 @@ private fun LinkWidgetItem(
},
onWidgetSourceClicked = onWidgetSourceClicked,
isInEditMode = mode is InteractionMode.Edit,
hasReadOnlyAccess = mode is InteractionMode.ReadOnly
hasReadOnlyAccess = mode is InteractionMode.ReadOnly,
onWidgetMenuTriggered = onWidgetMenuTriggered
)
AnimatedVisibility(
visible = mode is InteractionMode.Edit,
@ -775,10 +818,11 @@ private fun TreeWidgetItem(
alpha: Float,
item: WidgetView.Tree,
onExpand: (TreePath) -> Unit,
onWidgetMenuTriggered: (WidgetId) -> Unit,
onWidgetMenuAction: (WidgetId, DropDownMenuAction) -> Unit,
onWidgetObjectClicked: (ObjectWrapper.Basic) -> Unit,
onWidgetElementClicked: (ObjectWrapper.Basic) -> Unit,
onObjectCheckboxClicked: (Id, Boolean) -> Unit,
onWidgetSourceClicked: (Widget.Source) -> Unit,
onWidgetSourceClicked: (WidgetId, Widget.Source) -> Unit,
onToggleExpandedWidgetState: (WidgetId) -> Unit,
onCreateObjectInsideWidget: (Id) -> Unit
) {
@ -801,12 +845,13 @@ private fun TreeWidgetItem(
onDropDownMenuAction = { action ->
onWidgetMenuAction(item.id, action)
},
onWidgetObjectClicked = onWidgetObjectClicked,
onWidgetElementClicked = onWidgetElementClicked,
onObjectCheckboxClicked = onObjectCheckboxClicked,
onWidgetSourceClicked = onWidgetSourceClicked,
onToggleExpandedWidgetState = onToggleExpandedWidgetState,
mode = mode,
onCreateObjectInsideWidget = onCreateObjectInsideWidget
onCreateObjectInsideWidget = onCreateObjectInsideWidget,
onWidgetMenuClicked = onWidgetMenuTriggered
)
AnimatedVisibility(
visible = mode is InteractionMode.Edit,

View file

@ -186,7 +186,7 @@ class HomeScreenFragment : BaseComposeFragment(),
onWidgetMenuAction = { widget: Id, action: DropDownMenuAction ->
vm.onDropDownMenuAction(widget, action)
},
onWidgetObjectClicked = vm::onWidgetObjectClicked,
onWidgetElementClicked = vm::onWidgetElementClicked,
onWidgetSourceClicked = vm::onWidgetSourceClicked,
onChangeWidgetView = vm::onChangeCurrentWidgetView,
onToggleExpandedWidgetState = vm::onToggleCollapsedWidgetState,
@ -210,7 +210,8 @@ class HomeScreenFragment : BaseComposeFragment(),
onNavBarShareButtonClicked = vm::onNavBarShareIconClicked,
navPanelState = vm.navPanelState.collectAsStateWithLifecycle().value,
onHomeButtonClicked = vm::onHomeButtonClicked,
onCreateElement = vm::onCreateWidgetElementClicked
onCreateElement = vm::onCreateWidgetElementClicked,
onWidgetMenuTriggered = vm::onWidgetMenuTriggered
)
}

View file

@ -48,7 +48,6 @@ import com.anytypeio.anytype.core_ui.views.PreviewTitle2Medium
import com.anytypeio.anytype.core_ui.views.Relations3
import com.anytypeio.anytype.core_ui.widgets.ListWidgetObjectIcon
import com.anytypeio.anytype.core_utils.ext.orNull
import com.anytypeio.anytype.presentation.editor.cover.CoverGradient
import com.anytypeio.anytype.presentation.editor.cover.CoverView
import com.anytypeio.anytype.presentation.home.InteractionMode
import com.anytypeio.anytype.presentation.objects.ObjectIcon
@ -66,7 +65,8 @@ fun DataViewListWidgetCard(
item: WidgetView.SetOfObjects,
mode: InteractionMode,
onWidgetObjectClicked: (ObjectWrapper.Basic) -> Unit,
onWidgetSourceClicked: (Widget.Source) -> Unit,
onWidgetSourceClicked: (WidgetId, Widget.Source) -> Unit,
onWidgetMenuTriggered: (WidgetId) -> Unit,
onDropDownMenuAction: (DropDownMenuAction) -> Unit,
onChangeWidgetView: (WidgetId, ViewId) -> Unit,
onToggleExpandedWidgetState: (WidgetId) -> Unit,
@ -109,7 +109,7 @@ fun DataViewListWidgetCard(
isHeaderMenuExpanded = isHeaderMenuExpanded,
onWidgetHeaderClicked = {
if (mode !is InteractionMode.Edit) {
onWidgetSourceClicked(item.source)
onWidgetSourceClicked(item.id, item.source)
}
},
onExpandElement = { onToggleExpandedWidgetState(item.id) },
@ -118,7 +118,8 @@ fun DataViewListWidgetCard(
hasReadOnlyAccess = mode is InteractionMode.ReadOnly,
onDropDownMenuAction = onDropDownMenuAction,
canCreate = mode is InteractionMode.Default,
onCreateElement = { onCreateElement(item) }
onCreateElement = { onCreateElement(item) },
onWidgetMenuTriggered = { onWidgetMenuTriggered(item.id) }
)
if (item.tabs.size > 1 && item.isExpanded) {
DataViewTabs(
@ -195,7 +196,8 @@ fun GalleryWidgetCard(
item: WidgetView.Gallery,
mode: InteractionMode,
onWidgetObjectClicked: (ObjectWrapper.Basic) -> Unit,
onWidgetSourceClicked: (Widget.Source) -> Unit,
onWidgetSourceClicked: (WidgetId, Widget.Source) -> Unit,
onWidgetMenuTriggered: (WidgetId) -> Unit,
onDropDownMenuAction: (DropDownMenuAction) -> Unit,
onChangeWidgetView: (WidgetId, ViewId) -> Unit,
onToggleExpandedWidgetState: (WidgetId) -> Unit,
@ -237,14 +239,15 @@ fun GalleryWidgetCard(
isHeaderMenuExpanded = isHeaderMenuExpanded,
onWidgetHeaderClicked = {
if (mode !is InteractionMode.Edit) {
onWidgetSourceClicked(item.source)
onWidgetSourceClicked(item.id, item.source)
}
},
onExpandElement = { onToggleExpandedWidgetState(item.id) },
isExpanded = item.isExpanded,
isInEditMode = mode is InteractionMode.Edit,
hasReadOnlyAccess = mode is InteractionMode.ReadOnly,
onDropDownMenuAction = onDropDownMenuAction
onDropDownMenuAction = onDropDownMenuAction,
onWidgetMenuTriggered = { onWidgetMenuTriggered(item.id) }
)
if (item.tabs.size > 1 && item.isExpanded) {
DataViewTabs(

View file

@ -31,6 +31,7 @@ import com.anytypeio.anytype.core_ui.foundation.noRippleClickable
import com.anytypeio.anytype.core_ui.views.HeadlineSubheading
import com.anytypeio.anytype.presentation.widgets.DropDownMenuAction
import com.anytypeio.anytype.presentation.widgets.Widget
import com.anytypeio.anytype.presentation.widgets.WidgetId
import com.anytypeio.anytype.presentation.widgets.WidgetView
import com.anytypeio.anytype.ui.widgets.menu.WidgetMenu
@ -38,10 +39,11 @@ import com.anytypeio.anytype.ui.widgets.menu.WidgetMenu
@Composable
fun LinkWidgetCard(
item: WidgetView.Link,
onWidgetSourceClicked: (Widget.Source) -> Unit,
onWidgetSourceClicked: (WidgetId, Widget.Source) -> Unit,
onDropDownMenuAction: (DropDownMenuAction) -> Unit,
isInEditMode: Boolean,
hasReadOnlyAccess: Boolean = false
hasReadOnlyAccess: Boolean = false,
onWidgetMenuTriggered: (WidgetId) -> Unit,
) {
val isCardMenuExpanded = remember {
mutableStateOf(false)
@ -63,14 +65,17 @@ fun LinkWidgetCard(
if (isInEditMode) {
Modifier.noRippleClickable {
isCardMenuExpanded.value = !isCardMenuExpanded.value
if (isCardMenuExpanded.value == true) {
onWidgetMenuTriggered(item.id)
}
}
} else if (hasReadOnlyAccess) {
Modifier.noRippleClickable {
onWidgetSourceClicked(item.source)
onWidgetSourceClicked(item.id, item.source)
}
} else {
Modifier.combinedClickable(
onClick = { onWidgetSourceClicked(item.source) },
onClick = { onWidgetSourceClicked(item.id, item.source) },
onLongClick = {
isCardMenuExpanded.value = !isCardMenuExpanded.value
haptic.performHapticFeedback(HapticFeedbackType.LongPress)

View file

@ -41,7 +41,8 @@ fun ListWidgetCard(
item: WidgetView.ListOfObjects,
mode: InteractionMode,
onWidgetObjectClicked: (ObjectWrapper.Basic) -> Unit,
onWidgetSourceClicked: (Widget.Source) -> Unit,
onWidgetSourceClicked: (WidgetId, Widget.Source) -> Unit,
onWidgetMenuTriggered: (WidgetId) -> Unit,
onDropDownMenuAction: (DropDownMenuAction) -> Unit,
onToggleExpandedWidgetState: (WidgetId) -> Unit,
onObjectCheckboxClicked: (Id, Boolean) -> Unit,
@ -85,14 +86,15 @@ fun ListWidgetCard(
},
isCardMenuExpanded = isCardMenuExpanded,
isHeaderMenuExpanded = isHeaderMenuExpanded,
onWidgetHeaderClicked = { onWidgetSourceClicked(item.source) },
onWidgetHeaderClicked = { onWidgetSourceClicked(item.id, item.source) },
onExpandElement = { onToggleExpandedWidgetState(item.id) },
isExpanded = item.isExpanded,
isInEditMode = mode is InteractionMode.Edit,
hasReadOnlyAccess = mode is InteractionMode.ReadOnly,
onDropDownMenuAction = onDropDownMenuAction,
canCreate = (item.type is Type.Favorites && mode is InteractionMode.Default),
onCreateElement = { onCreateElement(item) }
onCreateElement = { onCreateElement(item) },
onWidgetMenuTriggered = { onWidgetMenuTriggered(item.id) }
)
if (item.elements.isNotEmpty()) {
if (item.isCompact) {

View file

@ -10,7 +10,6 @@ import androidx.compose.animation.fadeOut
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
@ -22,7 +21,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Divider
import androidx.compose.material.Text
@ -35,7 +33,6 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
@ -66,8 +63,9 @@ fun TreeWidgetCard(
mode: InteractionMode,
item: WidgetView.Tree,
onExpandElement: (TreePath) -> Unit,
onWidgetObjectClicked: (ObjectWrapper.Basic) -> Unit,
onWidgetSourceClicked: (Widget.Source) -> Unit,
onWidgetElementClicked: (ObjectWrapper.Basic) -> Unit,
onWidgetSourceClicked: (WidgetId, Widget.Source) -> Unit,
onWidgetMenuClicked: (WidgetId) -> Unit,
onDropDownMenuAction: (DropDownMenuAction) -> Unit,
onToggleExpandedWidgetState: (WidgetId) -> Unit,
onObjectCheckboxClicked: (Id, Boolean) -> Unit,
@ -108,19 +106,20 @@ fun TreeWidgetCard(
title = item.getPrettyName(),
isCardMenuExpanded = isCardMenuExpanded,
isHeaderMenuExpanded = isHeaderMenuExpanded,
onWidgetHeaderClicked = { onWidgetSourceClicked(item.source) },
onWidgetHeaderClicked = { onWidgetSourceClicked(item.id, item.source) },
onExpandElement = { onToggleExpandedWidgetState(item.id) },
isExpanded = item.isExpanded,
onDropDownMenuAction = onDropDownMenuAction,
isInEditMode = mode is InteractionMode.Edit,
hasReadOnlyAccess = mode == InteractionMode.ReadOnly
hasReadOnlyAccess = mode == InteractionMode.ReadOnly,
onWidgetMenuTriggered = { onWidgetMenuClicked(item.id) }
)
if (item.elements.isNotEmpty()) {
TreeWidgetTreeItems(
item = item,
mode = mode,
onExpand = onExpandElement,
onWidgetElementClicked = onWidgetObjectClicked,
onWidgetElementClicked = onWidgetElementClicked,
onObjectCheckboxClicked = onObjectCheckboxClicked
)
} else {
@ -256,6 +255,7 @@ fun WidgetHeader(
isCardMenuExpanded: MutableState<Boolean>,
isHeaderMenuExpanded: MutableState<Boolean>,
onWidgetHeaderClicked: () -> Unit,
onWidgetMenuTriggered: () -> Unit,
onDropDownMenuAction: (DropDownMenuAction) -> Unit,
onExpandElement: () -> Unit = {},
onCreateElement: () -> Unit = {},
@ -296,6 +296,9 @@ fun WidgetHeader(
onLongClick = {
isCardMenuExpanded.value = !isCardMenuExpanded.value
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
if (isCardMenuExpanded.value) {
onWidgetMenuTriggered()
}
},
indication = null,
interactionSource = remember { MutableInteractionSource() }

View file

@ -378,7 +378,8 @@ data class Block(
data class Widget(
val layout: Layout,
val limit: Int = 0,
val activeView: Id? = null
val activeView: Id? = null,
val isAutoAdded: Boolean = false
) : Content() {
enum class Layout {
TREE, LINK, LIST, COMPACT_LIST, VIEW

View file

@ -36,7 +36,6 @@ import com.anytypeio.anytype.core_models.NotificationPayload
import com.anytypeio.anytype.core_models.NotificationStatus
import com.anytypeio.anytype.core_models.ObjectOrder
import com.anytypeio.anytype.core_models.ObjectType
import com.anytypeio.anytype.core_models.ObjectTypeIds
import com.anytypeio.anytype.core_models.ObjectView
import com.anytypeio.anytype.core_models.Payload
import com.anytypeio.anytype.core_models.Process
@ -449,7 +448,8 @@ fun MBlock.toCoreWidget(): Block.Content.Widget {
MWidgetLayout.View -> Block.Content.Widget.Layout.VIEW
},
limit = content.limit,
activeView = content.viewId.ifEmpty { null }
activeView = content.viewId.ifEmpty { null },
isAutoAdded = content.autoAdded
)
}

View file

@ -1605,7 +1605,8 @@ fun CoroutineScope.sendDeleteWidgetEvent(
analytics: Analytics,
sourceObjectTypeId: Id,
isCustomObjectType: Boolean = false,
isInEditMode: Boolean
isInEditMode: Boolean,
isAutoCreated: Boolean?
) {
sendEvent(
analytics = analytics,
@ -1620,6 +1621,12 @@ fun CoroutineScope.sendDeleteWidgetEvent(
put(WidgetAnalytics.CONTEXT, WidgetAnalytics.CONTEXT_EDITOR)
else
put(WidgetAnalytics.CONTEXT, WidgetAnalytics.CONTEXT_HOME)
if (isAutoCreated == null) return
if (isAutoCreated) {
put(WidgetAnalytics.WIDGET_TYPE, WidgetAnalytics.WIDGET_TYPE_AUTO)
} else {
put(WidgetAnalytics.WIDGET_TYPE, WidgetAnalytics.WIDGET_TYPE_MANUAL)
}
}
)
)
@ -1628,7 +1635,8 @@ fun CoroutineScope.sendDeleteWidgetEvent(
fun CoroutineScope.sendDeleteWidgetEvent(
analytics: Analytics,
bundled: Widget.Source.Bundled,
isInEditMode: Boolean
isInEditMode: Boolean,
isAutoCreated: Boolean?
) {
sendEvent(
analytics = analytics,
@ -1659,35 +1667,38 @@ fun CoroutineScope.sendDeleteWidgetEvent(
put(WidgetAnalytics.CONTEXT, WidgetAnalytics.CONTEXT_EDITOR)
else
put(WidgetAnalytics.CONTEXT, WidgetAnalytics.CONTEXT_HOME)
if (isAutoCreated == null) return
if (isAutoCreated) {
put(WidgetAnalytics.WIDGET_TYPE, WidgetAnalytics.WIDGET_TYPE_AUTO)
} else {
put(WidgetAnalytics.WIDGET_TYPE, WidgetAnalytics.WIDGET_TYPE_MANUAL)
}
}
)
)
}
fun CoroutineScope.sendSelectHomeTabEvent(
fun CoroutineScope.sendClickWidgetTitleEvent(
analytics: Analytics,
bundled: Widget.Source.Bundled
bundled: Widget.Source.Bundled,
isAutoCreated: Boolean?
) {
sendEvent(
analytics = analytics,
eventName = EventsDictionary.selectHomeTab,
eventName = EventsDictionary.clickWidgetTitle,
props = Props(
buildMap {
put(WidgetAnalytics.VIEW, WidgetAnalytics.VIEW_WIDGET)
when (bundled) {
Widget.Source.Bundled.Favorites -> {
put(WidgetAnalytics.TAB, WidgetAnalytics.WIDGET_SOURCE_FAVORITES)
}
Widget.Source.Bundled.Recent -> {
put(WidgetAnalytics.TAB, WidgetAnalytics.WIDGET_SOURCE_RECENT)
}
Widget.Source.Bundled.RecentLocal -> {
put(WidgetAnalytics.TAB, WidgetAnalytics.WIDGET_SOURCE_RECENT_LOCAL)
}
Widget.Source.Bundled.Bin -> {
put(WidgetAnalytics.TAB, WidgetAnalytics.WIDGET_SOURCE_BIN)
}
@ -1695,19 +1706,26 @@ fun CoroutineScope.sendSelectHomeTabEvent(
put(WidgetAnalytics.TAB, WidgetAnalytics.WIDGET_SOURCE_ALL_OBJECTS)
}
}
if (isAutoCreated == null) return
if (isAutoCreated) {
put(WidgetAnalytics.WIDGET_TYPE, WidgetAnalytics.WIDGET_TYPE_AUTO)
} else {
put(WidgetAnalytics.WIDGET_TYPE, WidgetAnalytics.WIDGET_TYPE_MANUAL)
}
}
)
)
}
fun CoroutineScope.sendSelectHomeTabEvent(
fun CoroutineScope.sendClickWidgetTitleEvent(
analytics: Analytics,
sourceObjectTypeId: Id,
isCustomObjectType: Boolean = false
isCustomObjectType: Boolean = false,
isAutoCreated: Boolean?
) {
sendEvent(
analytics = analytics,
eventName = EventsDictionary.selectHomeTab,
eventName = EventsDictionary.clickWidgetTitle,
props = Props(
buildMap {
put(WidgetAnalytics.VIEW, WidgetAnalytics.VIEW_WIDGET)
@ -1715,6 +1733,12 @@ fun CoroutineScope.sendSelectHomeTabEvent(
put(WidgetAnalytics.TAB, WidgetAnalytics.CUSTOM_OBJECT_TYPE)
else
put(WidgetAnalytics.TAB, sourceObjectTypeId)
if (isAutoCreated == null) return
if (isAutoCreated) {
put(WidgetAnalytics.WIDGET_TYPE, WidgetAnalytics.WIDGET_TYPE_AUTO)
} else {
put(WidgetAnalytics.WIDGET_TYPE, WidgetAnalytics.WIDGET_TYPE_MANUAL)
}
}
)
)
@ -1741,7 +1765,8 @@ fun CoroutineScope.sendReorderWidgetEvent(
fun CoroutineScope.sendReorderWidgetEvent(
analytics: Analytics,
bundled: Widget.Source.Bundled
bundled: Widget.Source.Bundled,
isAutoCreated: Boolean?
) {
sendEvent(
analytics = analytics,
@ -1765,6 +1790,12 @@ fun CoroutineScope.sendReorderWidgetEvent(
put(WidgetAnalytics.TYPE, WidgetAnalytics.WIDGET_SOURCE_ALL_OBJECTS)
}
}
if (isAutoCreated == null) return
if (isAutoCreated) {
put(WidgetAnalytics.WIDGET_TYPE, WidgetAnalytics.WIDGET_TYPE_AUTO)
} else {
put(WidgetAnalytics.WIDGET_TYPE, WidgetAnalytics.WIDGET_TYPE_MANUAL)
}
}
)
)
@ -1781,6 +1812,42 @@ suspend fun Analytics.sendScreenHomeEvent() {
)
}
suspend fun Analytics.sendOpenSidebarObjectEvent(
isAutoCreated: Boolean?
) {
sendEvent(
eventName = EventsDictionary.openSidebarObject,
props = Props(
buildMap {
if (isAutoCreated == null) return
if (isAutoCreated) {
put(WidgetAnalytics.WIDGET_TYPE, WidgetAnalytics.WIDGET_TYPE_AUTO)
} else {
put(WidgetAnalytics.WIDGET_TYPE, WidgetAnalytics.WIDGET_TYPE_MANUAL)
}
}
)
)
}
suspend fun Analytics.sendScreenWidgetMenuEvent(
isAutoCreated: Boolean?
) {
sendEvent(
eventName = EventsDictionary.screenWidgetMenu,
props = Props(
buildMap {
if (isAutoCreated == null) return
if (isAutoCreated) {
put(WidgetAnalytics.WIDGET_TYPE, WidgetAnalytics.WIDGET_TYPE_AUTO)
} else {
put(WidgetAnalytics.WIDGET_TYPE, WidgetAnalytics.WIDGET_TYPE_MANUAL)
}
}
)
)
}
suspend fun Analytics.sendSettingsStorageEvent() {
sendEvent(
eventName = EventsDictionary.screenSettingsStorage

View file

@ -91,10 +91,12 @@ import com.anytypeio.anytype.presentation.editor.cover.CoverImageHashProvider
import com.anytypeio.anytype.presentation.extension.sendAddWidgetEvent
import com.anytypeio.anytype.presentation.extension.sendAnalyticsObjectCreateEvent
import com.anytypeio.anytype.presentation.extension.sendAnalyticsObjectTypeSelectOrChangeEvent
import com.anytypeio.anytype.presentation.extension.sendClickWidgetTitleEvent
import com.anytypeio.anytype.presentation.extension.sendDeleteWidgetEvent
import com.anytypeio.anytype.presentation.extension.sendEditWidgetsEvent
import com.anytypeio.anytype.presentation.extension.sendOpenSidebarObjectEvent
import com.anytypeio.anytype.presentation.extension.sendReorderWidgetEvent
import com.anytypeio.anytype.presentation.extension.sendSelectHomeTabEvent
import com.anytypeio.anytype.presentation.extension.sendScreenWidgetMenuEvent
import com.anytypeio.anytype.presentation.home.Command.ChangeWidgetType.Companion.UNDEFINED_LAYOUT_CODE
import com.anytypeio.anytype.presentation.navigation.DeepLinkToObjectDelegate
import com.anytypeio.anytype.presentation.navigation.NavPanelState
@ -966,15 +968,30 @@ class HomeScreenViewModel(
treeWidgetBranchStateHolder.onExpand(linkPath = path)
}
fun onWidgetObjectClicked(obj: ObjectWrapper.Basic) {
fun onWidgetElementClicked(widget: Id, obj: ObjectWrapper.Basic) {
Timber.d("With id: ${obj.id}")
if (obj.isArchived != true) {
viewModelScope.launch {
val isAutoCreated = widgets.value?.find { it.id == widget }?.isAutoCreated
analytics.sendOpenSidebarObjectEvent(
isAutoCreated = isAutoCreated
)
}
proceedWithOpeningObject(obj)
} else {
sendToast("Open bin to restore your archived object")
}
}
fun onWidgetMenuTriggered(widget: Id) {
viewModelScope.launch {
val isAutoCreated = widgets.value?.find { it.id == widget }?.isAutoCreated
analytics.sendScreenWidgetMenuEvent(
isAutoCreated = isAutoCreated
)
}
}
fun onObjectCheckboxClicked(id: Id, isChecked: Boolean) {
proceedWithTogglingObjectCheckboxState(id = id, isChecked = isChecked)
}
@ -999,13 +1016,15 @@ class HomeScreenViewModel(
}
}
fun onWidgetSourceClicked(source: Widget.Source) {
fun onWidgetSourceClicked(widget: Id, source: Widget.Source) {
Timber.d("onWidgetSourceClicked: $source")
val isAutoCreated = widgets.value?.find { it.id == widget }?.isAutoCreated
when (source) {
is Widget.Source.Bundled.Favorites -> {
viewModelScope.sendSelectHomeTabEvent(
viewModelScope.sendClickWidgetTitleEvent(
analytics = analytics,
bundled = source
bundled = source,
isAutoCreated = isAutoCreated
)
// TODO switch to bundled widgets id
viewModelScope.launch {
@ -1018,9 +1037,10 @@ class HomeScreenViewModel(
}
}
is Widget.Source.Bundled.Recent -> {
viewModelScope.sendSelectHomeTabEvent(
viewModelScope.sendClickWidgetTitleEvent(
analytics = analytics,
bundled = source
bundled = source,
isAutoCreated = isAutoCreated
)
// TODO switch to bundled widgets id
viewModelScope.launch {
@ -1033,9 +1053,10 @@ class HomeScreenViewModel(
}
}
is Widget.Source.Bundled.RecentLocal -> {
viewModelScope.sendSelectHomeTabEvent(
viewModelScope.sendClickWidgetTitleEvent(
analytics = analytics,
bundled = source
bundled = source,
isAutoCreated = isAutoCreated
)
// TODO switch to bundled widgets id
viewModelScope.launch {
@ -1049,7 +1070,10 @@ class HomeScreenViewModel(
}
is Widget.Source.Default -> {
if (source.obj.isArchived != true) {
dispatchSelectHomeTabCustomSourceEvent(source)
dispatchSelectHomeTabCustomSourceEvent(
widget = widget,
source = source
)
proceedWithOpeningObject(source.obj)
} else {
sendToast("Open bin to restore your archived object")
@ -1705,12 +1729,14 @@ class HomeScreenViewModel(
private fun dispatchDeleteWidgetAnalyticsEvent(target: Widget?) {
viewModelScope.launch {
val isAutoCreated = widgets.value?.find { it.id == target?.id }?.isAutoCreated
when (val source = target?.source) {
is Widget.Source.Bundled -> {
sendDeleteWidgetEvent(
analytics = analytics,
bundled = source,
isInEditMode = isInEditMode()
isInEditMode = isInEditMode(),
isAutoCreated = isAutoCreated
)
}
is Widget.Source.Default -> {
@ -1722,7 +1748,8 @@ class HomeScreenViewModel(
analytics = analytics,
sourceObjectTypeId = objectTypeWrapper.sourceObject.orEmpty(),
isCustomObjectType = objectTypeWrapper.sourceObject.isNullOrEmpty(),
isInEditMode = isInEditMode()
isInEditMode = isInEditMode(),
isAutoCreated = isAutoCreated
)
} else {
Timber.e("Failed to dispatch analytics: source type not found in types storage")
@ -1740,16 +1767,18 @@ class HomeScreenViewModel(
private fun isInEditMode() = mode.value == InteractionMode.Edit
private fun dispatchSelectHomeTabCustomSourceEvent(source: Widget.Source) {
private fun dispatchSelectHomeTabCustomSourceEvent(widget: Id, source: Widget.Source) {
viewModelScope.launch {
val isAutoCreated = widgets.value?.find { it.id == widget }?.isAutoCreated
val sourceObjectType = source.type
if (sourceObjectType != null) {
val objectTypeWrapper = storeOfObjectTypes.get(sourceObjectType)
if (objectTypeWrapper != null) {
sendSelectHomeTabEvent(
sendClickWidgetTitleEvent(
analytics = analytics,
sourceObjectTypeId = objectTypeWrapper.sourceObject.orEmpty(),
isCustomObjectType = objectTypeWrapper.sourceObject.isNullOrEmpty()
isCustomObjectType = objectTypeWrapper.sourceObject.isNullOrEmpty(),
isAutoCreated = isAutoCreated
)
} else {
Timber.e("Failed to dispatch analytics: source type not found in types storage")
@ -1771,9 +1800,11 @@ class HomeScreenViewModel(
}
when(source) {
is Widget.Source.Bundled -> {
val isAutoCreated = widgets.value?.find { it.id == subject.id }?.isAutoCreated
sendReorderWidgetEvent(
analytics = analytics,
bundled = source
bundled = source,
isAutoCreated = isAutoCreated
)
}
is Widget.Source.Default -> {

View file

@ -3,12 +3,11 @@ package com.anytypeio.anytype.presentation.widgets
import com.anytypeio.anytype.core_models.Block
import com.anytypeio.anytype.core_models.Config
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.ObjectType
import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_models.Relations
import com.anytypeio.anytype.core_models.Struct
import com.anytypeio.anytype.core_models.ext.asMap
import com.anytypeio.anytype.core_models.SupportedLayouts.isSupportedForWidgets
import com.anytypeio.anytype.core_models.ext.asMap
import com.anytypeio.anytype.core_models.widgets.BundledWidgetSourceIds
import com.anytypeio.anytype.domain.primitives.FieldParser
import com.anytypeio.anytype.presentation.widgets.WidgetView.Name
@ -20,6 +19,8 @@ sealed class Widget {
abstract val source: Source
abstract val config: Config
abstract val isAutoCreated: Boolean
/**
* @property [id] id of the widget
* @property [source] source for this widget - root object for a tree of objects.
@ -28,7 +29,8 @@ sealed class Widget {
override val id: Id,
override val source: Source,
override val config: Config,
val limit: Int = 0
override val isAutoCreated: Boolean = false,
val limit: Int = 0,
) : Widget()
/**
@ -39,6 +41,7 @@ sealed class Widget {
override val id: Id,
override val source: Source,
override val config: Config,
override val isAutoCreated: Boolean = false,
) : Widget()
/**
@ -49,6 +52,7 @@ sealed class Widget {
override val id: Id,
override val source: Source,
override val config: Config,
override val isAutoCreated: Boolean = false,
val isCompact: Boolean = false,
val limit: Int = 0
) : Widget()
@ -57,6 +61,7 @@ sealed class Widget {
override val id: Id,
override val source: Source.Default,
override val config: Config,
override val isAutoCreated: Boolean = false,
val limit: Int
) : Widget()
@ -64,6 +69,7 @@ sealed class Widget {
override val id: Id,
override val source: Source.Bundled.AllObjects,
override val config: Config,
override val isAutoCreated: Boolean = false,
) : Widget()
sealed class Source {
@ -157,7 +163,8 @@ fun List<Block>.parseWidgets(
Widget.AllObjects(
id = w.id,
source = source,
config = config
config = config,
isAutoCreated = widgetContent.isAutoAdded
)
)
} else {
@ -168,7 +175,8 @@ fun List<Block>.parseWidgets(
id = w.id,
source = source,
limit = widgetContent.limit,
config = config
config = config,
isAutoCreated = widgetContent.isAutoAdded
)
)
}
@ -178,7 +186,8 @@ fun List<Block>.parseWidgets(
Widget.Link(
id = w.id,
source = source,
config = config
config = config,
isAutoCreated = widgetContent.isAutoAdded
)
)
}
@ -189,7 +198,8 @@ fun List<Block>.parseWidgets(
id = w.id,
source = source,
limit = widgetContent.limit,
config = config
config = config,
isAutoCreated = widgetContent.isAutoAdded
)
)
}
@ -201,7 +211,8 @@ fun List<Block>.parseWidgets(
source = source,
isCompact = true,
limit = widgetContent.limit,
config = config
config = config,
isAutoCreated = widgetContent.isAutoAdded
)
)
}
@ -213,7 +224,8 @@ fun List<Block>.parseWidgets(
id = w.id,
source = source,
limit = widgetContent.limit,
config = config
config = config,
isAutoCreated = widgetContent.isAutoAdded
)
)
}