mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 22:39:39 +00:00
@@ -100,8 +100,7 @@ export const useImageUploadWidget = () => {
|
|||||||
// Add our own callback to the combo widget to render an image when it changes
|
// Add our own callback to the combo widget to render an image when it changes
|
||||||
fileComboWidget.callback = function () {
|
fileComboWidget.callback = function () {
|
||||||
nodeOutputStore.setNodeOutputs(node, fileComboWidget.value, {
|
nodeOutputStore.setNodeOutputs(node, fileComboWidget.value, {
|
||||||
isAnimated,
|
isAnimated
|
||||||
isInitialLoad: true
|
|
||||||
})
|
})
|
||||||
node.graph?.setDirtyCanvas(true)
|
node.graph?.setDirtyCanvas(true)
|
||||||
}
|
}
|
||||||
@@ -111,8 +110,7 @@ export const useImageUploadWidget = () => {
|
|||||||
// No change callbacks seem to be fired on initial setting of the value
|
// No change callbacks seem to be fired on initial setting of the value
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
nodeOutputStore.setNodeOutputs(node, fileComboWidget.value, {
|
nodeOutputStore.setNodeOutputs(node, fileComboWidget.value, {
|
||||||
isAnimated,
|
isAnimated
|
||||||
isInitialLoad: true
|
|
||||||
})
|
})
|
||||||
showPreview({ block: false })
|
showPreview({ block: false })
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { LGraph, LGraphNode, Subgraph } from '@comfyorg/litegraph'
|
import type { LGraph, Subgraph } from '@comfyorg/litegraph'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ import type {
|
|||||||
} from '@/schemas/comfyWorkflowSchema'
|
} from '@/schemas/comfyWorkflowSchema'
|
||||||
import { api } from '@/scripts/api'
|
import { api } from '@/scripts/api'
|
||||||
import { app } from '@/scripts/app'
|
import { app } from '@/scripts/app'
|
||||||
import type { NodeExecutionId, NodeLocatorId } from '@/types/nodeIdentification'
|
import type { NodeLocatorId } from '@/types/nodeIdentification'
|
||||||
import { createNodeLocatorId } from '@/types/nodeIdentification'
|
import { createNodeLocatorId } from '@/types/nodeIdentification'
|
||||||
|
|
||||||
import { useCanvasStore } from './graphStore'
|
import { useCanvasStore } from './graphStore'
|
||||||
@@ -54,22 +54,6 @@ export const useExecutionStore = defineStore('execution', () => {
|
|||||||
// This is the progress of all nodes in the currently executing workflow
|
// This is the progress of all nodes in the currently executing workflow
|
||||||
const nodeProgressStates = ref<Record<string, NodeProgressState>>({})
|
const nodeProgressStates = ref<Record<string, NodeProgressState>>({})
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Workaround for Subgraph phase 1 - execution IDs may share locator IDs.
|
|
||||||
* The most recently executed execution ID for each node locator ID.
|
|
||||||
*/
|
|
||||||
const locatorIdToExecutionIdMap = new Map<NodeLocatorId, NodeExecutionId>()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the NodeLocatorId for a node.
|
|
||||||
* @param node The node
|
|
||||||
* @returns The NodeLocatorId
|
|
||||||
*/
|
|
||||||
const getNodeLocatorId = (node: LGraphNode): NodeLocatorId =>
|
|
||||||
node.graph?.isRootGraph
|
|
||||||
? node.id.toString()
|
|
||||||
: [node.graph?.id, node.id].join(':')
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert execution context node IDs to NodeLocatorIds
|
* Convert execution context node IDs to NodeLocatorIds
|
||||||
* @param nodeId The node ID from execution context (could be execution ID)
|
* @param nodeId The node ID from execution context (could be execution ID)
|
||||||
@@ -484,8 +468,6 @@ export const useExecutionStore = defineStore('execution', () => {
|
|||||||
_executingNodeProgress,
|
_executingNodeProgress,
|
||||||
// NodeLocatorId conversion helpers
|
// NodeLocatorId conversion helpers
|
||||||
executionIdToNodeLocatorId,
|
executionIdToNodeLocatorId,
|
||||||
nodeLocatorIdToExecutionId,
|
nodeLocatorIdToExecutionId
|
||||||
locatorIdToExecutionIdMap,
|
|
||||||
getNodeLocatorId
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -8,12 +8,9 @@ import {
|
|||||||
} from '@/schemas/apiSchema'
|
} from '@/schemas/apiSchema'
|
||||||
import { api } from '@/scripts/api'
|
import { api } from '@/scripts/api'
|
||||||
import { app } from '@/scripts/app'
|
import { app } from '@/scripts/app'
|
||||||
import type { NodeExecutionId } from '@/types'
|
|
||||||
import { parseFilePath } from '@/utils/formatUtil'
|
import { parseFilePath } from '@/utils/formatUtil'
|
||||||
import { isVideoNode } from '@/utils/litegraphUtil'
|
import { isVideoNode } from '@/utils/litegraphUtil'
|
||||||
|
|
||||||
import { useExecutionStore } from './executionStore'
|
|
||||||
|
|
||||||
const createOutputs = (
|
const createOutputs = (
|
||||||
filenames: string[],
|
filenames: string[],
|
||||||
type: ResultItemType,
|
type: ResultItemType,
|
||||||
@@ -26,20 +23,16 @@ const createOutputs = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const useNodeOutputStore = defineStore('nodeOutput', () => {
|
export const useNodeOutputStore = defineStore('nodeOutput', () => {
|
||||||
const executionStore = useExecutionStore()
|
const getNodeId = (node: LGraphNode): string => node.id.toString()
|
||||||
const getMostRecentExecutionId = (node: LGraphNode): NodeExecutionId =>
|
|
||||||
executionStore.locatorIdToExecutionIdMap.get(
|
|
||||||
executionStore.getNodeLocatorId(node)
|
|
||||||
) ?? node.id.toString()
|
|
||||||
|
|
||||||
function getNodeOutputs(
|
function getNodeOutputs(
|
||||||
node: LGraphNode
|
node: LGraphNode
|
||||||
): ExecutedWsMessage['output'] | undefined {
|
): ExecutedWsMessage['output'] | undefined {
|
||||||
return app.nodeOutputs[getMostRecentExecutionId(node)]
|
return app.nodeOutputs[getNodeId(node)]
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNodePreviews(node: LGraphNode): string[] | undefined {
|
function getNodePreviews(node: LGraphNode): string[] | undefined {
|
||||||
return app.nodePreviewImages[getMostRecentExecutionId(node)]
|
return app.nodePreviewImages[getNodeId(node)]
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,23 +91,12 @@ export const useNodeOutputStore = defineStore('nodeOutput', () => {
|
|||||||
filenames: string | string[] | ResultItem,
|
filenames: string | string[] | ResultItem,
|
||||||
{
|
{
|
||||||
folder = 'input',
|
folder = 'input',
|
||||||
isAnimated = false,
|
isAnimated = false
|
||||||
isInitialLoad = false
|
}: { folder?: ResultItemType; isAnimated?: boolean } = {}
|
||||||
}: {
|
|
||||||
folder?: ResultItemType
|
|
||||||
isAnimated?: boolean
|
|
||||||
isInitialLoad?: boolean
|
|
||||||
} = {}
|
|
||||||
) {
|
) {
|
||||||
if (!filenames || !node) return
|
if (!filenames || !node) return
|
||||||
|
|
||||||
const nodeId = isInitialLoad
|
const nodeId = getNodeId(node)
|
||||||
? executionStore.getNodeLocatorId(node)
|
|
||||||
: getMostRecentExecutionId(node)
|
|
||||||
|
|
||||||
if (isInitialLoad) {
|
|
||||||
executionStore.locatorIdToExecutionIdMap.set(nodeId, nodeId)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof filenames === 'string') {
|
if (typeof filenames === 'string') {
|
||||||
app.nodeOutputs[nodeId] = createOutputs([filenames], folder, isAnimated)
|
app.nodeOutputs[nodeId] = createOutputs([filenames], folder, isAnimated)
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import type {
|
|||||||
ComfyApiWorkflow,
|
ComfyApiWorkflow,
|
||||||
ComfyWorkflowJSON
|
ComfyWorkflowJSON
|
||||||
} from '@/schemas/comfyWorkflowSchema'
|
} from '@/schemas/comfyWorkflowSchema'
|
||||||
import { useExecutionStore } from '@/stores/executionStore'
|
|
||||||
|
|
||||||
import { ExecutableGroupNodeDTO, isGroupNode } from './executableGroupNodeDto'
|
import { ExecutableGroupNodeDTO, isGroupNode } from './executableGroupNodeDto'
|
||||||
import { compressWidgetInputSlots } from './litegraphUtil'
|
import { compressWidgetInputSlots } from './litegraphUtil'
|
||||||
@@ -59,8 +58,6 @@ export const graphToPrompt = async (
|
|||||||
options: { sortNodes?: boolean; queueNodeIds?: NodeId[] } = {}
|
options: { sortNodes?: boolean; queueNodeIds?: NodeId[] } = {}
|
||||||
): Promise<{ workflow: ComfyWorkflowJSON; output: ComfyApiWorkflow }> => {
|
): Promise<{ workflow: ComfyWorkflowJSON; output: ComfyApiWorkflow }> => {
|
||||||
const { sortNodes = false, queueNodeIds } = options
|
const { sortNodes = false, queueNodeIds } = options
|
||||||
const executionStore = useExecutionStore()
|
|
||||||
executionStore.locatorIdToExecutionIdMap.clear()
|
|
||||||
|
|
||||||
for (const node of graph.computeExecutionOrder(false)) {
|
for (const node of graph.computeExecutionOrder(false)) {
|
||||||
const innerNodes = node.getInnerNodes
|
const innerNodes = node.getInnerNodes
|
||||||
@@ -162,13 +159,6 @@ export const graphToPrompt = async (
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temporary workaround for Subgraph phase 1. Overwrites the ID, but keeps the image.
|
|
||||||
const baseNodeId = node.id.split(':').at(-1)
|
|
||||||
executionStore.locatorIdToExecutionIdMap.set(
|
|
||||||
`${node.subgraphId}:${baseNodeId}`,
|
|
||||||
node.id
|
|
||||||
)
|
|
||||||
|
|
||||||
output[String(node.id)] = {
|
output[String(node.id)] = {
|
||||||
inputs,
|
inputs,
|
||||||
// TODO(huchenlei): Filter out all nodes that cannot be mapped to a
|
// TODO(huchenlei): Filter out all nodes that cannot be mapped to a
|
||||||
|
|||||||
Reference in New Issue
Block a user