diff --git a/browser_tests/browserTabTitle.spec.ts b/browser_tests/browserTabTitle.spec.ts index 0d2889974..512c396de 100644 --- a/browser_tests/browserTabTitle.spec.ts +++ b/browser_tests/browserTabTitle.spec.ts @@ -4,7 +4,7 @@ import { comfyPageFixture as test } from './ComfyPage' test.describe('Browser tab title', () => { test.describe('Beta Menu', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.setSetting('Comfy.UseNewMenu', 'Floating') }) test.afterEach(async ({ comfyPage }) => { diff --git a/browser_tests/groupNode.spec.ts b/browser_tests/groupNode.spec.ts index cf8cb6989..56f76f1aa 100644 --- a/browser_tests/groupNode.spec.ts +++ b/browser_tests/groupNode.spec.ts @@ -13,7 +13,7 @@ test.describe('Group Node', () => { let libraryTab test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.setSetting('Comfy.UseNewMenu', 'Floating') libraryTab = comfyPage.menu.nodeLibraryTab await comfyPage.convertAllNodesToGroupNode(groupNodeName) await libraryTab.open() diff --git a/browser_tests/menu.spec.ts b/browser_tests/menu.spec.ts index acab00aef..9eec3e97b 100644 --- a/browser_tests/menu.spec.ts +++ b/browser_tests/menu.spec.ts @@ -3,7 +3,7 @@ import { comfyPageFixture as test } from './ComfyPage' test.describe('Menu', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.setSetting('Comfy.UseNewMenu', 'Floating') }) test.afterEach(async ({ comfyPage }) => { diff --git a/browser_tests/propertiesPanel.spec.ts b/browser_tests/propertiesPanel.spec.ts index 8e889f3aa..b9c96b714 100644 --- a/browser_tests/propertiesPanel.spec.ts +++ b/browser_tests/propertiesPanel.spec.ts @@ -2,8 +2,16 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from './ComfyPage' test.describe('Properties Panel', () => { - test('Can change property value', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + test.beforeEach(async ({ comfyPage }) => { + await comfyPage.setSetting('Comfy.UseNewMenu', 'Floating') + }) + + test.afterEach(async ({ comfyPage }) => { + await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + }) + + // TODO: Update expectation after new menu dropdown is added. + test.skip('Can change property value', async ({ comfyPage }) => { await comfyPage.rightClickEmptyLatentNode() await comfyPage.page.getByText('Properties Panel').click() await comfyPage.nextFrame() @@ -19,6 +27,5 @@ test.describe('Properties Panel', () => { ) await propertyInput.fill('Empty Latent Image') - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') }) }) diff --git a/src/components/LiteGraphCanvasSplitterOverlay.vue b/src/components/LiteGraphCanvasSplitterOverlay.vue index aea6d4ed1..f91663fd8 100644 --- a/src/components/LiteGraphCanvasSplitterOverlay.vue +++ b/src/components/LiteGraphCanvasSplitterOverlay.vue @@ -75,9 +75,4 @@ const gutterClass = computed(() => { z-index: 999; border: none; } - -.comfyui-floating-menu .splitter-overlay { - top: var(--comfy-floating-menu-height); - height: calc(100% - var(--comfy-floating-menu-height)); -} diff --git a/src/scripts/ui/menu/index.ts b/src/scripts/ui/menu/index.ts index 7b28853d2..bbca3ce47 100644 --- a/src/scripts/ui/menu/index.ts +++ b/src/scripts/ui/menu/index.ts @@ -8,9 +8,6 @@ import { ComfySplitButton } from '../components/splitButton' import { ComfyQueueButton } from './queueButton' import { getInterruptButton } from './interruptButton' import './menu.css' -import type { ComfySettingsDialog } from '../settings' - -type MenuPosition = 'Disabled' | 'Top' | 'Bottom' | 'Floating' const collapseOnMobile = (t) => { ;(t.element ?? t).classList.add('comfyui-menu-mobile-collapse') @@ -22,16 +19,6 @@ const showOnMobile = (t) => { } export class ComfyAppMenu { - #sizeBreak = 'lg' - #lastSizeBreaks = { - lg: null, - md: null, - sm: null, - xs: null - } - #sizeBreaks = Object.keys(this.#lastSizeBreaks) - #cachedInnerSize = null - #cacheTimeout = null app: ComfyApp logo: HTMLElement saveButton: ComfySplitButton @@ -41,8 +28,6 @@ export class ComfyAppMenu { mobileMenuButton: ComfyButton queueButton: ComfyQueueButton element: HTMLElement - menuPositionSetting: ReturnType - position: MenuPosition constructor(app: ComfyApp) { this.app = app @@ -151,166 +136,6 @@ export class ComfyAppMenu { this.queueButton.element, showOnMobile(this.mobileMenuButton).element ]) - - let resizeHandler: () => void - this.menuPositionSetting = app.ui.settings.addSetting({ - id: 'Comfy.UseNewMenu', - category: ['Comfy', 'Menu', 'UseNewMenu'], - defaultValue: 'Disabled', - name: 'Use new menu and workflow management.', - experimental: true, - tooltip: 'On small screens the menu will always be at the top.', - type: 'combo', - options: ['Disabled', 'Floating', 'Top', 'Bottom'], - onChange: async (v: MenuPosition) => { - if (v && v !== 'Disabled') { - const floating = v === 'Floating' - if (floating) { - if (resizeHandler) { - window.removeEventListener('resize', resizeHandler) - resizeHandler = null - } - this.element.classList.add('floating') - document.body.classList.add('comfyui-floating-menu') - } else { - this.element.classList.remove('floating') - document.body.classList.remove('comfyui-floating-menu') - if (!resizeHandler) { - resizeHandler = () => { - this.calculateSizeBreak() - } - window.addEventListener('resize', resizeHandler) - } - } - - for (const b of [ - ...actionButtons.map((b) => b.element), - interruptButton, - this.queueButton.element - ]) { - b.style.display = floating ? 'none' : null - } - - this.updatePosition(v) - } else { - if (resizeHandler) { - window.removeEventListener('resize', resizeHandler) - resizeHandler = null - } - document.body.style.removeProperty('display') - if (app.ui.menuContainer) { - app.ui.menuContainer.style.removeProperty('display') - } - this.element.style.display = 'none' - app.ui.restoreMenuPosition() - } - window.dispatchEvent(new Event('resize')) - } - }) - } - - updatePosition(v: MenuPosition) { - document.body.style.display = 'grid' - if (this.app.ui.menuContainer) { - this.app.ui.menuContainer.style.display = 'none' - } - this.element.style.removeProperty('display') - this.position = v - if (v === 'Bottom') { - this.app.bodyBottom.append(this.element) - } else { - this.app.bodyTop.prepend(this.element) - } - if (v === 'Floating') { - this.updateSizeBreak(0, this.#sizeBreaks.indexOf(this.#sizeBreak), -999) - } else { - this.calculateSizeBreak() - } - } - - updateSizeBreak(idx: number, prevIdx: number, direction: number) { - const newSize = this.#sizeBreaks[idx] - if (newSize === this.#sizeBreak) return - this.#cachedInnerSize = null - clearTimeout(this.#cacheTimeout) - - this.#sizeBreak = this.#sizeBreaks[idx] - for (let i = 0; i < this.#sizeBreaks.length; i++) { - const sz = this.#sizeBreaks[i] - if (sz === this.#sizeBreak) { - this.element.classList.add(sz) - } else { - this.element.classList.remove(sz) - } - if (i < idx) { - this.element.classList.add('lt-' + sz) - } else { - this.element.classList.remove('lt-' + sz) - } - } - - if (idx) { - // We're on a small screen, force the menu at the top - if (this.position !== 'Top') { - this.updatePosition('Top') - } - } else if (this.position != this.menuPositionSetting.value) { - // Restore user position - this.updatePosition(this.menuPositionSetting.value) - } - - // Allow multiple updates, but prevent bouncing - if (!direction) { - direction = prevIdx - idx - } else if (direction != prevIdx - idx) { - return - } - this.calculateSizeBreak(direction) - } - - calculateSizeBreak(direction = 0) { - let idx = this.#sizeBreaks.indexOf(this.#sizeBreak) - const currIdx = idx - const innerSize = this.calculateInnerSize(idx) - if (window.innerWidth >= this.#lastSizeBreaks[this.#sizeBreaks[idx - 1]]) { - if (idx > 0) { - idx-- - } - } else if (innerSize > this.element.clientWidth) { - this.#lastSizeBreaks[this.#sizeBreak] = Math.max( - window.innerWidth, - innerSize - ) - // We need to shrink - if (idx < this.#sizeBreaks.length - 1) { - idx++ - } - } - - this.updateSizeBreak(idx, currIdx, direction) - } - - calculateInnerSize(idx: number) { - // Cache the inner size to prevent too much calculation when resizing the window - clearTimeout(this.#cacheTimeout) - if (this.#cachedInnerSize) { - // Extend cache time - this.#cacheTimeout = setTimeout(() => (this.#cachedInnerSize = null), 100) - } else { - let innerSize = 0 - let count = 1 - for (const c of this.element.children) { - if (c.classList.contains('comfyui-menu-push')) continue // ignore right push - if (idx && c.classList.contains('comfyui-menu-mobile-collapse')) - continue // ignore collapse items - innerSize += c.clientWidth - count++ - } - innerSize += 8 * count - this.#cachedInnerSize = innerSize - this.#cacheTimeout = setTimeout(() => (this.#cachedInnerSize = null), 100) - } - return this.#cachedInnerSize } getFilename(defaultName: string) { diff --git a/src/scripts/ui/menu/menu.css b/src/scripts/ui/menu/menu.css index ef0998a74..c01dab45e 100644 --- a/src/scripts/ui/menu/menu.css +++ b/src/scripts/ui/menu/menu.css @@ -1,7 +1,3 @@ -:root { - --comfy-floating-menu-height: 45px; -} - .mdi.rotate270::before { transform: rotate(270deg); } @@ -144,23 +140,6 @@ max-height: 90vh; } -.comfyui-menu.floating { - width: max-content; - padding: 8px 0 8px 12px; - overflow: hidden; - border-bottom-right-radius: 12px; - height: var(--comfy-floating-menu-height); - position: absolute; -} - -.comfyui-menu.floating .comfyui-logo { - padding-right: 8px; -} - -.comfyui-floating-menu .comfyui-body-left { - margin-top: var(--comfy-floating-menu-height); -} - .comfyui-menu>* { flex-shrink: 0; } diff --git a/src/stores/coreSettings.ts b/src/stores/coreSettings.ts index 0c7c2b41a..9270d0dd5 100644 --- a/src/stores/coreSettings.ts +++ b/src/stores/coreSettings.ts @@ -363,5 +363,14 @@ export const CORE_SETTINGS: SettingParams[] = [ element.style.display = value ? 'flex' : 'none' } } + }, + { + id: 'Comfy.UseNewMenu', + category: ['Comfy', 'Menu', 'UseNewMenu'], + defaultValue: 'Disabled', + name: 'Use new menu and workflow management.', + experimental: true, + type: 'combo', + options: ['Disabled', 'Floating'] } ] diff --git a/src/types/apiTypes.ts b/src/types/apiTypes.ts index 73da75a37..aa064c42a 100644 --- a/src/types/apiTypes.ts +++ b/src/types/apiTypes.ts @@ -493,7 +493,7 @@ const zSettings = z.record(z.any()).and( 'Comfy.SnapToGrid.GridSize': z.number(), 'Comfy.TextareaWidget.FontSize': z.number(), 'Comfy.TextareaWidget.Spellcheck': z.boolean(), - 'Comfy.UseNewMenu': z.enum(['Disabled', 'Floating', 'Top', 'Bottom']), + 'Comfy.UseNewMenu': z.enum(['Disabled', 'Floating']), 'Comfy.TreeExplorer.ItemPadding': z.number(), 'Comfy.Validation.Workflows': z.boolean(), 'Comfy.Workflow.SortNodeIdOnSave': z.boolean(), diff --git a/src/views/GraphView.vue b/src/views/GraphView.vue index 2e59107f6..9fa92f20c 100644 --- a/src/views/GraphView.vue +++ b/src/views/GraphView.vue @@ -87,6 +87,22 @@ watchEffect(() => { } }) +watchEffect(() => { + const useNewMenu = settingStore.get('Comfy.UseNewMenu') + if (useNewMenu === 'Disabled') { + app.ui.restoreMenuPosition() + document.body.style.removeProperty('display') + if (app.ui.menuContainer) { + app.ui.menuContainer.style.removeProperty('display') + } + } else { + document.body.style.setProperty('display', 'grid') + if (app.ui.menuContainer) { + app.ui.menuContainer.style.setProperty('display', 'none') + } + } +}) + const init = () => { settingStore.addSettings(app.ui.settings) app.extensionManager = useWorkspaceStore()