-
Notifications
You must be signed in to change notification settings - Fork 391
Contextmenu extension migration #5993
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
5b37fc5
0685a1d
d94821b
9981f25
bee6f05
f939dd6
6d4a926
ef1ee73
d0c2151
5753b09
858e94c
107aed8
08ec5c3
2b12b86
17285e8
9b38a88
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,23 +1,48 @@ | ||||||||||||||||||||||||||||||
import { st, te } from '@/i18n' | ||||||||||||||||||||||||||||||
import { legacyMenuCompat } from '@/lib/litegraph/src/contextMenuCompat' | ||||||||||||||||||||||||||||||
import type { | ||||||||||||||||||||||||||||||
IContextMenuOptions, | ||||||||||||||||||||||||||||||
IContextMenuValue, | ||||||||||||||||||||||||||||||
INodeInputSlot, | ||||||||||||||||||||||||||||||
IWidget | ||||||||||||||||||||||||||||||
} from '@/lib/litegraph/src/litegraph' | ||||||||||||||||||||||||||||||
import { LGraphCanvas, LiteGraph } from '@/lib/litegraph/src/litegraph' | ||||||||||||||||||||||||||||||
import { app } from '@/scripts/app' | ||||||||||||||||||||||||||||||
import { normalizeI18nKey } from '@/utils/formatUtil' | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||
* Add translation for litegraph context menu. | ||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||
export const useContextMenuTranslation = () => { | ||||||||||||||||||||||||||||||
// Install compatibility layer BEFORE any extensions load | ||||||||||||||||||||||||||||||
legacyMenuCompat.install(LGraphCanvas.prototype, 'getCanvasMenuOptions') | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
const f = LGraphCanvas.prototype.getCanvasMenuOptions | ||||||||||||||||||||||||||||||
const getCanvasCenterMenuOptions = function ( | ||||||||||||||||||||||||||||||
this: LGraphCanvas, | ||||||||||||||||||||||||||||||
...args: Parameters<typeof f> | ||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||
const res = f.apply(this, args) as ReturnType<typeof f> | ||||||||||||||||||||||||||||||
const res: IContextMenuValue<string>[] = f.apply(this, args) | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// Add items from new extension API | ||||||||||||||||||||||||||||||
const newApiItems = app.collectCanvasMenuItems( | ||||||||||||||||||||||||||||||
this | ||||||||||||||||||||||||||||||
) as IContextMenuValue<string>[] | ||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||
for (const item of newApiItems) { | ||||||||||||||||||||||||||||||
res.push(item) | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// Add legacy monkey-patched items | ||||||||||||||||||||||||||||||
const legacyItems = legacyMenuCompat.extractLegacyItems( | ||||||||||||||||||||||||||||||
'getCanvasMenuOptions', | ||||||||||||||||||||||||||||||
this, | ||||||||||||||||||||||||||||||
...args | ||||||||||||||||||||||||||||||
) as ReturnType<typeof f> | ||||||||||||||||||||||||||||||
for (const item of legacyItems) { | ||||||||||||||||||||||||||||||
res.push(item) | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// Translate all items | ||||||||||||||||||||||||||||||
for (const item of res) { | ||||||||||||||||||||||||||||||
if (item?.content) { | ||||||||||||||||||||||||||||||
item.content = st(`contextMenu.${item.content}`, item.content) | ||||||||||||||||||||||||||||||
|
@@ -28,6 +53,33 @@ export const useContextMenuTranslation = () => { | |||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
LGraphCanvas.prototype.getCanvasMenuOptions = getCanvasCenterMenuOptions | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
legacyMenuCompat.registerWrapper( | ||||||||||||||||||||||||||||||
'getCanvasMenuOptions', | ||||||||||||||||||||||||||||||
getCanvasCenterMenuOptions, | ||||||||||||||||||||||||||||||
f, | ||||||||||||||||||||||||||||||
LGraphCanvas.prototype | ||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// Wrap getNodeMenuOptions to add new API items | ||||||||||||||||||||||||||||||
const nodeMenuFn = LGraphCanvas.prototype.getNodeMenuOptions | ||||||||||||||||||||||||||||||
const getNodeMenuOptionsWithExtensions = function ( | ||||||||||||||||||||||||||||||
this: LGraphCanvas, | ||||||||||||||||||||||||||||||
...args: Parameters<typeof nodeMenuFn> | ||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||
const res = nodeMenuFn.apply(this, args) | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// Add items from new extension API | ||||||||||||||||||||||||||||||
const node = args[0] | ||||||||||||||||||||||||||||||
const newApiItems = app.collectNodeMenuItems(node) | ||||||||||||||||||||||||||||||
for (const item of newApiItems) { | ||||||||||||||||||||||||||||||
res.push(item as (typeof res)[number]) | ||||||||||||||||||||||||||||||
Comment on lines
+69
to
+75
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
return res | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
LGraphCanvas.prototype.getNodeMenuOptions = getNodeMenuOptionsWithExtensions | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
function translateMenus( | ||||||||||||||||||||||||||||||
values: readonly (IContextMenuValue | string | null)[] | undefined, | ||||||||||||||||||||||||||||||
options: IContextMenuOptions | ||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
import { PREFIX, SEPARATOR } from '@/constants/groupNodeConstants' | ||
import { t } from '@/i18n' | ||
import { type NodeId } from '@/lib/litegraph/src/LGraphNode' | ||
import type { IContextMenuValue } from '@/lib/litegraph/src/interfaces' | ||
import { | ||
type ExecutableLGraphNode, | ||
type ExecutionId, | ||
LGraphCanvas, | ||
LGraphNode, | ||
LiteGraph, | ||
SubgraphNode | ||
|
@@ -1630,57 +1630,6 @@ export class GroupNodeHandler { | |
} | ||
} | ||
|
||
function addConvertToGroupOptions() { | ||
// @ts-expect-error fixme ts strict error | ||
function addConvertOption(options, index) { | ||
const selected = Object.values(app.canvas.selected_nodes ?? {}) | ||
const disabled = | ||
selected.length < 2 || | ||
selected.find((n) => GroupNodeHandler.isGroupNode(n)) | ||
options.splice(index, null, { | ||
content: `Convert to Group Node (Deprecated)`, | ||
disabled, | ||
callback: convertSelectedNodesToGroupNode | ||
}) | ||
} | ||
|
||
// @ts-expect-error fixme ts strict error | ||
function addManageOption(options, index) { | ||
const groups = app.graph.extra?.groupNodes | ||
const disabled = !groups || !Object.keys(groups).length | ||
options.splice(index, null, { | ||
content: `Manage Group Nodes`, | ||
disabled, | ||
callback: () => manageGroupNodes() | ||
}) | ||
} | ||
|
||
// Add to canvas | ||
const getCanvasMenuOptions = LGraphCanvas.prototype.getCanvasMenuOptions | ||
LGraphCanvas.prototype.getCanvasMenuOptions = function () { | ||
// @ts-expect-error fixme ts strict error | ||
const options = getCanvasMenuOptions.apply(this, arguments) | ||
const index = options.findIndex((o) => o?.content === 'Add Group') | ||
const insertAt = index === -1 ? options.length - 1 : index + 2 | ||
addConvertOption(options, insertAt) | ||
addManageOption(options, insertAt + 1) | ||
return options | ||
} | ||
|
||
// Add to nodes | ||
const getNodeMenuOptions = LGraphCanvas.prototype.getNodeMenuOptions | ||
LGraphCanvas.prototype.getNodeMenuOptions = function (node) { | ||
// @ts-expect-error fixme ts strict error | ||
const options = getNodeMenuOptions.apply(this, arguments) | ||
if (!GroupNodeHandler.isGroupNode(node)) { | ||
const index = options.findIndex((o) => o?.content === 'Properties') | ||
const insertAt = index === -1 ? options.length - 1 : index | ||
addConvertOption(options, insertAt) | ||
} | ||
return options | ||
} | ||
} | ||
|
||
const replaceLegacySeparators = (nodes: ComfyNode[]): void => { | ||
for (const node of nodes) { | ||
if (typeof node.type === 'string' && node.type.startsWith('workflow/')) { | ||
|
@@ -1776,8 +1725,50 @@ const ext: ComfyExtension = { | |
} | ||
} | ||
], | ||
setup() { | ||
addConvertToGroupOptions() | ||
|
||
getCanvasMenuItems(canvas): IContextMenuValue[] { | ||
const items: IContextMenuValue[] = [] | ||
const selected = Object.values(canvas.selected_nodes ?? {}) | ||
const convertDisabled = | ||
selected.length < 2 || | ||
!!selected.find((n) => GroupNodeHandler.isGroupNode(n)) | ||
Comment on lines
+1732
to
+1734
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Observation: This logic is in two places, but with different names. |
||
|
||
items.push({ | ||
content: `Convert to Group Node (Deprecated)`, | ||
disabled: convertDisabled, | ||
// @ts-expect-error fixme ts strict error - async callback | ||
callback: () => convertSelectedNodesToGroupNode() | ||
}) | ||
|
||
const groups = canvas.graph?.extra?.groupNodes | ||
const manageDisabled = !groups || !Object.keys(groups).length | ||
items.push({ | ||
content: `Manage Group Nodes`, | ||
disabled: manageDisabled, | ||
callback: () => manageGroupNodes() | ||
}) | ||
|
||
return items | ||
}, | ||
|
||
getNodeMenuItems(node): IContextMenuValue[] { | ||
if (GroupNodeHandler.isGroupNode(node)) { | ||
return [] | ||
} | ||
|
||
const selected = Object.values(app.canvas.selected_nodes ?? {}) | ||
const disabled = | ||
selected.length < 2 || | ||
!!selected.find((n) => GroupNodeHandler.isGroupNode(n)) | ||
|
||
return [ | ||
{ | ||
content: `Convert to Group Node (Deprecated)`, | ||
disabled, | ||
// @ts-expect-error fixme ts strict error - async callback | ||
callback: () => convertSelectedNodesToGroupNode() | ||
} | ||
] | ||
}, | ||
async beforeConfigureGraph( | ||
graphData: ComfyWorkflowJSON, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional naming change for clarity?