Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/components/actionbar/ComfyActionbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import type { Ref } from 'vue'
import { computed, inject, nextTick, onMounted, ref, watch } from 'vue'

import { useSettingStore } from '@/platform/settings/settingStore'
import { useTelemetry } from '@/platform/telemetry'
import { cn } from '@/utils/tailwindUtil'

import ComfyRunButton from './ComfyRunButton'
Expand Down Expand Up @@ -121,6 +122,15 @@ watch(visible, async (newVisible) => {
}
})

/**
* Track run button handle drag start using mousedown on the drag handle.
*/
useEventListener(dragHandleRef, 'mousedown', () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'actionbar_run_handle_drag_start'
})
})

const lastDragState = ref({
x: x.value,
y: y.value,
Expand Down
6 changes: 6 additions & 0 deletions src/components/actionbar/ComfyRunButton/ComfyQueueButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ const queueModeMenuItemLookup = computed(() => {
label: `${t('menu.run')} (${t('menu.onChange')})`,
tooltip: t('menu.onChangeTooltip'),
command: () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'queue_mode_option_run_on_change_selected'
})
queueMode.value = 'change'
}
}
Expand All @@ -128,6 +131,9 @@ const queueModeMenuItemLookup = computed(() => {
label: `${t('menu.run')} (${t('menu.instant')})`,
tooltip: t('menu.instantTooltip'),
command: () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'queue_mode_option_run_instant_selected'
})
queueMode.value = 'instant'
}
}
Expand Down
9 changes: 7 additions & 2 deletions src/components/breadcrumb/SubgraphBreadcrumb.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { computed, onUpdated, ref, watch } from 'vue'

import SubgraphBreadcrumbItem from '@/components/breadcrumb/SubgraphBreadcrumbItem.vue'
import { useOverflowObserver } from '@/composables/element/useOverflowObserver'
import { useTelemetry } from '@/platform/telemetry'
import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore'
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
import { useSubgraphNavigationStore } from '@/stores/subgraphNavigationStore'
Expand Down Expand Up @@ -73,7 +74,9 @@ const items = computed(() => {
command: () => {
const canvas = useCanvasStore().getCanvas()
if (!canvas.graph) throw new TypeError('Canvas has no graph')

useTelemetry()?.trackUiButtonClicked({
button_id: 'breadcrumb_subgraph_item_selected'
})
canvas.setGraph(subgraph)
},
updateTitle: (title: string) => {
Expand All @@ -97,7 +100,9 @@ const home = computed(() => ({
command: () => {
const canvas = useCanvasStore().getCanvas()
if (!canvas.graph) throw new TypeError('Canvas has no graph')

useTelemetry()?.trackUiButtonClicked({
button_id: 'breadcrumb_subgraph_root_selected'
})
canvas.setGraph(canvas.graph.rootGraph)
}
}))
Expand Down
3 changes: 3 additions & 0 deletions src/components/dialog/content/ErrorDialogContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ const repoName = 'ComfyUI'
const reportContent = ref('')
const reportOpen = ref(false)
const showReport = () => {
telemetry?.trackUiButtonClicked({
button_id: 'error_dialog_show_report_clicked'
})
reportOpen.value = true
}
const toast = useToast()
Expand Down
5 changes: 5 additions & 0 deletions src/components/dialog/content/error/FindIssueButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import Button from 'primevue/button'
import { computed } from 'vue'

import { useTelemetry } from '@/platform/telemetry'

const props = defineProps<{
errorMessage: string
repoOwner: string
Expand All @@ -20,6 +22,9 @@ const props = defineProps<{
const queryString = computed(() => props.errorMessage + ' is:issue')

const openGitHubIssues = () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'error_dialog_find_existing_issues_clicked'
})
const query = encodeURIComponent(queryString.value)
const url = `https://github.com/${props.repoOwner}/${props.repoName}/issues?q=${query}`
window.open(url, '_blank')
Expand Down
11 changes: 10 additions & 1 deletion src/components/graph/GraphCanvasMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
:aria-label="linkVisibilityAriaLabel"
data-testid="toggle-link-visibility-button"
:style="stringifiedMinimapStyles.buttonStyles"
@click="() => commandStore.execute('Comfy.Canvas.ToggleLinkVisibility')"
@click="onLinkVisibilityToggleClick"
>
<template #icon>
<i class="icon-[lucide--route-off]" />
Expand All @@ -127,6 +127,7 @@ import { useI18n } from 'vue-i18n'
import { useZoomControls } from '@/composables/useZoomControls'
import { LiteGraph } from '@/lib/litegraph/src/litegraph'
import { useSettingStore } from '@/platform/settings/settingStore'
import { useTelemetry } from '@/platform/telemetry'
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
import { useCanvasInteractions } from '@/renderer/core/canvas/useCanvasInteractions'
import { useMinimap } from '@/renderer/extensions/minimap/composables/useMinimap'
Expand Down Expand Up @@ -263,6 +264,14 @@ onMounted(() => {
canvasStore.initScaleSync()
})

// Track hide/show links button click and execute the command.
const onLinkVisibilityToggleClick = () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'graph_menu_hide_links_toggle_clicked'
})
void commandStore.execute('Comfy.Canvas.ToggleLinkVisibility')
}

onBeforeUnmount(() => {
canvasStore.cleanupScaleSync()
})
Expand Down
9 changes: 8 additions & 1 deletion src/components/graph/selectionToolbox/InfoButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@
import Button from 'primevue/button'

import { useSelectionState } from '@/composables/graph/useSelectionState'
import { useTelemetry } from '@/platform/telemetry'

const { showNodeHelp: toggleHelp } = useSelectionState()
const { showNodeHelp } = useSelectionState()
const toggleHelp = () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'selection_toolbox_node_info_opened'
})
showNodeHelp()
}
</script>
28 changes: 27 additions & 1 deletion src/components/sidebar/SideToolbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import ExtensionSlot from '@/components/common/ExtensionSlot.vue'
import SidebarBottomPanelToggleButton from '@/components/sidebar/SidebarBottomPanelToggleButton.vue'
import SidebarShortcutsToggleButton from '@/components/sidebar/SidebarShortcutsToggleButton.vue'
import { useSettingStore } from '@/platform/settings/settingStore'
import { useTelemetry } from '@/platform/telemetry'
import { useCommandStore } from '@/stores/commandStore'
import { useKeybindingStore } from '@/stores/keybindingStore'
import { useUserStore } from '@/stores/userStore'
Expand Down Expand Up @@ -67,10 +68,35 @@ const isSmall = computed(
const tabs = computed(() => workspaceStore.getSidebarTabs())
const selectedTab = computed(() => workspaceStore.sidebarTab.activeSidebarTab)

const onTabClick = async (item: SidebarTabExtension) =>
const onTabClick = async (item: SidebarTabExtension) => {
const telemetry = useTelemetry()

const isNodeLibraryTab = item.id === 'node-library'
const isModelLibraryTab = item.id === 'model-library'
const isWorkflowsTab = item.id === 'workflows'
const isAssetsTab = item.id === 'assets'

if (isNodeLibraryTab)
telemetry?.trackUiButtonClicked({
button_id: 'sidebar_tab_node_library_selected'
})
else if (isModelLibraryTab)
telemetry?.trackUiButtonClicked({
button_id: 'sidebar_tab_model_library_selected'
})
else if (isWorkflowsTab)
telemetry?.trackUiButtonClicked({
button_id: 'sidebar_tab_workflows_selected'
})
else if (isAssetsTab)
telemetry?.trackUiButtonClicked({
button_id: 'sidebar_tab_assets_media_selected'
})

await commandStore.commands
.find((cmd) => cmd.id === `Workspace.ToggleSidebarTab.${item.id}`)
?.function?.()
}

const keybindingStore = useKeybindingStore()
const getTabTooltipSuffix = (tab: SidebarTabExtension) => {
Expand Down
9 changes: 8 additions & 1 deletion src/components/sidebar/SidebarBottomPanelToggleButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<SidebarIcon
:tooltip="$t('menu.toggleBottomPanel')"
:selected="bottomPanelStore.activePanel == 'terminal'"
@click="bottomPanelStore.toggleBottomPanel"
@click="onClick"
>
<template #icon>
<i-ph:terminal-bold />
Expand All @@ -11,9 +11,16 @@
</template>

<script setup lang="ts">
import { useTelemetry } from '@/platform/telemetry'
import { useBottomPanelStore } from '@/stores/workspace/bottomPanelStore'

import SidebarIcon from './SidebarIcon.vue'

const bottomPanelStore = useBottomPanelStore()
const onClick = () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'sidebar_bottom_panel_console_toggled'
})
bottomPanelStore.toggleBottomPanel()
}
</script>
4 changes: 4 additions & 0 deletions src/components/sidebar/SidebarHelpCenterIcon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import { computed, onMounted } from 'vue'

import HelpCenterMenuContent from '@/components/helpcenter/HelpCenterMenuContent.vue'
import { useSettingStore } from '@/platform/settings/settingStore'
import { useTelemetry } from '@/platform/telemetry'
import { useReleaseStore } from '@/platform/updates/common/releaseStore'
import ReleaseNotificationToast from '@/platform/updates/components/ReleaseNotificationToast.vue'
import WhatsNewPopup from '@/platform/updates/components/WhatsNewPopup.vue'
Expand Down Expand Up @@ -100,6 +101,9 @@ const sidebarLocation = computed(() =>
const sidebarSize = computed(() => settingStore.get('Comfy.Sidebar.Size'))

const toggleHelpCenter = () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'sidebar_help_center_toggled'
})
helpCenterStore.toggle()
}

Expand Down
4 changes: 4 additions & 0 deletions src/components/sidebar/SidebarShortcutsToggleButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'

import { useTelemetry } from '@/platform/telemetry'
import { useCommandStore } from '@/stores/commandStore'
import { useBottomPanelStore } from '@/stores/workspace/bottomPanelStore'

Expand All @@ -34,6 +35,9 @@ const tooltipText = computed(
)

const toggleShortcutsPanel = () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'sidebar_shortcuts_panel_toggled'
})
bottomPanelStore.togglePanel('shortcuts')
}
</script>
4 changes: 4 additions & 0 deletions src/components/sidebar/SidebarTemplatesButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { computed } from 'vue'

import { useWorkflowTemplateSelectorDialog } from '@/composables/useWorkflowTemplateSelectorDialog'
import { useSettingStore } from '@/platform/settings/settingStore'
import { useTelemetry } from '@/platform/telemetry'

import SidebarIcon from './SidebarIcon.vue'

Expand All @@ -24,6 +25,9 @@ const isSmall = computed(
)

const openTemplates = () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'sidebar_templates_dialog_opened'
})
useWorkflowTemplateSelectorDialog().show('sidebar')
}
</script>
21 changes: 19 additions & 2 deletions src/platform/settings/components/SettingItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import FormItem from '@/components/common/FormItem.vue'
import { st } from '@/i18n'
import { useSettingStore } from '@/platform/settings/settingStore'
import type { SettingOption, SettingParams } from '@/platform/settings/types'
import { useTelemetry } from '@/platform/telemetry'
import type { Settings } from '@/schemas/apiSchema'
import { normalizeI18nKey } from '@/utils/formatUtil'

const props = defineProps<{
Expand Down Expand Up @@ -75,7 +77,22 @@ const formItem = computed(() => {

const settingStore = useSettingStore()
const settingValue = computed(() => settingStore.get(props.setting.id))
const updateSettingValue = async (value: any) => {
await settingStore.set(props.setting.id, value)
const updateSettingValue = async <K extends keyof Settings>(
newValue: Settings[K]
) => {
const telemetry = useTelemetry()
const settingId = props.setting.id
const previousValue = settingValue.value

await settingStore.set(settingId, newValue)

const normalizedValue = settingStore.get(settingId)
if (previousValue !== normalizedValue) {
telemetry?.trackSettingChanged({
setting_id: settingId,
previous_value: previousValue,
new_value: normalizedValue
})
}
}
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import type {
NodeSearchResultMetadata,
PageVisibilityMetadata,
RunButtonProperties,
SettingChangedMetadata,
SurveyResponses,
TabCountMetadata,
TelemetryEventName,
Expand Down Expand Up @@ -506,6 +507,10 @@ export class MixpanelTelemetryProvider implements TelemetryProvider {
this.trackEvent(TelemetryEvents.UI_BUTTON_CLICKED, metadata)
}

trackSettingChanged(metadata: SettingChangedMetadata): void {
this.trackEvent(TelemetryEvents.SETTING_CHANGED, metadata)
}

trackWorkflowExecution(): void {
if (this.isOnboardingMode) {
// During onboarding, track basic execution without workflow context
Expand Down
16 changes: 16 additions & 0 deletions src/platform/telemetry/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,15 @@ export interface TabCountMetadata {
tab_count: number
}

/**
* Settings change metadata
*/
export interface SettingChangedMetadata {
setting_id: string
previous_value?: unknown
new_value?: unknown
}

/**
* Node search metadata
*/
Expand Down Expand Up @@ -298,6 +307,9 @@ export interface TelemetryProvider {
// Generic UI button click events
trackUiButtonClicked(metadata: UiButtonClickMetadata): void

// Settings events
trackSettingChanged(metadata: SettingChangedMetadata): void

// Help center events
trackHelpCenterOpened(metadata: HelpCenterOpenedMetadata): void
trackHelpResourceClicked(metadata: HelpResourceClickedMetadata): void
Expand Down Expand Up @@ -369,6 +381,9 @@ export const TelemetryEvents = {
// Template Filter Analytics
TEMPLATE_FILTER_CHANGED: 'app:template_filter_changed',

// Settings
SETTING_CHANGED: 'app:setting_changed',

// Help Center Analytics
HELP_CENTER_OPENED: 'app:help_center_opened',
HELP_RESOURCE_CLICKED: 'app:help_resource_clicked',
Expand Down Expand Up @@ -416,6 +431,7 @@ export type TelemetryEventProperties =
| NodeSearchResultMetadata
| TemplateFilterMetadata
| UiButtonClickMetadata
| SettingChangedMetadata
| HelpCenterOpenedMetadata
| HelpResourceClickedMetadata
| HelpCenterClosedMetadata
Expand Down
4 changes: 4 additions & 0 deletions src/renderer/extensions/vueNodes/components/LGraphNode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ import { toggleNodeOptions } from '@/composables/graph/useMoreOptionsMenu'
import { useErrorHandling } from '@/composables/useErrorHandling'
import { LiteGraph } from '@/lib/litegraph/src/litegraph'
import { useSettingStore } from '@/platform/settings/settingStore'
import { useTelemetry } from '@/platform/telemetry'
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
import { useCanvasInteractions } from '@/renderer/core/canvas/useCanvasInteractions'
import { TransformStateKey } from '@/renderer/core/layout/injectionKeys'
Expand Down Expand Up @@ -343,6 +344,9 @@ const handleHeaderTitleUpdate = (newTitle: string) => {
}

const handleEnterSubgraph = () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'graph_node_open_subgraph_clicked'
})
const graph = app.graph?.rootGraph || app.graph
if (!graph) {
console.warn('LGraphNode: No graph available for subgraph navigation')
Expand Down
Loading
Loading