Fix preview initialization

This commit is contained in:
Austin Mroz
2025-09-28 00:09:19 -05:00
parent 94f6778285
commit cc7c22a428
3 changed files with 68 additions and 67 deletions

View File

@@ -1,7 +1,7 @@
import type { LGraphNode } from '@/lib/litegraph/src/litegraph' import type { LGraphNode } from '@/lib/litegraph/src/litegraph'
import { useImagePreviewWidget } from '@/renderer/extensions/vueNodes/widgets/composables/useImagePreviewWidget' import { useImagePreviewWidget } from '@/renderer/extensions/vueNodes/widgets/composables/useImagePreviewWidget'
const CANVAS_IMAGE_PREVIEW_WIDGET = '$$canvas-image-preview' export const CANVAS_IMAGE_PREVIEW_WIDGET = '$$canvas-image-preview'
/** /**
* Composable for handling canvas image previews in nodes * Composable for handling canvas image previews in nodes

View File

@@ -1,4 +1,4 @@
import { useNodeImage } from '@/composables/node/useNodeImage' import { CANVAS_IMAGE_PREVIEW_WIDGET } from '@/composables/node/useNodeCanvasImagePreview'
import { parseProxyWidgets } from '@/core/schemas/proxyWidget' import { parseProxyWidgets } from '@/core/schemas/proxyWidget'
import type { import type {
LGraph, LGraph,
@@ -11,8 +11,8 @@ import type { IBaseWidget } from '@/lib/litegraph/src/types/widgets.ts'
import { disconnectedWidget } from '@/lib/litegraph/src/widgets/DisconnectedWidget' import { disconnectedWidget } from '@/lib/litegraph/src/widgets/DisconnectedWidget'
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore' import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
import { DOMWidgetImpl } from '@/scripts/domWidget' import { DOMWidgetImpl } from '@/scripts/domWidget'
import { useLitegraphService } from '@/services/litegraphService'
import { useDomWidgetStore } from '@/stores/domWidgetStore' import { useDomWidgetStore } from '@/stores/domWidgetStore'
import { useNodeOutputStore } from '@/stores/imagePreviewStore'
import { getNodeByExecutionId } from '@/utils/graphTraversalUtil' import { getNodeByExecutionId } from '@/utils/graphTraversalUtil'
/** /**
@@ -137,23 +137,20 @@ function resolveLinkedWidget(
if (!n) return [undefined, undefined] if (!n) return [undefined, undefined]
return [n, n.widgets?.find((w: IBaseWidget) => w.name === widgetName)] return [n, n.widgets?.find((w: IBaseWidget) => w.name === widgetName)]
} }
function addProxyFromOverlay(subgraphNode: SubgraphNode, overlay: Overlay) { function addProxyFromOverlay(subgraphNode: SubgraphNode, overlay: Overlay) {
const { updatePreviews } = useLitegraphService()
let [linkedNode, linkedWidget] = resolveLinkedWidget(overlay) let [linkedNode, linkedWidget] = resolveLinkedWidget(overlay)
let backingWidget = linkedWidget ?? disconnectedWidget let backingWidget = linkedWidget ?? disconnectedWidget
if (overlay.widgetName == '$$canvas-image-preview') if (overlay.widgetName == CANVAS_IMAGE_PREVIEW_WIDGET) {
overlay.node = new Proxy(subgraphNode, { overlay.node = new Proxy(subgraphNode, {
get(_t, p) { get(_t, p) {
if (p !== 'imgs') return Reflect.get(subgraphNode, p) if (p !== 'imgs') return Reflect.get(subgraphNode, p)
if (!linkedNode) return [] if (!linkedNode) return []
const images =
useNodeOutputStore().getNodeOutputs(linkedNode)?.images ?? []
if (images !== linkedNode.images) {
linkedNode.images = images
useNodeImage(linkedNode).showPreview()
}
return linkedNode.imgs return linkedNode.imgs
} }
}) })
}
/** /**
* A set of handlers which define widget interaction * A set of handlers which define widget interaction
* Many arguments are shared between function calls * Many arguments are shared between function calls
@@ -182,7 +179,9 @@ function addProxyFromOverlay(subgraphNode: SubgraphNode, overlay: Overlay) {
let redirectedReceiver = receiver let redirectedReceiver = receiver
if (property == 'value') redirectedReceiver = backingWidget if (property == 'value') redirectedReceiver = backingWidget
else if (property == 'computedHeight') { else if (property == 'computedHeight') {
//update linkage regularly, but no more than once per frame if (overlay.widgetName == CANVAS_IMAGE_PREVIEW_WIDGET && linkedNode)
updatePreviews(linkedNode)
//update linkage regularly, but no more than once per frame
;[linkedNode, linkedWidget] = resolveLinkedWidget(overlay) ;[linkedNode, linkedWidget] = resolveLinkedWidget(overlay)
backingWidget = linkedWidget ?? disconnectedWidget backingWidget = linkedWidget ?? disconnectedWidget
} }

View File

@@ -853,6 +853,61 @@ export const useLitegraphService = () => {
return [] return []
} }
} }
function updatePreviews(node: LGraphNode) {
try {
unsafeUpdatePreviews.call(node)
} catch (error) {
console.error('Error drawing node background', error)
}
}
function unsafeUpdatePreviews(this: LGraphNode) {
if (this.flags.collapsed) return
const nodeOutputStore = useNodeOutputStore()
const { showAnimatedPreview, removeAnimatedPreview } =
useNodeAnimatedImage()
const { showCanvasImagePreview, removeCanvasImagePreview } =
useNodeCanvasImagePreview()
const output = nodeOutputStore.getNodeOutputs(this)
const preview = nodeOutputStore.getNodePreviews(this)
const isNewOutput = output && this.images !== output.images
const isNewPreview = preview && this.preview !== preview
if (isNewPreview) this.preview = preview
if (isNewOutput) this.images = output.images
if (isNewOutput || isNewPreview) {
this.animatedImages = output?.animated?.find(Boolean)
const isAnimatedWebp =
this.animatedImages &&
output?.images?.some((img) => img.filename?.includes('webp'))
const isAnimatedPng =
this.animatedImages &&
output?.images?.some((img) => img.filename?.includes('png'))
const isVideo =
(this.animatedImages && !isAnimatedWebp && !isAnimatedPng) ||
isVideoNode(this)
if (isVideo) {
useNodeVideo(this).showPreview()
} else {
useNodeImage(this).showPreview()
}
}
// Nothing to do
if (!this.imgs?.length) return
if (this.animatedImages) {
removeCanvasImagePreview(this)
showAnimatedPreview(this)
} else {
removeAnimatedPreview(this)
showCanvasImagePreview(this)
}
}
/** /**
* Adds Custom drawing logic for nodes * Adds Custom drawing logic for nodes
@@ -868,62 +923,8 @@ export const useLitegraphService = () => {
'node.setSizeForImage is deprecated. Now it has no effect. Please remove the call to it.' 'node.setSizeForImage is deprecated. Now it has no effect. Please remove the call to it.'
) )
} }
function unsafeDrawBackground(this: LGraphNode) {
if (this.flags.collapsed) return
const nodeOutputStore = useNodeOutputStore()
const { showAnimatedPreview, removeAnimatedPreview } =
useNodeAnimatedImage()
const { showCanvasImagePreview, removeCanvasImagePreview } =
useNodeCanvasImagePreview()
const output = nodeOutputStore.getNodeOutputs(this)
const preview = nodeOutputStore.getNodePreviews(this)
const isNewOutput = output && this.images !== output.images
const isNewPreview = preview && this.preview !== preview
if (isNewPreview) this.preview = preview
if (isNewOutput) this.images = output.images
if (isNewOutput || isNewPreview) {
this.animatedImages = output?.animated?.find(Boolean)
const isAnimatedWebp =
this.animatedImages &&
output?.images?.some((img) => img.filename?.includes('webp'))
const isAnimatedPng =
this.animatedImages &&
output?.images?.some((img) => img.filename?.includes('png'))
const isVideo =
(this.animatedImages && !isAnimatedWebp && !isAnimatedPng) ||
isVideoNode(this)
if (isVideo) {
useNodeVideo(this).showPreview()
} else {
useNodeImage(this).showPreview()
}
}
// Nothing to do
if (!this.imgs?.length) return
if (this.animatedImages) {
removeCanvasImagePreview(this)
showAnimatedPreview(this)
} else {
removeAnimatedPreview(this)
showCanvasImagePreview(this)
}
}
node.prototype.onDrawBackground = function () { node.prototype.onDrawBackground = function () {
try { updatePreviews(this)
unsafeDrawBackground.call(this)
} catch (error) {
console.error('Error drawing node background', error)
}
} }
} }
@@ -1053,6 +1054,7 @@ export const useLitegraphService = () => {
getCanvasCenter, getCanvasCenter,
goToNode, goToNode,
resetView, resetView,
fitView fitView,
updatePreviews
} }
} }