diff --git a/src/renderer/extensions/vueNodes/components/ImagePreview.vue b/src/renderer/extensions/vueNodes/components/ImagePreview.vue index 7f4724dad6..c0304161ea 100644 --- a/src/renderer/extensions/vueNodes/components/ImagePreview.vue +++ b/src/renderer/extensions/vueNodes/components/ImagePreview.vue @@ -125,7 +125,6 @@ import { computed, ref, watch } from 'vue' import { useI18n } from 'vue-i18n' import { downloadFile } from '@/base/common/downloadUtil' -import { app } from '@/scripts/app' import { useCommandStore } from '@/stores/commandStore' import { useNodeOutputStore } from '@/stores/imagePreviewStore' @@ -188,17 +187,6 @@ watch( { deep: true, immediate: true } ) -/** - * Sync node.imgs for backwards compatibility with legacy systems (e.g., Copy Image). - */ -const syncNodeImgs = () => { - if (!props.nodeId || !currentImageEl.value) return - const node = app.rootGraph?.getNodeById(props.nodeId) - if (!node) return - node.imgs = [currentImageEl.value] - node.imageIndex = currentIndex.value -} - // Event handlers const handleImageLoad = (event: Event) => { if (!event.target || !(event.target instanceof HTMLImageElement)) return @@ -209,7 +197,6 @@ const handleImageLoad = (event: Event) => { if (img.naturalWidth && img.naturalHeight) { actualDimensions.value = `${img.naturalWidth} x ${img.naturalHeight}` } - syncNodeImgs() } const handleImageError = () => { diff --git a/src/stores/imagePreviewStore.ts b/src/stores/imagePreviewStore.ts index ee8ae759bd..634c01c263 100644 --- a/src/stores/imagePreviewStore.ts +++ b/src/stores/imagePreviewStore.ts @@ -37,7 +37,8 @@ interface SetOutputOptions { } export const useNodeOutputStore = defineStore('nodeOutput', () => { - const { nodeIdToNodeLocatorId, nodeToNodeLocatorId } = useWorkflowStore() + const { nodeIdToNodeLocatorId, nodeToNodeLocatorId, nodeLocatorIdToNodeId } = + useWorkflowStore() const { executionIdToNodeLocatorId } = useExecutionStore() const scheduledRevoke: Record void }> = {} const latestOutput = ref([]) @@ -156,6 +157,26 @@ export const useNodeOutputStore = defineStore('nodeOutput', () => { }) ?? [] app.nodeOutputs[nodeLocatorId] = outputs nodeOutputs.value[nodeLocatorId] = outputs + + syncNodeImgs(nodeLocatorId, latestOutput.value) + } + + /** + * Sync node.imgs for backwards compatibility with legacy systems (e.g., Copy Image). + */ + function syncNodeImgs(nodeLocatorId: NodeLocatorId, imageUrls: string[]) { + if (!imageUrls.length) return + const nodeId = nodeLocatorIdToNodeId(nodeLocatorId) + if (nodeId === null) return + const node = app.canvas?.graph?.getNodeById(nodeId) + if (!node) return + + const img = new Image() + img.onload = () => { + node.imgs = [img] + node.imageIndex = 0 + } + img.src = imageUrls[0] } function setNodeOutputs( diff --git a/tests-ui/tests/renderer/extensions/vueNodes/components/ImagePreview.test.ts b/tests-ui/tests/renderer/extensions/vueNodes/components/ImagePreview.test.ts index 54bd84c6b7..4d172a0a2e 100644 --- a/tests-ui/tests/renderer/extensions/vueNodes/components/ImagePreview.test.ts +++ b/tests-ui/tests/renderer/extensions/vueNodes/components/ImagePreview.test.ts @@ -1,7 +1,7 @@ import { createTestingPinia } from '@pinia/testing' import type { VueWrapper } from '@vue/test-utils' import { mount } from '@vue/test-utils' -import { beforeEach, describe, expect, it, vi } from 'vitest' +import { describe, expect, it, vi } from 'vitest' import { nextTick } from 'vue' import { createI18n } from 'vue-i18n' @@ -13,22 +13,6 @@ vi.mock('@/base/common/downloadUtil', () => ({ downloadFile: vi.fn() })) -// Mock app for node.imgs sync tests -const mockNode: { - imgs?: HTMLImageElement[] | undefined - imageIndex?: number | null -} = {} -vi.mock('@/scripts/app', () => ({ - app: { - rootGraph: { - getNodeById: vi.fn(() => mockNode) - }, - canvas: { - select: vi.fn() - } - } -})) - const i18n = createI18n({ legacy: false, locale: 'en', @@ -60,11 +44,6 @@ describe('ImagePreview', () => { } const wrapperRegistry = new Set() - beforeEach(() => { - delete mockNode.imgs - delete mockNode.imageIndex - }) - const mountImagePreview = (props = {}) => { const wrapper = mount(ImagePreview, { props: { ...defaultProps, ...props }, @@ -329,21 +308,4 @@ describe('ImagePreview', () => { expect(imgElement.exists()).toBe(true) expect(imgElement.attributes('alt')).toBe('Node output 2') }) - - it('syncs node.imgs on image load for legacy compatibility', async () => { - const wrapper = mountImagePreview({ - imageUrls: [defaultProps.imageUrls[0]], - nodeId: 'test-node-123' - }) - - const img = wrapper.find('img') - expect(img.exists()).toBe(true) - - await img.trigger('load') - await nextTick() - - expect(mockNode.imgs).toHaveLength(1) - expect(mockNode.imgs?.[0]).toBe(img.element) - expect(mockNode.imageIndex).toBe(0) - }) })