mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-15 01:48:06 +00:00
Compare commits
6 Commits
fix/codera
...
v1.39.13
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b952a8b21 | ||
|
|
9f760b543b | ||
|
|
805649e2c9 | ||
|
|
fc627106e1 | ||
|
|
3b88f55158 | ||
|
|
8cfc714e9f |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@comfyorg/comfyui-frontend",
|
||||
"version": "1.39.12",
|
||||
"version": "1.39.13",
|
||||
"private": true,
|
||||
"description": "Official front-end implementation of ComfyUI",
|
||||
"homepage": "https://comfy.org",
|
||||
|
||||
@@ -36,7 +36,7 @@ defineProps<{
|
||||
:side-offset="5"
|
||||
:collision-padding="10"
|
||||
v-bind="$attrs"
|
||||
class="rounded-lg p-2 bg-base-background shadow-sm border border-border-subtle will-change-[transform,opacity] data-[state=open]:data-[side=top]:animate-slideDownAndFade data-[state=open]:data-[side=right]:animate-slideLeftAndFade data-[state=open]:data-[side=bottom]:animate-slideUpAndFade data-[state=open]:data-[side=left]:animate-slideRightAndFade"
|
||||
class="z-1700 rounded-lg p-2 bg-base-background shadow-sm border border-border-subtle will-change-[transform,opacity] data-[state=open]:data-[side=top]:animate-slideDownAndFade data-[state=open]:data-[side=right]:animate-slideLeftAndFade data-[state=open]:data-[side=bottom]:animate-slideUpAndFade data-[state=open]:data-[side=left]:animate-slideRightAndFade"
|
||||
>
|
||||
<slot>
|
||||
<div class="flex flex-col p-1">
|
||||
|
||||
@@ -6,6 +6,7 @@ useExtensionService().registerExtension({
|
||||
async nodeCreated(node) {
|
||||
if (node.constructor.comfyClass !== 'ImageCropV2') return
|
||||
|
||||
node.hideOutputImages = true
|
||||
const [oldWidth, oldHeight] = node.size
|
||||
node.setSize([Math.max(oldWidth, 300), Math.max(oldHeight, 450)])
|
||||
}
|
||||
|
||||
@@ -215,6 +215,8 @@ export const useWorkflowService = () => {
|
||||
}
|
||||
}
|
||||
|
||||
workflowDraftStore.removeDraft(workflow.path)
|
||||
|
||||
// If this is the last workflow, create a new default temporary workflow
|
||||
if (workflowStore.openWorkflows.length === 1) {
|
||||
await loadDefaultWorkflow()
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
useWorkflowBookmarkStore,
|
||||
useWorkflowStore
|
||||
} from '@/platform/workflow/management/stores/workflowStore'
|
||||
import { useWorkflowDraftStore } from '@/platform/workflow/persistence/stores/workflowDraftStore'
|
||||
import { api } from '@/scripts/api'
|
||||
import { app as comfyApp } from '@/scripts/app'
|
||||
import { defaultGraph, defaultGraphJSON } from '@/scripts/defaultGraph'
|
||||
@@ -911,4 +912,41 @@ describe('useWorkflowStore', () => {
|
||||
expect(mostRecent).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
describe('closeWorkflow draft cleanup', () => {
|
||||
it('should remove draft for persisted workflows on close', async () => {
|
||||
const draftStore = useWorkflowDraftStore()
|
||||
await syncRemoteWorkflows(['a.json'])
|
||||
const workflow = store.getWorkflowByPath('workflows/a.json')!
|
||||
|
||||
draftStore.saveDraft('workflows/a.json', {
|
||||
data: '{"dirty":true}',
|
||||
updatedAt: Date.now(),
|
||||
name: 'a.json',
|
||||
isTemporary: false
|
||||
})
|
||||
expect(draftStore.getDraft('workflows/a.json')).toBeDefined()
|
||||
|
||||
await store.closeWorkflow(workflow)
|
||||
|
||||
expect(draftStore.getDraft('workflows/a.json')).toBeUndefined()
|
||||
})
|
||||
|
||||
it('should remove draft for temporary workflows on close', async () => {
|
||||
const draftStore = useWorkflowDraftStore()
|
||||
const workflow = store.createTemporary('temp.json')
|
||||
|
||||
draftStore.saveDraft(workflow.path, {
|
||||
data: '{"dirty":true}',
|
||||
updatedAt: Date.now(),
|
||||
name: 'temp.json',
|
||||
isTemporary: true
|
||||
})
|
||||
expect(draftStore.getDraft(workflow.path)).toBeDefined()
|
||||
|
||||
await store.closeWorkflow(workflow)
|
||||
|
||||
expect(draftStore.getDraft(workflow.path)).toBeUndefined()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -320,11 +320,9 @@ export const useWorkflowStore = defineStore('workflow', () => {
|
||||
openWorkflowPaths.value = openWorkflowPaths.value.filter(
|
||||
(path) => path !== workflow.path
|
||||
)
|
||||
useWorkflowDraftStore().removeDraft(workflow.path)
|
||||
if (workflow.isTemporary) {
|
||||
// Clear thumbnail when temporary workflow is closed
|
||||
clearThumbnail(workflow.key)
|
||||
// Clear draft when unsaved workflow tab is closed
|
||||
useWorkflowDraftStore().removeDraft(workflow.path)
|
||||
delete workflowLookup.value[workflow.path]
|
||||
} else {
|
||||
workflow.unload()
|
||||
|
||||
@@ -567,7 +567,8 @@ const nodeMedia = computed(() => {
|
||||
const newOutputs = nodeOutputs.nodeOutputs[nodeOutputLocatorId.value]
|
||||
const node = lgraphNode.value
|
||||
|
||||
if (!node || !newOutputs?.images?.length) return undefined
|
||||
if (!node || !newOutputs?.images?.length || node.hideOutputImages)
|
||||
return undefined
|
||||
|
||||
const urls = nodeOutputs.getNodeImageUrls(node)
|
||||
if (!urls?.length) return undefined
|
||||
|
||||
@@ -85,6 +85,24 @@ describe('imagePreviewStore setNodeOutputsByExecutionId with merge', () => {
|
||||
)
|
||||
expect(store.nodeOutputs[executionId]?.images).toHaveLength(2)
|
||||
})
|
||||
|
||||
it('should create a new object reference on merge so Vue detects the change', () => {
|
||||
const store = useNodeOutputStore()
|
||||
const executionId = '1'
|
||||
|
||||
const initialOutput = createMockOutputs([{ filename: 'a.png' }])
|
||||
store.setNodeOutputsByExecutionId(executionId, initialOutput)
|
||||
|
||||
const refBefore = store.nodeOutputs[executionId]
|
||||
|
||||
const newOutput = createMockOutputs([{ filename: 'b.png' }])
|
||||
store.setNodeOutputsByExecutionId(executionId, newOutput, { merge: true })
|
||||
|
||||
const refAfter = store.nodeOutputs[executionId]
|
||||
|
||||
expect(refAfter).not.toBe(refBefore)
|
||||
expect(refAfter?.images).toHaveLength(2)
|
||||
})
|
||||
})
|
||||
|
||||
describe('imagePreviewStore getPreviewParam', () => {
|
||||
|
||||
@@ -152,7 +152,7 @@ export const useNodeOutputStore = defineStore('nodeOutput', () => {
|
||||
existingOutput[k] = newValue
|
||||
}
|
||||
}
|
||||
nodeOutputs.value[nodeLocatorId] = existingOutput
|
||||
nodeOutputs.value[nodeLocatorId] = { ...existingOutput }
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
2
src/types/litegraph-augmentation.d.ts
vendored
2
src/types/litegraph-augmentation.d.ts
vendored
@@ -177,6 +177,8 @@ declare module '@/lib/litegraph/src/litegraph' {
|
||||
isLoading?: boolean
|
||||
/** The content type of the node's preview media */
|
||||
previewMediaType?: 'image' | 'video' | 'audio' | 'model'
|
||||
/** If true, output images are stored but not rendered below the node */
|
||||
hideOutputImages?: boolean
|
||||
|
||||
preview: string[]
|
||||
/** Index of the currently selected image on a multi-image node such as Preview Image */
|
||||
|
||||
Reference in New Issue
Block a user