mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-06-03 11:54:07 +00:00
Compare commits
1 Commits
v1.46.8
...
feat/node-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e1ede9a89 |
@@ -67,6 +67,7 @@ import { LGraphNode, LiteGraph } from '@/lib/litegraph/src/litegraph'
|
||||
import type { CanvasPointerEvent } from '@/lib/litegraph/src/types/events'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { useSurveyFeatureTracking } from '@/platform/surveys/useSurveyFeatureTracking'
|
||||
import { withNodeAddSource } from '@/platform/telemetry/nodeAdded/nodeAddSource'
|
||||
import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore'
|
||||
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
||||
import { useLitegraphService } from '@/services/litegraphService'
|
||||
@@ -140,10 +141,12 @@ function closeDialog() {
|
||||
|
||||
function addNode(nodeDef: ComfyNodeDefImpl, dragEvent?: MouseEvent) {
|
||||
const followCursor = settingStore.get('Comfy.NodeSearchBoxImpl.FollowCursor')
|
||||
const node = litegraphService.addNodeOnGraph(
|
||||
nodeDef,
|
||||
{ pos: getNewNodeLocation() },
|
||||
{ ghost: useSearchBoxV2.value && followCursor, dragEvent }
|
||||
const node = withNodeAddSource('search_modal', () =>
|
||||
litegraphService.addNodeOnGraph(
|
||||
nodeDef,
|
||||
{ pos: getNewNodeLocation() },
|
||||
{ ghost: useSearchBoxV2.value && followCursor, dragEvent }
|
||||
)
|
||||
)
|
||||
if (!node) return
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ import ModelTreeLeaf from '@/components/sidebar/tabs/modelLibrary/ModelTreeLeaf.
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { useTreeExpansion } from '@/composables/useTreeExpansion'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { withNodeAddSource } from '@/platform/telemetry/nodeAdded/nodeAddSource'
|
||||
import { useLitegraphService } from '@/services/litegraphService'
|
||||
import { useAssetDownloadStore } from '@/stores/assetDownloadStore'
|
||||
import type { ComfyModelDef, ModelFolder } from '@/stores/modelStore'
|
||||
@@ -155,8 +156,8 @@ const renderedRoot = computed<TreeExplorerNode<ModelOrFolder>>(() => {
|
||||
if (this.leaf && model) {
|
||||
const provider = modelToNodeStore.getNodeProvider(model.directory)
|
||||
if (provider) {
|
||||
const graphNode = useLitegraphService().addNodeOnGraph(
|
||||
provider.nodeDef
|
||||
const graphNode = withNodeAddSource('sidebar_drag', () =>
|
||||
useLitegraphService().addNodeOnGraph(provider.nodeDef)
|
||||
)
|
||||
const widget = graphNode?.widgets?.find(
|
||||
(widget) => widget.name === provider.key
|
||||
|
||||
@@ -189,6 +189,7 @@ import NodeTreeFolder from '@/components/sidebar/tabs/nodeLibrary/NodeTreeFolder
|
||||
import NodeTreeLeaf from '@/components/sidebar/tabs/nodeLibrary/NodeTreeLeaf.vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { useTreeExpansion } from '@/composables/useTreeExpansion'
|
||||
import { withNodeAddSource } from '@/platform/telemetry/nodeAdded/nodeAddSource'
|
||||
import { useLitegraphService } from '@/services/litegraphService'
|
||||
import {
|
||||
DEFAULT_GROUPING_ID,
|
||||
@@ -321,8 +322,11 @@ const renderedRoot = computed<TreeExplorerNode<ComfyNodeDefImpl>>(() => {
|
||||
}
|
||||
},
|
||||
handleClick(e: MouseEvent) {
|
||||
if (this.leaf && this.data) {
|
||||
useLitegraphService().addNodeOnGraph(this.data)
|
||||
const nodeDef = this.data
|
||||
if (this.leaf && nodeDef) {
|
||||
withNodeAddSource('sidebar_drag', () =>
|
||||
useLitegraphService().addNodeOnGraph(nodeDef)
|
||||
)
|
||||
} else {
|
||||
toggleNodeOnEvent(e, this)
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import NodePreview from '@/components/node/NodePreview.vue'
|
||||
import NodeTreeFolder from '@/components/sidebar/tabs/nodeLibrary/NodeTreeFolder.vue'
|
||||
import NodeTreeLeaf from '@/components/sidebar/tabs/nodeLibrary/NodeTreeLeaf.vue'
|
||||
import { useTreeExpansion } from '@/composables/useTreeExpansion'
|
||||
import { withNodeAddSource } from '@/platform/telemetry/nodeAdded/nodeAddSource'
|
||||
import { useLitegraphService } from '@/services/litegraphService'
|
||||
import { useNodeBookmarkStore } from '@/stores/nodeBookmarkStore'
|
||||
import type { ComfyNodeDefImpl } from '@/stores/nodeDefStore'
|
||||
@@ -183,8 +184,11 @@ const renderedBookmarkedRoot = computed<TreeExplorerNode<ComfyNodeDefImpl>>(
|
||||
await nodeBookmarkStore.addBookmark(nodePath)
|
||||
},
|
||||
handleClick(e: MouseEvent) {
|
||||
if (this.leaf && this.data) {
|
||||
useLitegraphService().addNodeOnGraph(this.data)
|
||||
const nodeDef = this.data
|
||||
if (this.leaf && nodeDef) {
|
||||
withNodeAddSource('sidebar_drag', () =>
|
||||
useLitegraphService().addNodeOnGraph(nodeDef)
|
||||
)
|
||||
} else {
|
||||
toggleNodeOnEvent(e, node)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ref, shallowRef } from 'vue'
|
||||
|
||||
import { withNodeAddSource } from '@/platform/telemetry/nodeAdded/nodeAddSource'
|
||||
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
||||
import { useLitegraphService } from '@/services/litegraphService'
|
||||
import type { ComfyNodeDefImpl } from '@/stores/nodeDefStore'
|
||||
@@ -37,7 +38,8 @@ function isOverCanvas(clientX: number, clientY: number): boolean {
|
||||
}
|
||||
|
||||
function addNodeAtPosition(clientX: number, clientY: number): boolean {
|
||||
if (!draggedNode.value) return false
|
||||
const nodeDef = draggedNode.value
|
||||
if (!nodeDef) return false
|
||||
const canvas = useCanvasStore().canvas
|
||||
if (!canvas) return false
|
||||
if (!isOverCanvas(clientX, clientY)) return false
|
||||
@@ -46,7 +48,9 @@ function addNodeAtPosition(clientX: number, clientY: number): boolean {
|
||||
clientX,
|
||||
clientY
|
||||
} as PointerEvent)
|
||||
const node = useLitegraphService().addNodeOnGraph(draggedNode.value, { pos })
|
||||
const node = withNodeAddSource('sidebar_drag', () =>
|
||||
useLitegraphService().addNodeOnGraph(nodeDef, { pos })
|
||||
)
|
||||
if (node) canvas.selectItems([node])
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { mapTaskOutputToAssetItem } from '@/platform/assets/composables/media/as
|
||||
import { useMediaAssetActions } from '@/platform/assets/composables/useMediaAssetActions'
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { withNodeAddSource } from '@/platform/telemetry/nodeAdded/nodeAddSource'
|
||||
import { useWorkflowService } from '@/platform/workflow/core/services/workflowService'
|
||||
import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore'
|
||||
import type { ResultItem, ResultItemType } from '@/schemas/apiSchema'
|
||||
@@ -146,9 +147,11 @@ export function useJobMenu(
|
||||
|
||||
const nodeDef = nodeDefStore.nodeDefsByName[nodeType]
|
||||
if (!nodeDef) return
|
||||
const node = litegraphService.addNodeOnGraph(nodeDef, {
|
||||
pos: litegraphService.getCanvasCenter()
|
||||
})
|
||||
const node = withNodeAddSource('programmatic', () =>
|
||||
litegraphService.addNodeOnGraph(nodeDef, {
|
||||
pos: litegraphService.getCanvasCenter()
|
||||
})
|
||||
)
|
||||
|
||||
if (!node) return
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useSharedCanvasPositionConversion } from '@/composables/element/useCanv
|
||||
import { usePragmaticDroppable } from '@/composables/usePragmaticDragAndDrop'
|
||||
import type { LGraphNode, Point } from '@/lib/litegraph/src/litegraph'
|
||||
import { LiteGraph } from '@/lib/litegraph/src/litegraph'
|
||||
import { withNodeAddSource } from '@/platform/telemetry/nodeAdded/nodeAddSource'
|
||||
import { useWorkflowService } from '@/platform/workflow/core/services/workflowService'
|
||||
import { ComfyWorkflow } from '@/platform/workflow/management/stores/workflowStore'
|
||||
import { app as comfyApp } from '@/scripts/app'
|
||||
@@ -37,7 +38,9 @@ export const useCanvasDrop = (canvasRef: Ref<HTMLCanvasElement | null>) => {
|
||||
// Add an offset on y to make sure after adding the node, the cursor
|
||||
// is on the node (top left corner)
|
||||
pos[1] += LiteGraph.NODE_TITLE_HEIGHT
|
||||
litegraphService.addNodeOnGraph(nodeDef, { pos })
|
||||
withNodeAddSource('sidebar_drag', () =>
|
||||
litegraphService.addNodeOnGraph(nodeDef, { pos })
|
||||
)
|
||||
} else if (node.data instanceof ComfyModelDef) {
|
||||
const model = node.data
|
||||
const pos = basePos
|
||||
@@ -58,11 +61,8 @@ export const useCanvasDrop = (canvasRef: Ref<HTMLCanvasElement | null>) => {
|
||||
if (!targetGraphNode) {
|
||||
const provider = modelToNodeStore.getNodeProvider(model.directory)
|
||||
if (provider) {
|
||||
targetGraphNode = litegraphService.addNodeOnGraph(
|
||||
provider.nodeDef,
|
||||
{
|
||||
pos
|
||||
}
|
||||
targetGraphNode = withNodeAddSource('sidebar_drag', () =>
|
||||
litegraphService.addNodeOnGraph(provider.nodeDef, { pos })
|
||||
)
|
||||
targetProvider = provider
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import ConfirmationDialogContent from '@/components/dialog/content/ConfirmationD
|
||||
import { downloadFile } from '@/base/common/downloadUtil'
|
||||
import { useCopyToClipboard } from '@/composables/useCopyToClipboard'
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
import { withNodeAddSource } from '@/platform/telemetry/nodeAdded/nodeAddSource'
|
||||
import { useWorkflowActionsService } from '@/platform/workflow/core/services/workflowActionsService'
|
||||
import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore'
|
||||
import { extractWorkflowFromAsset } from '@/platform/workflow/utils/workflowExtractionUtil'
|
||||
@@ -280,9 +281,11 @@ export function useMediaAssetActions() {
|
||||
return
|
||||
}
|
||||
|
||||
const node = litegraphService.addNodeOnGraph(nodeDef, {
|
||||
pos: litegraphService.getCanvasCenter()
|
||||
})
|
||||
const node = withNodeAddSource('programmatic', () =>
|
||||
litegraphService.addNodeOnGraph(nodeDef, {
|
||||
pos: litegraphService.getCanvasCenter()
|
||||
})
|
||||
)
|
||||
|
||||
if (!node) {
|
||||
toast.add({
|
||||
@@ -425,12 +428,14 @@ export function useMediaAssetActions() {
|
||||
}
|
||||
|
||||
const center = litegraphService.getCanvasCenter()
|
||||
const node = litegraphService.addNodeOnGraph(nodeDef, {
|
||||
pos: [
|
||||
center[0] + nodeIndex * NODE_OFFSET,
|
||||
center[1] + nodeIndex * NODE_OFFSET
|
||||
]
|
||||
})
|
||||
const node = withNodeAddSource('programmatic', () =>
|
||||
litegraphService.addNodeOnGraph(nodeDef, {
|
||||
pos: [
|
||||
center[0] + nodeIndex * NODE_OFFSET,
|
||||
center[1] + nodeIndex * NODE_OFFSET
|
||||
]
|
||||
})
|
||||
)
|
||||
|
||||
if (!node) {
|
||||
failed++
|
||||
|
||||
@@ -12,6 +12,7 @@ import type {
|
||||
HelpCenterClosedMetadata,
|
||||
HelpCenterOpenedMetadata,
|
||||
HelpResourceClickedMetadata,
|
||||
NodeAddedMetadata,
|
||||
NodeSearchMetadata,
|
||||
NodeSearchResultMetadata,
|
||||
PageViewMetadata,
|
||||
@@ -198,6 +199,10 @@ export class TelemetryRegistry implements TelemetryDispatcher {
|
||||
)
|
||||
}
|
||||
|
||||
trackNodeAdded(metadata: NodeAddedMetadata): void {
|
||||
this.dispatch((provider) => provider.trackNodeAdded?.(metadata))
|
||||
}
|
||||
|
||||
trackTemplateFilterChanged(metadata: TemplateFilterMetadata): void {
|
||||
this.dispatch((provider) => provider.trackTemplateFilterChanged?.(metadata))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import type { LGraph, LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
import { ChangeTracker } from '@/scripts/changeTracker'
|
||||
|
||||
import { installNodeAddedTelemetry } from './installNodeAddedTelemetry'
|
||||
import { withNodeAddSource } from './nodeAddSource'
|
||||
|
||||
const trackNodeAdded = vi.fn()
|
||||
|
||||
vi.mock('..', () => ({
|
||||
useTelemetry: () => ({ trackNodeAdded })
|
||||
}))
|
||||
|
||||
function fakeGraph(): LGraph {
|
||||
return { onNodeAdded: undefined } as unknown as LGraph
|
||||
}
|
||||
|
||||
function fakeNode(type: string): LGraphNode {
|
||||
return { type } as unknown as LGraphNode
|
||||
}
|
||||
|
||||
describe('installNodeAddedTelemetry', () => {
|
||||
beforeEach(() => {
|
||||
trackNodeAdded.mockClear()
|
||||
ChangeTracker.isLoadingGraph = false
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
ChangeTracker.isLoadingGraph = false
|
||||
})
|
||||
|
||||
it('fires trackNodeAdded with the current source on add', () => {
|
||||
const graph = fakeGraph()
|
||||
installNodeAddedTelemetry(graph)
|
||||
|
||||
withNodeAddSource('sidebar_drag', () => {
|
||||
graph.onNodeAdded?.(fakeNode('KSampler'))
|
||||
})
|
||||
|
||||
expect(trackNodeAdded).toHaveBeenCalledExactlyOnceWith({
|
||||
node_type: 'KSampler',
|
||||
source: 'sidebar_drag'
|
||||
})
|
||||
})
|
||||
|
||||
it('defaults source to "unknown" outside withNodeAddSource', () => {
|
||||
const graph = fakeGraph()
|
||||
installNodeAddedTelemetry(graph)
|
||||
|
||||
graph.onNodeAdded?.(fakeNode('CheckpointLoader'))
|
||||
|
||||
expect(trackNodeAdded).toHaveBeenCalledWith({
|
||||
node_type: 'CheckpointLoader',
|
||||
source: 'unknown'
|
||||
})
|
||||
})
|
||||
|
||||
it('skips telemetry during workflow load', () => {
|
||||
const graph = fakeGraph()
|
||||
installNodeAddedTelemetry(graph)
|
||||
ChangeTracker.isLoadingGraph = true
|
||||
|
||||
graph.onNodeAdded?.(fakeNode('VAEDecode'))
|
||||
|
||||
expect(trackNodeAdded).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('preserves an existing onNodeAdded subscriber', () => {
|
||||
const graph = fakeGraph()
|
||||
const previous = vi.fn()
|
||||
graph.onNodeAdded = previous
|
||||
installNodeAddedTelemetry(graph)
|
||||
|
||||
const node = fakeNode('LoadImage')
|
||||
graph.onNodeAdded?.(node)
|
||||
|
||||
expect(previous).toHaveBeenCalledExactlyOnceWith(node)
|
||||
expect(trackNodeAdded).toHaveBeenCalledOnce()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { LGraph } from '@/lib/litegraph/src/litegraph'
|
||||
import { ChangeTracker } from '@/scripts/changeTracker'
|
||||
|
||||
import { useTelemetry } from '..'
|
||||
import { getCurrentNodeAddSource } from './nodeAddSource'
|
||||
|
||||
/**
|
||||
* Wire `app:node_added` telemetry into a graph. Wraps any existing
|
||||
* `onNodeAdded` callback so we don't displace other subscribers. Bulk
|
||||
* additions during workflow load are skipped — `workflow_imported`
|
||||
* already covers those.
|
||||
*/
|
||||
export function installNodeAddedTelemetry(graph: LGraph): void {
|
||||
const previous = graph.onNodeAdded
|
||||
graph.onNodeAdded = function (node) {
|
||||
previous?.call(this, node)
|
||||
if (ChangeTracker.isLoadingGraph) return
|
||||
useTelemetry()?.trackNodeAdded({
|
||||
node_type: node.type ?? 'unknown',
|
||||
source: getCurrentNodeAddSource()
|
||||
})
|
||||
}
|
||||
}
|
||||
22
src/platform/telemetry/nodeAdded/nodeAddSource.ts
Normal file
22
src/platform/telemetry/nodeAdded/nodeAddSource.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import type { NodeAddSource } from '../types'
|
||||
|
||||
let currentSource: NodeAddSource = 'unknown'
|
||||
|
||||
export function getCurrentNodeAddSource(): NodeAddSource {
|
||||
return currentSource
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the node-add source for the duration of `fn`. Synchronous only —
|
||||
* the source is read by the synchronous LGraph.onNodeAdded callback that
|
||||
* fires inside `graph.add()`. Nesting restores the previous value on exit.
|
||||
*/
|
||||
export function withNodeAddSource<T>(source: NodeAddSource, fn: () => T): T {
|
||||
const previous = currentSource
|
||||
currentSource = source
|
||||
try {
|
||||
return fn()
|
||||
} finally {
|
||||
currentSource = previous
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import type {
|
||||
HelpCenterOpenedMetadata,
|
||||
HelpResourceClickedMetadata,
|
||||
NodeSearchMetadata,
|
||||
NodeAddedMetadata,
|
||||
NodeSearchResultMetadata,
|
||||
PageViewMetadata,
|
||||
PageVisibilityMetadata,
|
||||
@@ -316,6 +317,13 @@ export class GtmTelemetryProvider implements TelemetryProvider {
|
||||
})
|
||||
}
|
||||
|
||||
trackNodeAdded(metadata: NodeAddedMetadata): void {
|
||||
this.pushEvent('node_added', {
|
||||
node_type: metadata.node_type,
|
||||
source: metadata.source
|
||||
})
|
||||
}
|
||||
|
||||
trackTemplateFilterChanged(metadata: TemplateFilterMetadata): void {
|
||||
this.pushEvent('template_filter', {
|
||||
search_query: metadata.search_query,
|
||||
|
||||
@@ -26,6 +26,7 @@ import type {
|
||||
HelpCenterOpenedMetadata,
|
||||
HelpResourceClickedMetadata,
|
||||
NodeSearchMetadata,
|
||||
NodeAddedMetadata,
|
||||
NodeSearchResultMetadata,
|
||||
PageVisibilityMetadata,
|
||||
RunButtonProperties,
|
||||
@@ -400,6 +401,10 @@ export class MixpanelTelemetryProvider implements TelemetryProvider {
|
||||
this.trackEvent(TelemetryEvents.NODE_SEARCH_RESULT_SELECTED, metadata)
|
||||
}
|
||||
|
||||
trackNodeAdded(metadata: NodeAddedMetadata): void {
|
||||
this.trackEvent(TelemetryEvents.NODE_ADDED, metadata)
|
||||
}
|
||||
|
||||
trackTemplateFilterChanged(metadata: TemplateFilterMetadata): void {
|
||||
this.trackEvent(TelemetryEvents.TEMPLATE_FILTER_CHANGED, metadata)
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import type {
|
||||
HelpCenterClosedMetadata,
|
||||
HelpCenterOpenedMetadata,
|
||||
HelpResourceClickedMetadata,
|
||||
NodeAddedMetadata,
|
||||
NodeSearchMetadata,
|
||||
NodeSearchResultMetadata,
|
||||
PageViewMetadata,
|
||||
@@ -457,6 +458,10 @@ export class PostHogTelemetryProvider implements TelemetryProvider {
|
||||
this.trackEvent(TelemetryEvents.NODE_SEARCH_RESULT_SELECTED, metadata)
|
||||
}
|
||||
|
||||
trackNodeAdded(metadata: NodeAddedMetadata): void {
|
||||
this.trackEvent(TelemetryEvents.NODE_ADDED, metadata)
|
||||
}
|
||||
|
||||
trackTemplateFilterChanged(metadata: TemplateFilterMetadata): void {
|
||||
this.trackEvent(TelemetryEvents.TEMPLATE_FILTER_CHANGED, metadata)
|
||||
}
|
||||
|
||||
@@ -232,6 +232,23 @@ export interface NodeSearchMetadata {
|
||||
query: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Node added metadata. `source` indicates how the user initiated the add.
|
||||
* Bulk additions during workflow load are excluded — workflow_imported
|
||||
* already covers that.
|
||||
*/
|
||||
export type NodeAddSource =
|
||||
| 'sidebar_drag'
|
||||
| 'search_modal'
|
||||
| 'paste'
|
||||
| 'programmatic'
|
||||
| 'unknown'
|
||||
|
||||
export interface NodeAddedMetadata {
|
||||
node_type: string
|
||||
source: NodeAddSource
|
||||
}
|
||||
|
||||
/**
|
||||
* Node search result selection metadata
|
||||
*/
|
||||
@@ -437,6 +454,9 @@ export interface TelemetryProvider {
|
||||
trackNodeSearch?(metadata: NodeSearchMetadata): void
|
||||
trackNodeSearchResultSelected?(metadata: NodeSearchResultMetadata): void
|
||||
|
||||
// Node-added-to-canvas analytics
|
||||
trackNodeAdded?(metadata: NodeAddedMetadata): void
|
||||
|
||||
// Template filter tracking events
|
||||
trackTemplateFilterChanged?(metadata: TemplateFilterMetadata): void
|
||||
|
||||
@@ -523,6 +543,7 @@ export const TelemetryEvents = {
|
||||
// Node Search Analytics
|
||||
NODE_SEARCH: 'app:node_search',
|
||||
NODE_SEARCH_RESULT_SELECTED: 'app:node_search_result_selected',
|
||||
NODE_ADDED: 'app:node_added',
|
||||
|
||||
// Template Filter Analytics
|
||||
TEMPLATE_FILTER_CHANGED: 'app:template_filter_changed',
|
||||
|
||||
@@ -25,6 +25,7 @@ import { LGraphEventMode } from '@/lib/litegraph/src/types/globalEnums'
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { useTelemetry } from '@/platform/telemetry'
|
||||
import { installNodeAddedTelemetry } from '@/platform/telemetry/nodeAdded/installNodeAddedTelemetry'
|
||||
import type { WorkflowOpenSource } from '@/platform/telemetry/types'
|
||||
import { useToastStore } from '@/platform/updates/common/toastStore'
|
||||
import { updatePendingWarnings } from '@/platform/workflow/core/utils/pendingWarnings'
|
||||
@@ -888,6 +889,7 @@ export class ComfyApp {
|
||||
this.addAfterConfigureHandler(graph)
|
||||
|
||||
this.rootGraphInternal = graph
|
||||
installNodeAddedTelemetry(graph)
|
||||
this.canvas = new LGraphCanvas(canvasEl, graph)
|
||||
// Make canvas states reactive so we can observe changes on them.
|
||||
this.canvas.state = reactive(this.canvas.state)
|
||||
|
||||
@@ -4,6 +4,7 @@ import type {
|
||||
LGraphNode
|
||||
} from '@/lib/litegraph/src/litegraph'
|
||||
import { LiteGraph } from '@/lib/litegraph/src/litegraph'
|
||||
import { withNodeAddSource } from '@/platform/telemetry/nodeAdded/nodeAddSource'
|
||||
|
||||
/**
|
||||
* Serialises an array of nodes using a modified version of the old Litegraph copy (& paste) function
|
||||
@@ -106,7 +107,7 @@ export function deserialiseAndCreate(data: string, canvas: LGraphCanvas): void {
|
||||
node.pos[1] += graph_mouse[1] - topLeft[1]
|
||||
|
||||
// @ts-expect-error fixme ts strict error
|
||||
graph.add(node, true)
|
||||
withNodeAddSource('paste', () => graph.add(node, true))
|
||||
nodes.push(node)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user