mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-29 18:52:19 +00:00
Cloud/tracking v2 (#6400)
## Summary <!-- One sentence describing what changed and why. --> ## Changes - **What**: <!-- Core functionality added/modified --> - **Breaking**: <!-- Any breaking changes (if none, remove this line) --> - **Dependencies**: <!-- New dependencies (if none, remove this line) --> ## Review Focus <!-- Critical design decisions or edge cases that need attention --> <!-- If this PR fixes an issue, uncomment and update the line below --> <!-- Fixes #ISSUE_NUMBER --> ## Screenshots (if applicable) <!-- Add screenshots or video recording to help explain your changes --> ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6400-Cloud-tracking-v2-29c6d73d365081a1ae32e9337f510a9e) by [Unito](https://www.unito.io) --------- Co-authored-by: Arjan Singh <arjan@comfy.org>
This commit is contained in:
@@ -48,7 +48,9 @@ import { useErrorHandling } from '@/composables/useErrorHandling'
|
||||
import { useProgressFavicon } from '@/composables/useProgressFavicon'
|
||||
import { SERVER_CONFIG_ITEMS } from '@/constants/serverConfig'
|
||||
import { i18n, loadLocale } from '@/i18n'
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { useTelemetry } from '@/platform/telemetry'
|
||||
import { useFrontendVersionMismatchWarning } from '@/platform/updates/common/useFrontendVersionMismatchWarning'
|
||||
import { useVersionCompatibilityStore } from '@/platform/updates/common/versionCompatibilityStore'
|
||||
import type { StatusWsMessageStatus } from '@/schemas/apiSchema'
|
||||
@@ -59,6 +61,7 @@ import { useKeybindingService } from '@/services/keybindingService'
|
||||
import { useAssetsStore } from '@/stores/assetsStore'
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
import { useExecutionStore } from '@/stores/executionStore'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useMenuItemStore } from '@/stores/menuItemStore'
|
||||
import { useModelStore } from '@/stores/modelStore'
|
||||
import { useNodeDefStore, useNodeFrequencyStore } from '@/stores/nodeDefStore'
|
||||
@@ -87,6 +90,13 @@ const assetsStore = useAssetsStore()
|
||||
const versionCompatibilityStore = useVersionCompatibilityStore()
|
||||
const graphCanvasContainerRef = ref<HTMLDivElement | null>(null)
|
||||
|
||||
const telemetry = useTelemetry()
|
||||
const firebaseAuthStore = useFirebaseAuthStore()
|
||||
let hasTrackedLogin = false
|
||||
let visibilityListener: (() => void) | null = null
|
||||
let tabCountInterval: number | null = null
|
||||
let tabCountChannel: BroadcastChannel | null = null
|
||||
|
||||
watch(
|
||||
() => colorPaletteStore.completedActivePalette,
|
||||
(newTheme) => {
|
||||
@@ -250,6 +260,22 @@ onBeforeUnmount(() => {
|
||||
api.removeEventListener('reconnecting', onReconnecting)
|
||||
api.removeEventListener('reconnected', onReconnected)
|
||||
executionStore.unbindExecutionEvents()
|
||||
|
||||
// Clean up page visibility listener
|
||||
if (visibilityListener) {
|
||||
document.removeEventListener('visibilitychange', visibilityListener)
|
||||
visibilityListener = null
|
||||
}
|
||||
|
||||
// Clean up tab count tracking
|
||||
if (tabCountInterval) {
|
||||
window.clearInterval(tabCountInterval)
|
||||
tabCountInterval = null
|
||||
}
|
||||
if (tabCountChannel) {
|
||||
tabCountChannel.close()
|
||||
tabCountChannel = null
|
||||
}
|
||||
})
|
||||
|
||||
useEventListener(window, 'keydown', useKeybindingService().keybindHandler)
|
||||
@@ -268,6 +294,61 @@ void nextTick(() => {
|
||||
|
||||
const onGraphReady = () => {
|
||||
runWhenGlobalIdle(() => {
|
||||
// Track user login when app is ready in graph view (cloud only)
|
||||
if (isCloud && firebaseAuthStore.isAuthenticated && !hasTrackedLogin) {
|
||||
telemetry?.trackUserLoggedIn()
|
||||
hasTrackedLogin = true
|
||||
}
|
||||
|
||||
// Set up page visibility tracking (cloud only)
|
||||
if (isCloud && telemetry && !visibilityListener) {
|
||||
visibilityListener = () => {
|
||||
telemetry.trackPageVisibilityChanged({
|
||||
visibility_state: document.visibilityState as 'visible' | 'hidden'
|
||||
})
|
||||
}
|
||||
document.addEventListener('visibilitychange', visibilityListener)
|
||||
}
|
||||
|
||||
// Set up tab count tracking (cloud only)
|
||||
if (isCloud && telemetry && !tabCountInterval) {
|
||||
tabCountChannel = new BroadcastChannel('comfyui-tab-count')
|
||||
const activeTabs = new Map<string, number>()
|
||||
const currentTabId = crypto.randomUUID()
|
||||
|
||||
// Listen for heartbeats from other tabs
|
||||
tabCountChannel.onmessage = (event) => {
|
||||
if (
|
||||
event.data.type === 'heartbeat' &&
|
||||
event.data.tabId !== currentTabId
|
||||
) {
|
||||
activeTabs.set(event.data.tabId, Date.now())
|
||||
}
|
||||
}
|
||||
|
||||
// 30-second heartbeat interval
|
||||
tabCountInterval = window.setInterval(() => {
|
||||
const now = Date.now()
|
||||
|
||||
// Clean up stale tabs (no heartbeat for 45 seconds)
|
||||
activeTabs.forEach((lastHeartbeat, tabId) => {
|
||||
if (now - lastHeartbeat > 45000) {
|
||||
activeTabs.delete(tabId)
|
||||
}
|
||||
})
|
||||
|
||||
// Broadcast our heartbeat
|
||||
tabCountChannel?.postMessage({ type: 'heartbeat', tabId: currentTabId })
|
||||
|
||||
// Track tab count (include current tab)
|
||||
const tabCount = activeTabs.size + 1
|
||||
telemetry.trackTabCount({ tab_count: tabCount })
|
||||
}, 30000)
|
||||
|
||||
// Send initial heartbeat
|
||||
tabCountChannel.postMessage({ type: 'heartbeat', tabId: currentTabId })
|
||||
}
|
||||
|
||||
// Setting values now available after comfyApp.setup.
|
||||
// Load keybindings.
|
||||
wrapWithErrorHandling(useKeybindingService().registerUserKeybindings)()
|
||||
|
||||
Reference in New Issue
Block a user