From dabcd4741beebf6296f83da8869a95f221c165a5 Mon Sep 17 00:00:00 2001 From: Chenlei Hu Date: Tue, 3 Dec 2024 20:06:19 -0800 Subject: [PATCH] [Refactor] Extract command definitions to coreCommandHooks (#1785) * [Refactor] Extract command definitions to coreCommandHooks * Register core commands * Fix rebase issue --- src/hooks/coreCommandHooks.ts | 479 +++++++++++++++++++++++++++++++++ src/stores/commandStore.ts | 481 +--------------------------------- src/views/GraphView.vue | 4 + 3 files changed, 489 insertions(+), 475 deletions(-) create mode 100644 src/hooks/coreCommandHooks.ts diff --git a/src/hooks/coreCommandHooks.ts b/src/hooks/coreCommandHooks.ts new file mode 100644 index 000000000..2059cd394 --- /dev/null +++ b/src/hooks/coreCommandHooks.ts @@ -0,0 +1,479 @@ +import { app } from '@/scripts/app' +import { api } from '@/scripts/api' +import { + showSettingsDialog, + showTemplateWorkflowsDialog +} from '@/services/dialogService' +import { workflowService } from '@/services/workflowService' +import type { ComfyCommand } from '@/stores/commandStore' +import { useTitleEditorStore } from '@/stores/graphStore' +import { useQueueSettingsStore, useQueueStore } from '@/stores/queueStore' +import { useSettingStore } from '@/stores/settingStore' +import { useToastStore } from '@/stores/toastStore' +import { type ComfyWorkflow, useWorkflowStore } from '@/stores/workflowStore' +import { useBottomPanelStore } from '@/stores/workspace/bottomPanelStore' +import { useWorkspaceStore } from '@/stores/workspaceStore' +import { LGraphGroup } from '@comfyorg/litegraph' +import { LiteGraph } from '@comfyorg/litegraph' +import { LGraphNode } from '@comfyorg/litegraph' + +export function useCoreCommands(): ComfyCommand[] { + const getTracker = () => useWorkflowStore()?.activeWorkflow?.changeTracker + + const getSelectedNodes = (): LGraphNode[] => { + const selectedNodes = app.canvas.selected_nodes + const result: LGraphNode[] = [] + if (selectedNodes) { + for (const i in selectedNodes) { + const node = selectedNodes[i] + result.push(node) + } + } + return result + } + + const toggleSelectedNodesMode = (mode: number) => { + getSelectedNodes().forEach((node) => { + if (node.mode === mode) { + node.mode = 0 // always + } else { + node.mode = mode + } + }) + } + + return [ + { + id: 'Comfy.NewBlankWorkflow', + icon: 'pi pi-plus', + label: 'New Blank Workflow', + menubarLabel: 'New', + function: () => workflowService.loadBlankWorkflow() + }, + { + id: 'Comfy.OpenWorkflow', + icon: 'pi pi-folder-open', + label: 'Open Workflow', + menubarLabel: 'Open', + function: () => { + app.ui.loadFile() + } + }, + { + id: 'Comfy.LoadDefaultWorkflow', + icon: 'pi pi-code', + label: 'Load Default Workflow', + function: () => workflowService.loadDefaultWorkflow() + }, + { + id: 'Comfy.SaveWorkflow', + icon: 'pi pi-save', + label: 'Save Workflow', + menubarLabel: 'Save', + function: async () => { + const workflow = useWorkflowStore().activeWorkflow as ComfyWorkflow + if (!workflow) return + + await workflowService.saveWorkflow(workflow) + } + }, + { + id: 'Comfy.SaveWorkflowAs', + icon: 'pi pi-save', + label: 'Save Workflow As', + menubarLabel: 'Save As', + function: async () => { + const workflow = useWorkflowStore().activeWorkflow as ComfyWorkflow + if (!workflow) return + + await workflowService.saveWorkflowAs(workflow) + } + }, + { + id: 'Comfy.ExportWorkflow', + icon: 'pi pi-download', + label: 'Export Workflow', + menubarLabel: 'Export', + function: () => { + workflowService.exportWorkflow('workflow', 'workflow') + } + }, + { + id: 'Comfy.ExportWorkflowAPI', + icon: 'pi pi-download', + label: 'Export Workflow (API Format)', + menubarLabel: 'Export (API)', + function: () => { + workflowService.exportWorkflow('workflow_api', 'output') + } + }, + { + id: 'Comfy.Undo', + icon: 'pi pi-undo', + label: 'Undo', + function: async () => { + await getTracker()?.undo?.() + } + }, + { + id: 'Comfy.Redo', + icon: 'pi pi-refresh', + label: 'Redo', + function: async () => { + await getTracker()?.redo?.() + } + }, + { + id: 'Comfy.ClearWorkflow', + icon: 'pi pi-trash', + label: 'Clear Workflow', + function: () => { + const settingStore = useSettingStore() + if ( + !settingStore.get('Comfy.ComfirmClear') || + confirm('Clear workflow?') + ) { + app.clean() + app.graph.clear() + api.dispatchCustomEvent('graphCleared') + } + } + }, + { + id: 'Comfy.Canvas.ResetView', + icon: 'pi pi-expand', + label: 'Reset View', + function: () => { + app.resetView() + } + }, + { + id: 'Comfy.OpenClipspace', + icon: 'pi pi-clipboard', + label: 'Clipspace', + function: () => { + app.openClipspace() + } + }, + { + id: 'Comfy.RefreshNodeDefinitions', + icon: 'pi pi-refresh', + label: 'Refresh Node Definitions', + function: async () => { + await app.refreshComboInNodes() + } + }, + { + id: 'Comfy.Interrupt', + icon: 'pi pi-stop', + label: 'Interrupt', + function: async () => { + await api.interrupt() + useToastStore().add({ + severity: 'info', + summary: 'Interrupted', + detail: 'Execution has been interrupted', + life: 1000 + }) + } + }, + { + id: 'Comfy.ClearPendingTasks', + icon: 'pi pi-stop', + label: 'Clear Pending Tasks', + function: async () => { + await useQueueStore().clear(['queue']) + useToastStore().add({ + severity: 'info', + summary: 'Confirmed', + detail: 'Pending tasks deleted', + life: 3000 + }) + } + }, + { + id: 'Comfy.BrowseTemplates', + icon: 'pi pi-folder-open', + label: 'Browse Templates', + function: showTemplateWorkflowsDialog + }, + { + id: 'Comfy.Canvas.ZoomIn', + icon: 'pi pi-plus', + label: 'Zoom In', + function: () => { + const ds = app.canvas.ds + ds.changeScale( + ds.scale * 1.1, + ds.element ? [ds.element.width / 2, ds.element.height / 2] : undefined + ) + app.canvas.setDirty(true, true) + } + }, + { + id: 'Comfy.Canvas.ZoomOut', + icon: 'pi pi-minus', + label: 'Zoom Out', + function: () => { + const ds = app.canvas.ds + ds.changeScale( + ds.scale / 1.1, + ds.element ? [ds.element.width / 2, ds.element.height / 2] : undefined + ) + app.canvas.setDirty(true, true) + } + }, + { + id: 'Comfy.Canvas.FitView', + icon: 'pi pi-expand', + label: 'Fit view to selected nodes', + function: () => app.canvas.fitViewToSelectionAnimated() + }, + { + id: 'Comfy.Canvas.ToggleLock', + icon: 'pi pi-lock', + label: 'Toggle Lock', + function: () => { + app.canvas['read_only'] = !app.canvas['read_only'] + } + }, + { + id: 'Comfy.Canvas.ToggleLinkVisibility', + icon: 'pi pi-eye', + label: 'Toggle Link Visibility', + versionAdded: '1.3.6', + + function: (() => { + const settingStore = useSettingStore() + let lastLinksRenderMode = LiteGraph.SPLINE_LINK + + return () => { + const currentMode = settingStore.get('Comfy.LinkRenderMode') + + if (currentMode === LiteGraph.HIDDEN_LINK) { + // If links are hidden, restore the last positive value or default to spline mode + settingStore.set('Comfy.LinkRenderMode', lastLinksRenderMode) + } else { + // If links are visible, store the current mode and hide links + lastLinksRenderMode = currentMode + settingStore.set('Comfy.LinkRenderMode', LiteGraph.HIDDEN_LINK) + } + } + })() + }, + { + id: 'Comfy.QueuePrompt', + icon: 'pi pi-play', + label: 'Queue Prompt', + versionAdded: '1.3.7', + function: () => { + const batchCount = useQueueSettingsStore().batchCount + app.queuePrompt(0, batchCount) + } + }, + { + id: 'Comfy.QueuePromptFront', + icon: 'pi pi-play', + label: 'Queue Prompt (Front)', + versionAdded: '1.3.7', + function: () => { + const batchCount = useQueueSettingsStore().batchCount + app.queuePrompt(-1, batchCount) + } + }, + { + id: 'Comfy.ShowSettingsDialog', + icon: 'pi pi-cog', + label: 'Settings', + versionAdded: '1.3.7', + function: () => { + showSettingsDialog() + } + }, + { + id: 'Comfy.Graph.GroupSelectedNodes', + icon: 'pi pi-sitemap', + label: 'Group Selected Nodes', + versionAdded: '1.3.7', + function: () => { + const { canvas } = app + if (!canvas.selectedItems?.size) { + useToastStore().add({ + severity: 'error', + summary: 'Nothing to group', + detail: + 'Please select the nodes (or other groups) to create a group for', + life: 3000 + }) + return + } + const group = new LGraphGroup() + const padding = useSettingStore().get( + 'Comfy.GroupSelectedNodes.Padding' + ) + group.resizeTo(canvas.selectedItems, padding) + canvas.graph.add(group) + useTitleEditorStore().titleEditorTarget = group + } + }, + { + id: 'Workspace.NextOpenedWorkflow', + icon: 'pi pi-step-forward', + label: 'Next Opened Workflow', + versionAdded: '1.3.9', + function: () => { + workflowService.loadNextOpenedWorkflow() + } + }, + { + id: 'Workspace.PreviousOpenedWorkflow', + icon: 'pi pi-step-backward', + label: 'Previous Opened Workflow', + versionAdded: '1.3.9', + function: () => { + workflowService.loadPreviousOpenedWorkflow() + } + }, + { + id: 'Comfy.Canvas.ToggleSelectedNodes.Mute', + icon: 'pi pi-volume-off', + label: 'Mute/Unmute Selected Nodes', + versionAdded: '1.3.11', + function: () => { + toggleSelectedNodesMode(2) // muted + } + }, + { + id: 'Comfy.Canvas.ToggleSelectedNodes.Bypass', + icon: 'pi pi-shield', + label: 'Bypass/Unbypass Selected Nodes', + versionAdded: '1.3.11', + function: () => { + toggleSelectedNodesMode(4) // bypassed + } + }, + { + id: 'Comfy.Canvas.ToggleSelectedNodes.Pin', + icon: 'pi pi-pin', + label: 'Pin/Unpin Selected Nodes', + versionAdded: '1.3.11', + function: () => { + getSelectedNodes().forEach((node) => { + node.pin(!node.pinned) + }) + } + }, + { + id: 'Comfy.Canvas.ToggleSelected.Pin', + icon: 'pi pi-pin', + label: 'Pin/Unpin Selected Items', + versionAdded: '1.3.33', + function: () => { + for (const item of app.canvas.selectedItems) { + if (item instanceof LGraphNode || item instanceof LGraphGroup) { + item.pin(!item.pinned) + } + } + } + }, + { + id: 'Comfy.Canvas.ToggleSelectedNodes.Collapse', + icon: 'pi pi-minus', + label: 'Collapse/Expand Selected Nodes', + versionAdded: '1.3.11', + function: () => { + getSelectedNodes().forEach((node) => { + node.collapse() + }) + } + }, + { + id: 'Comfy.ToggleTheme', + icon: 'pi pi-moon', + label: 'Toggle Theme', + versionAdded: '1.3.12', + function: (() => { + let previousDarkTheme: string = 'dark' + + // Official light theme is the only light theme supported now. + const isDarkMode = (themeId: string) => themeId !== 'light' + return () => { + const settingStore = useSettingStore() + const currentTheme = settingStore.get('Comfy.ColorPalette') + if (isDarkMode(currentTheme)) { + previousDarkTheme = currentTheme + settingStore.set('Comfy.ColorPalette', 'light') + } else { + settingStore.set('Comfy.ColorPalette', previousDarkTheme) + } + } + })() + }, + { + id: 'Workspace.ToggleBottomPanel', + icon: 'pi pi-list', + label: 'Toggle Bottom Panel', + versionAdded: '1.3.22', + function: () => { + useBottomPanelStore().toggleBottomPanel() + } + }, + { + id: 'Workspace.ToggleFocusMode', + icon: 'pi pi-eye', + label: 'Toggle Focus Mode', + versionAdded: '1.3.27', + function: () => { + useWorkspaceStore().toggleFocusMode() + } + }, + { + id: 'Comfy.Graph.FitGroupToContents', + icon: 'pi pi-expand', + label: 'Fit Group To Contents', + versionAdded: '1.4.9', + function: () => { + for (const group of app.canvas.selectedItems) { + if (group instanceof LGraphGroup) { + group.recomputeInsideNodes() + const padding = useSettingStore().get( + 'Comfy.GroupSelectedNodes.Padding' + ) + group.resizeTo(group.children, padding) + app.graph.change() + } + } + } + }, + { + id: 'Comfy.Help.OpenComfyUIIssues', + icon: 'pi pi-github', + label: 'ComfyUI Issues', + versionAdded: '1.5.5', + function: () => { + window.open( + 'https://github.com/comfyanonymous/ComfyUI/issues', + '_blank' + ) + } + }, + { + id: 'Comfy.Help.OpenComfyUIDocs', + icon: 'pi pi-info-circle', + label: 'ComfyUI Docs', + versionAdded: '1.5.5', + function: () => { + window.open('https://docs.comfy.org/', '_blank') + } + }, + { + id: 'Comfy.Help.OpenComfyOrgDiscord', + icon: 'pi pi-discord', + label: 'Comfy-Org Discord', + versionAdded: '1.5.5', + function: () => { + window.open('https://www.comfy.org/discord', '_blank') + } + } + ] +} diff --git a/src/stores/commandStore.ts b/src/stores/commandStore.ts index cc34bb43f..54e69623c 100644 --- a/src/stores/commandStore.ts +++ b/src/stores/commandStore.ts @@ -1,25 +1,8 @@ -import { app } from '@/scripts/app' -import { api } from '@/scripts/api' import { defineStore } from 'pinia' import { computed, ref } from 'vue' -import { useSettingStore } from '@/stores/settingStore' -import { useToastStore } from '@/stores/toastStore' -import { - showSettingsDialog, - showTemplateWorkflowsDialog -} from '@/services/dialogService' -import { useQueueSettingsStore, useQueueStore } from './queueStore' -import { LiteGraph } from '@comfyorg/litegraph' -import { ComfyExtension } from '@/types/comfy' -import { LGraphGroup } from '@comfyorg/litegraph' -import { useTitleEditorStore } from './graphStore' +import type { ComfyExtension } from '@/types/comfy' import { useErrorHandling } from '@/hooks/errorHooks' -import { ComfyWorkflow, useWorkflowStore } from './workflowStore' import { type KeybindingImpl, useKeybindingStore } from './keybindingStore' -import { useBottomPanelStore } from './workspace/bottomPanelStore' -import { LGraphNode } from '@comfyorg/litegraph' -import { useWorkspaceStore } from './workspaceStore' -import { workflowService } from '@/services/workflowService' export interface ComfyCommand { id: string @@ -75,33 +58,7 @@ export class ComfyCommandImpl implements ComfyCommand { } } -const getTracker = () => useWorkflowStore()?.activeWorkflow?.changeTracker - -const getSelectedNodes = (): LGraphNode[] => { - const selectedNodes = app.canvas.selected_nodes - const result: LGraphNode[] = [] - if (selectedNodes) { - for (const i in selectedNodes) { - const node = selectedNodes[i] - result.push(node) - } - } - return result -} - -const toggleSelectedNodesMode = (mode: number) => { - getSelectedNodes().forEach((node) => { - if (node.mode === mode) { - node.mode = 0 // always - } else { - node.mode = mode - } - }) -} - export const useCommandStore = defineStore('command', () => { - const settingStore = useSettingStore() - const commandsById = ref>({}) const commands = computed(() => Object.values(commandsById.value)) @@ -112,439 +69,12 @@ export const useCommandStore = defineStore('command', () => { commandsById.value[command.id] = new ComfyCommandImpl(command) } - const commandDefinitions: ComfyCommand[] = [ - { - id: 'Comfy.NewBlankWorkflow', - icon: 'pi pi-plus', - label: 'New Blank Workflow', - menubarLabel: 'New', - function: () => workflowService.loadBlankWorkflow() - }, - { - id: 'Comfy.OpenWorkflow', - icon: 'pi pi-folder-open', - label: 'Open Workflow', - menubarLabel: 'Open', - function: () => { - app.ui.loadFile() - } - }, - { - id: 'Comfy.LoadDefaultWorkflow', - icon: 'pi pi-code', - label: 'Load Default Workflow', - function: () => workflowService.loadDefaultWorkflow() - }, - { - id: 'Comfy.SaveWorkflow', - icon: 'pi pi-save', - label: 'Save Workflow', - menubarLabel: 'Save', - function: async () => { - const workflow = useWorkflowStore().activeWorkflow as ComfyWorkflow - if (!workflow) return - - await workflowService.saveWorkflow(workflow) - } - }, - { - id: 'Comfy.SaveWorkflowAs', - icon: 'pi pi-save', - label: 'Save Workflow As', - menubarLabel: 'Save As', - function: async () => { - const workflow = useWorkflowStore().activeWorkflow as ComfyWorkflow - if (!workflow) return - - await workflowService.saveWorkflowAs(workflow) - } - }, - { - id: 'Comfy.ExportWorkflow', - icon: 'pi pi-download', - label: 'Export Workflow', - menubarLabel: 'Export', - function: () => { - workflowService.exportWorkflow('workflow', 'workflow') - } - }, - { - id: 'Comfy.ExportWorkflowAPI', - icon: 'pi pi-download', - label: 'Export Workflow (API Format)', - menubarLabel: 'Export (API)', - function: () => { - workflowService.exportWorkflow('workflow_api', 'output') - } - }, - { - id: 'Comfy.Undo', - icon: 'pi pi-undo', - label: 'Undo', - function: async () => { - await getTracker()?.undo?.() - } - }, - { - id: 'Comfy.Redo', - icon: 'pi pi-refresh', - label: 'Redo', - function: async () => { - await getTracker()?.redo?.() - } - }, - { - id: 'Comfy.ClearWorkflow', - icon: 'pi pi-trash', - label: 'Clear Workflow', - function: () => { - if ( - !settingStore.get('Comfy.ComfirmClear') || - confirm('Clear workflow?') - ) { - app.clean() - app.graph.clear() - api.dispatchCustomEvent('graphCleared') - } - } - }, - { - id: 'Comfy.Canvas.ResetView', - icon: 'pi pi-expand', - label: 'Reset View', - function: () => { - app.resetView() - } - }, - { - id: 'Comfy.OpenClipspace', - icon: 'pi pi-clipboard', - label: 'Clipspace', - function: () => { - app.openClipspace() - } - }, - { - id: 'Comfy.RefreshNodeDefinitions', - icon: 'pi pi-refresh', - label: 'Refresh Node Definitions', - function: async () => { - await app.refreshComboInNodes() - } - }, - { - id: 'Comfy.Interrupt', - icon: 'pi pi-stop', - label: 'Interrupt', - function: async () => { - await api.interrupt() - useToastStore().add({ - severity: 'info', - summary: 'Interrupted', - detail: 'Execution has been interrupted', - life: 1000 - }) - } - }, - { - id: 'Comfy.ClearPendingTasks', - icon: 'pi pi-stop', - label: 'Clear Pending Tasks', - function: async () => { - await useQueueStore().clear(['queue']) - useToastStore().add({ - severity: 'info', - summary: 'Confirmed', - detail: 'Pending tasks deleted', - life: 3000 - }) - } - }, - { - id: 'Comfy.BrowseTemplates', - icon: 'pi pi-folder-open', - label: 'Browse Templates', - function: showTemplateWorkflowsDialog - }, - { - id: 'Comfy.Canvas.ZoomIn', - icon: 'pi pi-plus', - label: 'Zoom In', - function: () => { - const ds = app.canvas.ds - ds.changeScale( - ds.scale * 1.1, - ds.element ? [ds.element.width / 2, ds.element.height / 2] : undefined - ) - app.canvas.setDirty(true, true) - } - }, - { - id: 'Comfy.Canvas.ZoomOut', - icon: 'pi pi-minus', - label: 'Zoom Out', - function: () => { - const ds = app.canvas.ds - ds.changeScale( - ds.scale / 1.1, - ds.element ? [ds.element.width / 2, ds.element.height / 2] : undefined - ) - app.canvas.setDirty(true, true) - } - }, - { - id: 'Comfy.Canvas.FitView', - icon: 'pi pi-expand', - label: 'Fit view to selected nodes', - function: () => app.canvas.fitViewToSelectionAnimated() - }, - { - id: 'Comfy.Canvas.ToggleLock', - icon: 'pi pi-lock', - label: 'Toggle Lock', - function: () => { - app.canvas['read_only'] = !app.canvas['read_only'] - } - }, - { - id: 'Comfy.Canvas.ToggleLinkVisibility', - icon: 'pi pi-eye', - label: 'Toggle Link Visibility', - versionAdded: '1.3.6', - - function: (() => { - let lastLinksRenderMode = LiteGraph.SPLINE_LINK - - return () => { - const currentMode = settingStore.get('Comfy.LinkRenderMode') - - if (currentMode === LiteGraph.HIDDEN_LINK) { - // If links are hidden, restore the last positive value or default to spline mode - settingStore.set('Comfy.LinkRenderMode', lastLinksRenderMode) - } else { - // If links are visible, store the current mode and hide links - lastLinksRenderMode = currentMode - settingStore.set('Comfy.LinkRenderMode', LiteGraph.HIDDEN_LINK) - } - } - })() - }, - { - id: 'Comfy.QueuePrompt', - icon: 'pi pi-play', - label: 'Queue Prompt', - versionAdded: '1.3.7', - function: () => { - const batchCount = useQueueSettingsStore().batchCount - app.queuePrompt(0, batchCount) - } - }, - { - id: 'Comfy.QueuePromptFront', - icon: 'pi pi-play', - label: 'Queue Prompt (Front)', - versionAdded: '1.3.7', - function: () => { - const batchCount = useQueueSettingsStore().batchCount - app.queuePrompt(-1, batchCount) - } - }, - { - id: 'Comfy.ShowSettingsDialog', - icon: 'pi pi-cog', - label: 'Settings', - versionAdded: '1.3.7', - function: () => { - showSettingsDialog() - } - }, - { - id: 'Comfy.Graph.GroupSelectedNodes', - icon: 'pi pi-sitemap', - label: 'Group Selected Nodes', - versionAdded: '1.3.7', - function: () => { - const { canvas } = app - if (!canvas.selectedItems?.size) { - useToastStore().add({ - severity: 'error', - summary: 'Nothing to group', - detail: - 'Please select the nodes (or other groups) to create a group for', - life: 3000 - }) - return - } - const group = new LGraphGroup() - const padding = useSettingStore().get( - 'Comfy.GroupSelectedNodes.Padding' - ) - group.resizeTo(canvas.selectedItems, padding) - canvas.graph.add(group) - useTitleEditorStore().titleEditorTarget = group - } - }, - { - id: 'Workspace.NextOpenedWorkflow', - icon: 'pi pi-step-forward', - label: 'Next Opened Workflow', - versionAdded: '1.3.9', - function: () => { - workflowService.loadNextOpenedWorkflow() - } - }, - { - id: 'Workspace.PreviousOpenedWorkflow', - icon: 'pi pi-step-backward', - label: 'Previous Opened Workflow', - versionAdded: '1.3.9', - function: () => { - workflowService.loadPreviousOpenedWorkflow() - } - }, - { - id: 'Comfy.Canvas.ToggleSelectedNodes.Mute', - icon: 'pi pi-volume-off', - label: 'Mute/Unmute Selected Nodes', - versionAdded: '1.3.11', - function: () => { - toggleSelectedNodesMode(2) // muted - } - }, - { - id: 'Comfy.Canvas.ToggleSelectedNodes.Bypass', - icon: 'pi pi-shield', - label: 'Bypass/Unbypass Selected Nodes', - versionAdded: '1.3.11', - function: () => { - toggleSelectedNodesMode(4) // bypassed - } - }, - { - id: 'Comfy.Canvas.ToggleSelectedNodes.Pin', - icon: 'pi pi-pin', - label: 'Pin/Unpin Selected Nodes', - versionAdded: '1.3.11', - function: () => { - getSelectedNodes().forEach((node) => { - node.pin(!node.pinned) - }) - } - }, - { - id: 'Comfy.Canvas.ToggleSelected.Pin', - icon: 'pi pi-pin', - label: 'Pin/Unpin Selected Items', - versionAdded: '1.3.33', - function: () => { - for (const item of app.canvas.selectedItems) { - if (item instanceof LGraphNode || item instanceof LGraphGroup) { - item.pin(!item.pinned) - } - } - } - }, - { - id: 'Comfy.Canvas.ToggleSelectedNodes.Collapse', - icon: 'pi pi-minus', - label: 'Collapse/Expand Selected Nodes', - versionAdded: '1.3.11', - function: () => { - getSelectedNodes().forEach((node) => { - node.collapse() - }) - } - }, - { - id: 'Comfy.ToggleTheme', - icon: 'pi pi-moon', - label: 'Toggle Theme', - versionAdded: '1.3.12', - function: (() => { - let previousDarkTheme: string = 'dark' - - // Official light theme is the only light theme supported now. - const isDarkMode = (themeId: string) => themeId !== 'light' - return () => { - const currentTheme = settingStore.get('Comfy.ColorPalette') - if (isDarkMode(currentTheme)) { - previousDarkTheme = currentTheme - settingStore.set('Comfy.ColorPalette', 'light') - } else { - settingStore.set('Comfy.ColorPalette', previousDarkTheme) - } - } - })() - }, - { - id: 'Workspace.ToggleBottomPanel', - icon: 'pi pi-list', - label: 'Toggle Bottom Panel', - versionAdded: '1.3.22', - function: () => { - useBottomPanelStore().toggleBottomPanel() - } - }, - { - id: 'Workspace.ToggleFocusMode', - icon: 'pi pi-eye', - label: 'Toggle Focus Mode', - versionAdded: '1.3.27', - function: () => { - useWorkspaceStore().toggleFocusMode() - } - }, - { - id: 'Comfy.Graph.FitGroupToContents', - icon: 'pi pi-expand', - label: 'Fit Group To Contents', - versionAdded: '1.4.9', - function: () => { - for (const group of app.canvas.selectedItems) { - if (group instanceof LGraphGroup) { - group.recomputeInsideNodes() - const padding = useSettingStore().get( - 'Comfy.GroupSelectedNodes.Padding' - ) - group.resizeTo(group.children, padding) - app.graph.change() - } - } - } - }, - { - id: 'Comfy.Help.OpenComfyUIIssues', - icon: 'pi pi-github', - label: 'ComfyUI Issues', - versionAdded: '1.5.5', - function: () => { - window.open( - 'https://github.com/comfyanonymous/ComfyUI/issues', - '_blank' - ) - } - }, - { - id: 'Comfy.Help.OpenComfyUIDocs', - icon: 'pi pi-info-circle', - label: 'ComfyUI Docs', - versionAdded: '1.5.5', - function: () => { - window.open('https://docs.comfy.org/', '_blank') - } - }, - { - id: 'Comfy.Help.OpenComfyOrgDiscord', - icon: 'pi pi-discord', - label: 'Comfy-Org Discord', - versionAdded: '1.5.5', - function: () => { - window.open('https://www.comfy.org/discord', '_blank') - } + const registerCommands = (commands: ComfyCommand[]) => { + for (const command of commands) { + registerCommand(command) } - ] + } - commandDefinitions.forEach(registerCommand) const getCommand = (command: string) => { return commandsById.value[command] } @@ -579,6 +109,7 @@ export const useCommandStore = defineStore('command', () => { execute, getCommand, registerCommand, + registerCommands, isRegistered, loadExtensionCommands } diff --git a/src/views/GraphView.vue b/src/views/GraphView.vue index 90d962138..9cfeae883 100644 --- a/src/views/GraphView.vue +++ b/src/views/GraphView.vue @@ -40,6 +40,8 @@ import { useModelStore } from '@/stores/modelStore' import { useServerConfigStore } from '@/stores/serverConfigStore' import { SERVER_CONFIG_ITEMS } from '@/constants/serverConfig' import { useMenuItemStore } from '@/stores/menuItemStore' +import { useCommandStore } from '@/stores/commandStore' +import { useCoreCommands } from '@/hooks/coreCommandHooks' setupAutoQueueHandler() @@ -105,6 +107,8 @@ watchEffect(() => { const init = () => { settingStore.addSettings(app.ui.settings) + const coreCommands = useCoreCommands() + useCommandStore().registerCommands(coreCommands) useMenuItemStore().registerCoreMenuCommands() useKeybindingStore().loadCoreKeybindings() useSidebarTabStore().registerCoreSidebarTabs()