mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-26 19:09:52 +00:00
Remove support of Top/Bottom in menu positions (#933)
* Remove support of Top/Bottom in menu positions * Update menu positions in test setting * nit
This commit is contained in:
@@ -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 }) => {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 }) => {
|
||||
|
||||
@@ -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')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -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<ComfySettingsDialog['addSetting']>
|
||||
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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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']
|
||||
}
|
||||
]
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user