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
4 changes: 1 addition & 3 deletions src/components/actionbar/ComfyRunButton/ComfyQueueButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,7 @@ const queuePrompt = async (e: Event) => {
? 'Comfy.QueuePromptFront'
: 'Comfy.QueuePrompt'

if (isCloud) {
useTelemetry()?.trackRunButton({ subscribe_to_run: false })
}
useTelemetry()?.trackRunButton({ subscribe_to_run: false })

await commandStore.execute(commandId)
}
Expand Down
7 changes: 7 additions & 0 deletions src/components/dialog/content/ErrorDialogContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import { useI18n } from 'vue-i18n'
import NoResultsPlaceholder from '@/components/common/NoResultsPlaceholder.vue'
import FindIssueButton from '@/components/dialog/content/error/FindIssueButton.vue'
import { useCopyToClipboard } from '@/composables/useCopyToClipboard'
import { useTelemetry } from '@/platform/telemetry'
import { api } from '@/scripts/api'
import { app } from '@/scripts/app'
import { useCommandStore } from '@/stores/commandStore'
Expand Down Expand Up @@ -92,12 +93,18 @@ const showReport = () => {
const toast = useToast()
const { t } = useI18n()
const systemStatsStore = useSystemStatsStore()
const telemetry = useTelemetry()

const title = computed<string>(
() => error.nodeType ?? error.exceptionType ?? t('errorDialog.defaultTitle')
)

const showContactSupport = async () => {
telemetry?.trackHelpResourceClicked({
resource_type: 'help_feedback',
is_external: true,
source: 'error_dialog'
})
await useCommandStore().execute('Comfy.ContactSupport')
}

Expand Down
7 changes: 6 additions & 1 deletion src/components/dialog/content/credit/CreditTopUpOption.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ import Tag from 'primevue/tag'
import { onBeforeUnmount, ref } from 'vue'

import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
import { useTelemetry } from '@/platform/telemetry'

const authActions = useFirebaseAuthActions()
const telemetry = useTelemetry()

const {
amount,
Expand All @@ -61,8 +63,11 @@ const didClickBuyNow = ref(false)
const loading = ref(false)

const handleBuyNow = async () => {
const creditAmount = editable ? customAmount.value : amount
telemetry?.trackApiCreditTopupButtonPurchaseClicked(creditAmount)

loading.value = true
await authActions.purchaseCredits(editable ? customAmount.value : amount)
await authActions.purchaseCredits(creditAmount)
loading.value = false
didClickBuyNow.value = true
}
Expand Down
7 changes: 7 additions & 0 deletions src/components/dialog/content/setting/CreditsPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ import { computed, ref, watch } from 'vue'
import UserCredit from '@/components/common/UserCredit.vue'
import UsageLogsTable from '@/components/dialog/content/setting/UsageLogsTable.vue'
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
import { useTelemetry } from '@/platform/telemetry'
import { useDialogService } from '@/services/dialogService'
import { useCommandStore } from '@/stores/commandStore'
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
Expand All @@ -139,6 +140,7 @@ const dialogService = useDialogService()
const authStore = useFirebaseAuthStore()
const authActions = useFirebaseAuthActions()
const commandStore = useCommandStore()
const telemetry = useTelemetry()
const loading = computed(() => authStore.loading)
const balanceLoading = computed(() => authStore.isFetchingBalance)

Expand Down Expand Up @@ -168,6 +170,11 @@ const handleCreditsHistoryClick = async () => {
}

const handleMessageSupport = async () => {
telemetry?.trackHelpResourceClicked({
resource_type: 'help_feedback',
is_external: true,
source: 'credits_panel'
})
await commandStore.execute('Comfy.ContactSupport')
}

Expand Down
36 changes: 35 additions & 1 deletion src/components/helpcenter/HelpCenterMenuContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,14 @@

<script setup lang="ts">
import Button from 'primevue/button'
import { computed, nextTick, onMounted, ref } from 'vue'
import { computed, nextTick, onBeforeUnmount, onMounted, ref } from 'vue'
import type { CSSProperties, Component } from 'vue'
import { useI18n } from 'vue-i18n'

import PuzzleIcon from '@/components/icons/PuzzleIcon.vue'
import { isCloud } from '@/platform/distribution/types'
import { useSettingStore } from '@/platform/settings/settingStore'
import { useTelemetry } from '@/platform/telemetry'
import type { ReleaseNote } from '@/platform/updates/common/releaseService'
import { useReleaseStore } from '@/platform/updates/common/releaseStore'
import { useCommandStore } from '@/stores/commandStore'
Expand Down Expand Up @@ -188,6 +189,7 @@ const { t, locale } = useI18n()
const releaseStore = useReleaseStore()
const commandStore = useCommandStore()
const settingStore = useSettingStore()
const telemetry = useTelemetry()

// Emits
const emit = defineEmits<{
Expand All @@ -199,6 +201,7 @@ const isSubmenuVisible = ref(false)
const submenuRef = ref<HTMLElement | null>(null)
const submenuStyle = ref<CSSProperties>({})
let hoverTimeout: number | null = null
const openedAt = ref<number>(Date.now())

// Computed
const hasReleases = computed(() => releaseStore.releases.length > 0)
Expand All @@ -218,6 +221,7 @@ const moreItems = computed<MenuItem[]>(() => {
label: t('helpCenter.desktopUserGuide'),
visible: isElectron(),
action: () => {
trackResourceClick('docs', true)
const docsUrl =
electronAPI().getPlatform() === 'darwin'
? EXTERNAL_LINKS.DESKTOP_GUIDE_MACOS
Expand Down Expand Up @@ -273,6 +277,7 @@ const menuItems = computed<MenuItem[]>(() => {
icon: 'pi pi-book',
label: t('helpCenter.docs'),
action: () => {
trackResourceClick('docs', true)
openExternalLink(EXTERNAL_LINKS.DOCS)
emit('close')
}
Expand All @@ -283,6 +288,7 @@ const menuItems = computed<MenuItem[]>(() => {
icon: 'pi pi-discord',
label: 'Discord',
action: () => {
trackResourceClick('discord', true)
openExternalLink(EXTERNAL_LINKS.DISCORD)
emit('close')
}
Expand All @@ -293,6 +299,7 @@ const menuItems = computed<MenuItem[]>(() => {
icon: 'pi pi-github',
label: t('helpCenter.github'),
action: () => {
trackResourceClick('github', true)
openExternalLink(EXTERNAL_LINKS.GITHUB)
emit('close')
}
Expand All @@ -303,6 +310,7 @@ const menuItems = computed<MenuItem[]>(() => {
icon: 'pi pi-question-circle',
label: t('helpCenter.helpFeedback'),
action: () => {
trackResourceClick('help_feedback', false)
void commandStore.execute('Comfy.ContactSupport')
emit('close')
}
Expand All @@ -318,6 +326,7 @@ const menuItems = computed<MenuItem[]>(() => {
label: t('helpCenter.managerExtension'),
showRedDot: shouldShowManagerRedDot.value,
action: async () => {
trackResourceClick('manager', false)
await useManagerState().openManager({
initialTab: ManagerTab.All,
showToastOnLegacyError: false
Expand All @@ -341,6 +350,23 @@ const menuItems = computed<MenuItem[]>(() => {
})

// Utility Functions
const trackResourceClick = (
resourceType:
| 'docs'
| 'discord'
| 'github'
| 'help_feedback'
| 'manager'
| 'release_notes',
isExternal: boolean
): void => {
telemetry?.trackHelpResourceClicked({
resource_type: resourceType,
is_external: isExternal,
source: 'help_center'
})
}

const openExternalLink = (url: string): void => {
window.open(url, '_blank', 'noopener,noreferrer')
}
Expand Down Expand Up @@ -496,6 +522,7 @@ const onReinstall = (): void => {
}

const onReleaseClick = (release: ReleaseNote): void => {
trackResourceClick('release_notes', true)
void releaseStore.handleShowChangelog(release.version)
const versionAnchor = formatVersionAnchor(release.version)
const changelogUrl = `${getChangelogUrl()}#${versionAnchor}`
Expand All @@ -504,6 +531,7 @@ const onReleaseClick = (release: ReleaseNote): void => {
}

const onUpdate = (_: ReleaseNote): void => {
trackResourceClick('docs', true)
openExternalLink(EXTERNAL_LINKS.UPDATE_GUIDE)
emit('close')
}
Expand All @@ -518,10 +546,16 @@ const getChangelogUrl = (): string => {

// Lifecycle
onMounted(async () => {
telemetry?.trackHelpCenterOpened({ source: 'sidebar' })
if (!hasReleases.value) {
await releaseStore.fetchReleases()
}
})

onBeforeUnmount(() => {
const timeSpentSeconds = Math.round((Date.now() - openedAt.value) / 1000)
telemetry?.trackHelpCenterClosed({ time_spent_seconds: timeSpentSeconds })
})
</script>

<style scoped>
Expand Down
25 changes: 24 additions & 1 deletion src/components/searchbox/NodeSearchBox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
multiple
:option-label="'display_name'"
@complete="search($event.query)"
@option-select="emit('addNode', $event.value)"
@option-select="onAddNode($event.value)"
@focused-option-changed="setHoverSuggestion($event)"
>
<template #option="{ option }">
Expand All @@ -78,6 +78,7 @@
</template>

<script setup lang="ts">
import { debounce } from 'es-toolkit/compat'
import Button from 'primevue/button'
import Dialog from 'primevue/dialog'
import { computed, nextTick, onMounted, ref } from 'vue'
Expand All @@ -88,6 +89,7 @@ import AutoCompletePlus from '@/components/primevueOverride/AutoCompletePlus.vue
import NodeSearchFilter from '@/components/searchbox/NodeSearchFilter.vue'
import NodeSearchItem from '@/components/searchbox/NodeSearchItem.vue'
import { useSettingStore } from '@/platform/settings/settingStore'
import { useTelemetry } from '@/platform/telemetry'
import type { ComfyNodeDefImpl } from '@/stores/nodeDefStore'
import { useNodeDefStore, useNodeFrequencyStore } from '@/stores/nodeDefStore'
import type { FuseFilterWithValue } from '@/utils/fuseUtil'
Expand All @@ -96,6 +98,7 @@ import SearchFilterChip from '../common/SearchFilterChip.vue'

const settingStore = useSettingStore()
const { t } = useI18n()
const telemetry = useTelemetry()

const enableNodePreview = computed(() =>
settingStore.get('Comfy.NodeSearchBoxImpl.NodePreview')
Expand All @@ -117,6 +120,14 @@ const placeholder = computed(() => {

const nodeDefStore = useNodeDefStore()
const nodeFrequencyStore = useNodeFrequencyStore()

// Debounced search tracking (500ms as per implementation plan)
const debouncedTrackSearch = debounce((query: string) => {
if (query.trim()) {
telemetry?.trackNodeSearch({ query })
}
}, 500)

const search = (query: string) => {
const queryIsEmpty = query === '' && filters.length === 0
currentQuery.value = query
Expand All @@ -127,10 +138,22 @@ const search = (query: string) => {
limit: searchLimit
})
]

// Track search queries with debounce
debouncedTrackSearch(query)
}

const emit = defineEmits(['addFilter', 'removeFilter', 'addNode'])

// Track node selection and emit addNode event
const onAddNode = (nodeDef: ComfyNodeDefImpl) => {
telemetry?.trackNodeSearchResultSelected({
node_type: nodeDef.name,
last_query: currentQuery.value
})
emit('addNode', nodeDef)
}

let inputElement: HTMLInputElement | null = null
const reFocusInput = async () => {
inputElement ??= document.getElementById(inputId) as HTMLInputElement
Expand Down
Loading
Loading