mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-26 01:34:07 +00:00
fix: refresh image previews on media upload nodes when refreshing node definitions (#9141)
## Summary - When pressing `R` to refresh node definitions, image previews on LoadImage/LoadVideo nodes now update to reflect external file changes - Re-triggers the combo widget callback to regenerate preview URLs with a fresh cache-busting `&rand=` parameter - Extracts `isMediaUploadComboInput` from `uploadImage.ts` to `nodeDefSchema.ts` as a shared utility - Fixes #2082 https://github.com/user-attachments/assets/d18d69ae-6ecd-448d-8d7c-76b2c49fdea5 ## Test plan - [ ] Open a workflow with a LoadImage node and select an image - [ ] Edit and save the image externally (e.g. in an image editor) - [ ] Press `R` to refresh node definitions - [ ] Verify the preview updates to show the edited image
This commit is contained in:
committed by
GitHub
parent
3b5649232d
commit
1f0ca18737
@@ -2,27 +2,13 @@ import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'
|
||||
import {
|
||||
type ComfyNodeDef,
|
||||
type InputSpec,
|
||||
isComboInputSpecV1
|
||||
isMediaUploadComboInput
|
||||
} from '@/schemas/nodeDefSchema'
|
||||
|
||||
import { app } from '../../scripts/app'
|
||||
|
||||
// Adds an upload button to the nodes
|
||||
|
||||
const isMediaUploadComboInput = (inputSpec: InputSpec) => {
|
||||
const [inputName, inputOptions] = inputSpec
|
||||
if (!inputOptions) return false
|
||||
|
||||
const isUploadInput =
|
||||
inputOptions['image_upload'] === true ||
|
||||
inputOptions['video_upload'] === true ||
|
||||
inputOptions['animated_image_upload'] === true
|
||||
|
||||
return (
|
||||
isUploadInput && (isComboInputSpecV1(inputSpec) || inputName === 'COMBO')
|
||||
)
|
||||
}
|
||||
|
||||
const createUploadInput = (
|
||||
imageInputName: string,
|
||||
imageInputOptions: InputSpec
|
||||
|
||||
@@ -158,6 +158,20 @@ export function isComboInputSpec(
|
||||
return isComboInputSpecV1(inputSpec) || isComboInputSpecV2(inputSpec)
|
||||
}
|
||||
|
||||
export function isMediaUploadComboInput(inputSpec: InputSpec): boolean {
|
||||
const [inputName, inputOptions] = inputSpec
|
||||
if (!inputOptions) return false
|
||||
|
||||
const isUploadInput =
|
||||
inputOptions['image_upload'] === true ||
|
||||
inputOptions['video_upload'] === true ||
|
||||
inputOptions['animated_image_upload'] === true
|
||||
|
||||
return (
|
||||
isUploadInput && (isComboInputSpecV1(inputSpec) || inputName === 'COMBO')
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of an input spec.
|
||||
*
|
||||
|
||||
@@ -89,7 +89,8 @@ import {
|
||||
executeWidgetsCallback,
|
||||
createNode,
|
||||
fixLinkInputSlots,
|
||||
isImageNode
|
||||
isImageNode,
|
||||
isVideoNode
|
||||
} from '@/utils/litegraphUtil'
|
||||
import {
|
||||
createSharedObjectUrl,
|
||||
@@ -1822,6 +1823,7 @@ export class ComfyApp {
|
||||
this.registerNodeDef(nodeId, defs[nodeId])
|
||||
}
|
||||
// Refresh combo widgets in all nodes including those in subgraphs
|
||||
const nodeOutputStore = useNodeOutputStore()
|
||||
forEachNode(this.rootGraph, (node) => {
|
||||
const def = defs[node.type]
|
||||
// Allow primitive nodes to handle refresh
|
||||
@@ -1854,6 +1856,12 @@ export class ComfyApp {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Re-trigger previews on media nodes (e.g. LoadImage)
|
||||
// to bust browser cache when files are edited externally
|
||||
if (isImageNode(node) || isVideoNode(node)) {
|
||||
nodeOutputStore.refreshNodeOutputs(node)
|
||||
}
|
||||
})
|
||||
|
||||
await useExtensionService().invokeExtensionsAsync(
|
||||
|
||||
@@ -388,6 +388,16 @@ export const useNodeOutputStore = defineStore('nodeOutput', () => {
|
||||
}
|
||||
}
|
||||
|
||||
function refreshNodeOutputs(node: LGraphNode) {
|
||||
const locatorId = nodeToNodeLocatorId(node)
|
||||
if (!locatorId) return
|
||||
|
||||
const outputs = app.nodeOutputs[locatorId]
|
||||
if (!outputs) return
|
||||
|
||||
nodeOutputs.value[locatorId] = { ...outputs }
|
||||
}
|
||||
|
||||
function resetAllOutputsAndPreviews() {
|
||||
app.nodeOutputs = {}
|
||||
nodeOutputs.value = {}
|
||||
@@ -433,6 +443,7 @@ export const useNodeOutputStore = defineStore('nodeOutput', () => {
|
||||
setNodePreviewsByExecutionId,
|
||||
setNodePreviewsByNodeId,
|
||||
updateNodeImages,
|
||||
refreshNodeOutputs,
|
||||
syncLegacyNodeImgs,
|
||||
|
||||
// Cleanup
|
||||
|
||||
Reference in New Issue
Block a user