mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-13 17:10:06 +00:00
fix: sync node.imgs for legacy context menu in Vue Nodes mode (#8143)
## Summary Fixes missing "Copy Image", "Open Image", "Save Image", and "Open in Mask Editor" context menu options on SaveImage nodes when Vue Nodes mode is enabled. ## Changes - Add `syncLegacyNodeImgs` store method to sync loaded image elements to `node.imgs` - Call sync on image load in ImagePreview component - Simplify mask editor handling to call composable directly ## Technical Details - Only runs when `vueNodesMode` is enabled (no impact on legacy mode) - Reuses already-loaded `<img>` element from Vue (no duplicate network requests) - Store owns the sync logic, component just hands off the element Supersedes #7416 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8143-fix-sync-node-imgs-for-legacy-context-menu-in-Vue-Nodes-mode-2ec6d73d365081c59d42cd1722779b61) by [Unito](https://www.unito.io) --------- Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
@@ -40,7 +40,6 @@
|
||||
<!-- Main Image -->
|
||||
<img
|
||||
v-if="!imageError"
|
||||
ref="currentImageEl"
|
||||
:src="currentImageUrl"
|
||||
:alt="imageAltText"
|
||||
class="block size-full object-contain pointer-events-none contain-size"
|
||||
@@ -128,8 +127,8 @@ import { computed, ref, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { downloadFile } from '@/base/common/downloadUtil'
|
||||
import { useMaskEditor } from '@/composables/maskeditor/useMaskEditor'
|
||||
import { app } from '@/scripts/app'
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
import { useNodeOutputStore } from '@/stores/imagePreviewStore'
|
||||
|
||||
interface ImagePreviewProps {
|
||||
@@ -142,7 +141,7 @@ interface ImagePreviewProps {
|
||||
const props = defineProps<ImagePreviewProps>()
|
||||
|
||||
const { t } = useI18n()
|
||||
const commandStore = useCommandStore()
|
||||
const maskEditor = useMaskEditor()
|
||||
const nodeOutputStore = useNodeOutputStore()
|
||||
|
||||
const actionButtonClass =
|
||||
@@ -156,7 +155,6 @@ const actualDimensions = ref<string | null>(null)
|
||||
const imageError = ref(false)
|
||||
const showLoader = ref(false)
|
||||
|
||||
const currentImageEl = ref<HTMLImageElement>()
|
||||
const imageWrapperEl = ref<HTMLDivElement>()
|
||||
|
||||
const { start: startDelayedLoader, stop: stopDelayedLoader } = useTimeoutFn(
|
||||
@@ -209,6 +207,10 @@ const handleImageLoad = (event: Event) => {
|
||||
if (img.naturalWidth && img.naturalHeight) {
|
||||
actualDimensions.value = `${img.naturalWidth} x ${img.naturalHeight}`
|
||||
}
|
||||
|
||||
if (props.nodeId) {
|
||||
nodeOutputStore.syncLegacyNodeImgs(props.nodeId, img, currentIndex.value)
|
||||
}
|
||||
}
|
||||
|
||||
const handleImageError = () => {
|
||||
@@ -218,19 +220,11 @@ const handleImageError = () => {
|
||||
actualDimensions.value = null
|
||||
}
|
||||
|
||||
// In vueNodes mode, we need to set them manually before opening the mask editor.
|
||||
const setupNodeForMaskEditor = () => {
|
||||
if (!props.nodeId || !currentImageEl.value) return
|
||||
const node = app.rootGraph?.getNodeById(props.nodeId)
|
||||
if (!node) return
|
||||
node.imageIndex = currentIndex.value
|
||||
node.imgs = [currentImageEl.value]
|
||||
app.canvas?.select(node)
|
||||
}
|
||||
|
||||
const handleEditMask = () => {
|
||||
setupNodeForMaskEditor()
|
||||
void commandStore.execute('Comfy.MaskEditor.OpenMaskEditor')
|
||||
if (!props.nodeId) return
|
||||
const node = app.rootGraph?.getNodeById(Number(props.nodeId))
|
||||
if (!node) return
|
||||
maskEditor.openMaskEditor(node)
|
||||
}
|
||||
|
||||
const handleDownload = () => {
|
||||
|
||||
Reference in New Issue
Block a user