mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-04 23:20:07 +00:00
┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8074-Further-linear-fixes-2e96d73d365081efb74bf150982c7a66) by [Unito](https://www.unito.io)
120 lines
3.3 KiB
TypeScript
120 lines
3.3 KiB
TypeScript
import { whenever } from '@vueuse/core'
|
|
import { defineStore } from 'pinia'
|
|
import type { MenuItem } from 'primevue/menuitem'
|
|
import { ref } from 'vue'
|
|
|
|
import { CORE_MENU_COMMANDS } from '@/constants/coreMenuCommands'
|
|
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
|
import type { ComfyExtension } from '@/types/comfy'
|
|
|
|
import { useCommandStore } from './commandStore'
|
|
|
|
export const useMenuItemStore = defineStore('menuItem', () => {
|
|
const canvasStore = useCanvasStore()
|
|
const commandStore = useCommandStore()
|
|
const menuItems = ref<MenuItem[]>([])
|
|
const menuItemHasActiveStateChildren = ref<Record<string, boolean>>({})
|
|
const hasSeenLinear = ref(false)
|
|
|
|
whenever(
|
|
() => canvasStore.linearMode,
|
|
() => (hasSeenLinear.value = true),
|
|
{ immediate: true, once: true }
|
|
)
|
|
|
|
const registerMenuGroup = (path: string[], items: MenuItem[]) => {
|
|
let currentLevel = menuItems.value
|
|
|
|
// Traverse the path, creating nodes if necessary
|
|
for (let i = 0; i < path.length; i++) {
|
|
const segment = path[i]
|
|
let found = currentLevel.find((item) => item.label === segment)
|
|
|
|
if (!found) {
|
|
// Create a new node if it doesn't exist
|
|
found = {
|
|
label: segment,
|
|
key: segment,
|
|
items: []
|
|
}
|
|
currentLevel.push(found)
|
|
}
|
|
|
|
// Ensure the found item has an 'items' array
|
|
if (!found.items) {
|
|
found.items = []
|
|
}
|
|
|
|
// Move to the next level
|
|
currentLevel = found.items
|
|
}
|
|
|
|
if (currentLevel.length > 0) {
|
|
currentLevel.push({
|
|
separator: true
|
|
})
|
|
}
|
|
// Add the new items to the last level
|
|
currentLevel.push(...items)
|
|
|
|
// Store if any of the children have active state as we will hide the icon if they do
|
|
const parentPath = path.join('.')
|
|
if (!menuItemHasActiveStateChildren.value[parentPath]) {
|
|
menuItemHasActiveStateChildren.value[parentPath] = items.some(
|
|
(item) => item.comfyCommand?.active
|
|
)
|
|
}
|
|
}
|
|
|
|
const registerCommands = (path: string[], commandIds: string[]) => {
|
|
const items = commandIds
|
|
.map((commandId) => commandStore.getCommand(commandId))
|
|
.map(
|
|
(command) =>
|
|
({
|
|
command: () => commandStore.execute(command.id),
|
|
label: command.menubarLabel,
|
|
icon: command.icon,
|
|
tooltip: command.tooltip,
|
|
comfyCommand: command,
|
|
parentPath: path.join('.')
|
|
}) as MenuItem
|
|
)
|
|
registerMenuGroup(path, items)
|
|
}
|
|
|
|
const loadExtensionMenuCommands = (extension: ComfyExtension) => {
|
|
if (!extension.menuCommands) {
|
|
return
|
|
}
|
|
|
|
const extensionCommandIds = new Set(
|
|
extension.commands?.map((command) => command.id) ?? []
|
|
)
|
|
extension.menuCommands.forEach((menuCommand) => {
|
|
const commands = menuCommand.commands.filter((command) =>
|
|
extensionCommandIds.has(command)
|
|
)
|
|
if (commands.length) {
|
|
registerCommands(menuCommand.path, commands)
|
|
}
|
|
})
|
|
}
|
|
|
|
const registerCoreMenuCommands = () => {
|
|
for (const [path, commands] of CORE_MENU_COMMANDS) {
|
|
registerCommands(path, commands)
|
|
}
|
|
}
|
|
|
|
return {
|
|
menuItems,
|
|
registerMenuGroup,
|
|
registerCommands,
|
|
loadExtensionMenuCommands,
|
|
registerCoreMenuCommands,
|
|
menuItemHasActiveStateChildren,
|
|
hasSeenLinear
|
|
}
|
|
})
|