@@ -3,6 +3,7 @@ import { type NodeId } from '@/lib/litegraph/src/LGraphNode'
33import {
44 type ExecutableLGraphNode ,
55 type ExecutionId ,
6+ LGraphCanvas ,
67 LGraphNode ,
78 LiteGraph ,
89 SubgraphNode
@@ -1172,8 +1173,7 @@ export class GroupNodeHandler {
11721173 // @ts -expect-error fixme ts strict error
11731174 getExtraMenuOptions ?. apply ( this , arguments )
11741175
1175- // @ts -expect-error fixme ts strict error
1176- let optionIndex = options . findIndex ( ( o ) => o . content === 'Outputs' )
1176+ let optionIndex = options . findIndex ( ( o ) => o ?. content === 'Outputs' )
11771177 if ( optionIndex === - 1 ) optionIndex = options . length
11781178 else optionIndex ++
11791179 options . splice (
@@ -1634,6 +1634,57 @@ export class GroupNodeHandler {
16341634 }
16351635}
16361636
1637+ function addConvertToGroupOptions ( ) {
1638+ // @ts -expect-error fixme ts strict error
1639+ function addConvertOption ( options , index ) {
1640+ const selected = Object . values ( app . canvas . selected_nodes ?? { } )
1641+ const disabled =
1642+ selected . length < 2 ||
1643+ selected . find ( ( n ) => GroupNodeHandler . isGroupNode ( n ) )
1644+ options . splice ( index , null , {
1645+ content : `Convert to Group Node (Deprecated)` ,
1646+ disabled,
1647+ callback : convertSelectedNodesToGroupNode
1648+ } )
1649+ }
1650+
1651+ // @ts -expect-error fixme ts strict error
1652+ function addManageOption ( options , index ) {
1653+ const groups = app . graph . extra ?. groupNodes
1654+ const disabled = ! groups || ! Object . keys ( groups ) . length
1655+ options . splice ( index , null , {
1656+ content : `Manage Group Nodes` ,
1657+ disabled,
1658+ callback : ( ) => manageGroupNodes ( )
1659+ } )
1660+ }
1661+
1662+ // Add to canvas
1663+ const getCanvasMenuOptions = LGraphCanvas . prototype . getCanvasMenuOptions
1664+ LGraphCanvas . prototype . getCanvasMenuOptions = function ( ) {
1665+ // @ts -expect-error fixme ts strict error
1666+ const options = getCanvasMenuOptions . apply ( this , arguments )
1667+ const index = options . findIndex ( ( o ) => o ?. content === 'Add Group' )
1668+ const insertAt = index === - 1 ? options . length - 1 : index + 2
1669+ addConvertOption ( options , insertAt )
1670+ addManageOption ( options , insertAt + 1 )
1671+ return options
1672+ }
1673+
1674+ // Add to nodes
1675+ const getNodeMenuOptions = LGraphCanvas . prototype . getNodeMenuOptions
1676+ LGraphCanvas . prototype . getNodeMenuOptions = function ( node ) {
1677+ // @ts -expect-error fixme ts strict error
1678+ const options = getNodeMenuOptions . apply ( this , arguments )
1679+ if ( ! GroupNodeHandler . isGroupNode ( node ) ) {
1680+ const index = options . findIndex ( ( o ) => o ?. content === 'Properties' )
1681+ const insertAt = index === - 1 ? options . length - 1 : index
1682+ addConvertOption ( options , insertAt )
1683+ }
1684+ return options
1685+ }
1686+ }
1687+
16371688const replaceLegacySeparators = ( nodes : ComfyNode [ ] ) : void => {
16381689 for ( const node of nodes ) {
16391690 if ( typeof node . type === 'string' && node . type . startsWith ( 'workflow/' ) ) {
@@ -1729,6 +1780,9 @@ const ext: ComfyExtension = {
17291780 }
17301781 }
17311782 ] ,
1783+ setup ( ) {
1784+ addConvertToGroupOptions ( )
1785+ } ,
17321786 async beforeConfigureGraph (
17331787 graphData : ComfyWorkflowJSON ,
17341788 missingNodeTypes : string [ ]
0 commit comments