Update compatibility with the latest frontend version
This commit is contained in:
+127
-25
@@ -1,4 +1,5 @@
|
||||
import { app } from "/scripts/app.js";
|
||||
import { SettingIds } from "../core/constants.js";
|
||||
|
||||
export function findOriginalPropertiesButton() {
|
||||
const byTestId = document.querySelector('[data-testid="properties-panel-toggle"]');
|
||||
@@ -26,7 +27,7 @@ export function findOriginalPropertiesButton() {
|
||||
}
|
||||
|
||||
export function findTopbarContainer() {
|
||||
const container = document.querySelector('[data-testid="action-bar-buttons"], [class*="actionbar-buttons"], .actionbar-buttons, [class*="actionbar"]');
|
||||
const container = document.querySelector('.actionbar-container, [data-testid="action-bar-buttons"], [class*="actionbar-buttons"], .actionbar-buttons, [class*="actionbar"]');
|
||||
if (container) return container;
|
||||
|
||||
const orig = findOriginalPropertiesButton();
|
||||
@@ -156,6 +157,11 @@ export function findNativeExtensionsPanel() {
|
||||
}
|
||||
|
||||
export function findGraphButton() {
|
||||
const byTestId = document.querySelector('[data-testid="view-mode-toggle"]');
|
||||
if (byTestId && !byTestId.closest('.p-dialog, .comfy-modal, [role="dialog"], .p-sidebar, .comfy-settings, .comfyui-sidebar, .comfy-sidebar')) {
|
||||
return byTestId;
|
||||
}
|
||||
|
||||
const elements = document.querySelectorAll('.p-1.bg-base-background.rounded-lg, .bg-base-background.rounded-lg, .bg-secondary-background.rounded-lg.items-center.inline-flex.pointer-events-auto, [data-testid="graph-view-button"]');
|
||||
for (const el of elements) {
|
||||
if (el.closest('.p-dialog, .comfy-modal, [role="dialog"], .p-sidebar, .comfy-settings, .comfyui-sidebar, .comfy-sidebar')) continue;
|
||||
@@ -230,39 +236,135 @@ export function updateSidebarBadge(count) {
|
||||
}
|
||||
}
|
||||
|
||||
export function applySidebarOverride() {
|
||||
const overrideStock = app.ui.settings?.getSettingValue?.("Comfy Sidebar.Hide Junk.Override Stock Job History Tab") ?? false;
|
||||
const stdBtn = findStandardQueueButton();
|
||||
const ourBtn = findOurSidebarButton();
|
||||
let isApplyingSidebarOverride = false;
|
||||
|
||||
if (stdBtn) {
|
||||
if (!stdBtn._originalDisplay) {
|
||||
stdBtn._originalDisplay = window.getComputedStyle(stdBtn).display || "block";
|
||||
export function findSidebarMenuButton(sidebar) {
|
||||
const root = sidebar || document.querySelector('[data-testid="sidebar-top-group"]') ||
|
||||
document.querySelector('.comfyui-sidebar, .comfy-sidebar, .sidebar');
|
||||
if (!root) return null;
|
||||
|
||||
// 1. Look for explicit menu or logo test ID
|
||||
const byTestId = root.querySelector(
|
||||
'[data-testid*="menu-button"], [data-testid*="app-menu"], [data-testid*="comfy-logo"], [data-testid="sidebar-menu-button"]'
|
||||
);
|
||||
if (byTestId) {
|
||||
return byTestId.closest('button, [role="button"], .comfyui-sidebar-tab, .comfyui-sidebar-item') || byTestId;
|
||||
}
|
||||
|
||||
// 2. Look for title, tooltip, or aria-label containing "menu"
|
||||
const candidates = Array.from(root.querySelectorAll('button, [role="button"], a, .comfyui-sidebar-tab, .comfyui-sidebar-item'));
|
||||
const menuBtn = candidates.find(el => {
|
||||
if (el.classList.contains('comfy-sidebar-tab') || el.id?.includes('classic-comfy-sidebar')) return false;
|
||||
const title = (el.getAttribute('title') || el.getAttribute('aria-label') || el.textContent || '').trim().toLowerCase();
|
||||
return title === 'menu' || title.startsWith('menu');
|
||||
});
|
||||
if (menuBtn) return menuBtn;
|
||||
|
||||
// 3. Fallback: the first child element that is not our button and not the stock queue button
|
||||
const ourBtn = findOurSidebarButton();
|
||||
const stdBtn = findStandardQueueButton();
|
||||
for (const child of root.children) {
|
||||
if (child !== ourBtn && child !== stdBtn) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function applySidebarOverride() {
|
||||
if (isApplyingSidebarOverride) return;
|
||||
isApplyingSidebarOverride = true;
|
||||
|
||||
try {
|
||||
const overrideStock = (
|
||||
app.extensionManager?.setting?.get?.(SettingIds.OVERRIDE_STOCK_HISTORY) ??
|
||||
app.ui?.settings?.getSettingValue?.(SettingIds.OVERRIDE_STOCK_HISTORY) ??
|
||||
app.ui?.settings?.getSettingValue?.("Comfy Sidebar.Hide Junk.Override Stock Job History Tab") ??
|
||||
app.ui?.settings?.getSettingValue?.("Comfy Sidebar.Override Stock History") ??
|
||||
false
|
||||
);
|
||||
const stdBtn = findStandardQueueButton();
|
||||
const ourBtn = findOurSidebarButton();
|
||||
const topGroup = document.querySelector('[data-testid="sidebar-top-group"]') ||
|
||||
(ourBtn ? ourBtn.closest('[data-testid="sidebar-top-group"]') : null);
|
||||
|
||||
if (ourBtn && !ourBtn._capturedOriginal) {
|
||||
ourBtn._capturedOriginal = true;
|
||||
ourBtn._originalParent = ourBtn.parentNode;
|
||||
ourBtn._originalNextSibling = ourBtn.nextSibling;
|
||||
}
|
||||
|
||||
if (overrideStock) {
|
||||
stdBtn.style.setProperty("display", "none", "important");
|
||||
if (!stdBtn._overrideClickListener) {
|
||||
stdBtn._overrideClickListener = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const b = findOurSidebarButton();
|
||||
if (b) b.click();
|
||||
};
|
||||
stdBtn.addEventListener('click', stdBtn._overrideClickListener, true);
|
||||
if (stdBtn) {
|
||||
if (!stdBtn._originalDisplay) {
|
||||
stdBtn._originalDisplay = window.getComputedStyle(stdBtn).display || "block";
|
||||
}
|
||||
if (stdBtn.style.display !== "none") {
|
||||
stdBtn.style.setProperty("display", "none", "important");
|
||||
}
|
||||
if (!stdBtn._overrideClickListener) {
|
||||
stdBtn._overrideClickListener = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const b = findOurSidebarButton();
|
||||
if (b) b.click();
|
||||
};
|
||||
stdBtn.addEventListener('click', stdBtn._overrideClickListener, true);
|
||||
}
|
||||
}
|
||||
if (ourBtn && stdBtn.parentNode && ourBtn.nextSibling !== stdBtn) {
|
||||
stdBtn.parentNode.insertBefore(ourBtn, stdBtn);
|
||||
|
||||
if (ourBtn) {
|
||||
const parent = (topGroup && topGroup.contains(ourBtn)) ? topGroup : (stdBtn ? stdBtn.parentNode : ourBtn.parentNode);
|
||||
if (parent) {
|
||||
const menuBtn = findSidebarMenuButton(parent);
|
||||
if (menuBtn && menuBtn.parentNode === parent) {
|
||||
// Place Queue immediately below the Menu button
|
||||
if (menuBtn.nextSibling !== ourBtn) {
|
||||
parent.insertBefore(ourBtn, menuBtn.nextSibling);
|
||||
}
|
||||
} else if (stdBtn && stdBtn.parentNode === parent) {
|
||||
// Place Queue right where stock Job History was
|
||||
if (stdBtn.previousSibling !== ourBtn && stdBtn !== ourBtn) {
|
||||
parent.insertBefore(ourBtn, stdBtn);
|
||||
}
|
||||
} else {
|
||||
// Fallback: top of the group
|
||||
const first = parent.firstElementChild;
|
||||
if (first && first !== ourBtn) {
|
||||
parent.insertBefore(ourBtn, first);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
stdBtn.style.setProperty("display", stdBtn._originalDisplay === "none" ? "block" : stdBtn._originalDisplay);
|
||||
if (stdBtn._overrideClickListener) {
|
||||
stdBtn.removeEventListener('click', stdBtn._overrideClickListener, true);
|
||||
stdBtn._overrideClickListener = null;
|
||||
if (stdBtn) {
|
||||
if (stdBtn.style.display === "none") {
|
||||
stdBtn.style.removeProperty("display");
|
||||
if (stdBtn._originalDisplay && stdBtn._originalDisplay !== "none") {
|
||||
stdBtn.style.display = stdBtn._originalDisplay;
|
||||
}
|
||||
}
|
||||
if (stdBtn._overrideClickListener) {
|
||||
stdBtn.removeEventListener('click', stdBtn._overrideClickListener, true);
|
||||
stdBtn._overrideClickListener = null;
|
||||
}
|
||||
}
|
||||
if (ourBtn && stdBtn.parentNode && ourBtn.parentNode === stdBtn.parentNode && ourBtn !== stdBtn.parentNode.lastChild) {
|
||||
stdBtn.parentNode.appendChild(ourBtn);
|
||||
|
||||
if (ourBtn) {
|
||||
if (ourBtn._originalNextSibling && ourBtn._originalNextSibling.parentNode === ourBtn.parentNode) {
|
||||
if (ourBtn.nextSibling !== ourBtn._originalNextSibling) {
|
||||
ourBtn.parentNode.insertBefore(ourBtn, ourBtn._originalNextSibling);
|
||||
}
|
||||
} else if (ourBtn._originalParent && ourBtn.parentNode === ourBtn._originalParent) {
|
||||
if (ourBtn !== ourBtn.parentNode.lastElementChild) {
|
||||
ourBtn.parentNode.appendChild(ourBtn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
isApplyingSidebarOverride = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+48
-11
@@ -6,8 +6,10 @@ import {
|
||||
findActiveQueueIndicator,
|
||||
findNativeExtensionsPanel,
|
||||
findGraphButton,
|
||||
findPropertiesPanel
|
||||
findPropertiesPanel,
|
||||
applySidebarOverride
|
||||
} from "./adapter.js";
|
||||
import { SettingIds } from "../core/constants.js";
|
||||
import { isRuntimePreviewEnabled, setRuntimePreviewEnabled, setRuntimePreviewStateListener } from "../utils/comparison.js";
|
||||
|
||||
// Listen for runtime preview state changes to keep button UI in sync
|
||||
@@ -18,20 +20,22 @@ setRuntimePreviewStateListener(() => {
|
||||
const STYLE_ID = "comfy-sidebar-classic-layout-override";
|
||||
|
||||
const CLASSIC_LAYOUT_CSS_MEDIA = `
|
||||
/* Neutralize the leftover floating shell box to prevent empty dark square artifacts */
|
||||
.actionbar-container,
|
||||
.shadow-interface.rounded-lg.bg-comfy-menu-bg:not(.floating-panel):not([role="toolbar"]),
|
||||
.shadow-interface.rounded-lg.border-interface-stroke:not(.floating-panel):not([role="toolbar"]),
|
||||
.shadow-interface.border.rounded-lg:has([class*="actionbar-buttons"]),
|
||||
.shadow-interface.border.rounded-lg:has(.actionbar-buttons),
|
||||
div.border-interface-stroke.rounded-lg:has([class*="actionbar-buttons"]),
|
||||
div.shadow-interface.py-1\\.75 {
|
||||
/* Neutralize the leftover floating shell box to prevent empty dark square/circle artifacts */
|
||||
[data-testid="action-bar-card"],
|
||||
.floating-panel:has(.actionbar-container),
|
||||
.floating-panel:has([class*="actionbar"]),
|
||||
div.shadow-interface:has(.actionbar-container),
|
||||
div.shadow-interface:has([class*="actionbar-buttons"]),
|
||||
div:has(> .actionbar-container):not(header):not(.topbar),
|
||||
div:has(> [class*="actionbar"]):not(header):not(.topbar):not(.actionbar-container) {
|
||||
border: none !important;
|
||||
background: transparent !important;
|
||||
box-shadow: none !important;
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
/* Dock actionbar buttons in the topbar row with transparent background */
|
||||
.actionbar-container,
|
||||
[class*="actionbar"]:not(.actionbar),
|
||||
[class*="actionbar-buttons"],
|
||||
.actionbar-buttons {
|
||||
@@ -102,9 +106,27 @@ export function syncStockHistoryAndProgressSettings(enable) {
|
||||
|
||||
let savedButtonData = null;
|
||||
let domObserver = null;
|
||||
let sidebarTopObserver = null;
|
||||
let syncScheduled = false;
|
||||
let actionbarResizeObserver = null;
|
||||
|
||||
function setupSidebarTopObserver() {
|
||||
if (sidebarTopObserver) return;
|
||||
const target = document.querySelector('[data-testid="sidebar-top-group"]') ||
|
||||
document.querySelector('.comfyui-sidebar, .comfy-sidebar, .sidebar');
|
||||
if (!target) return;
|
||||
|
||||
sidebarTopObserver = new MutationObserver(() => {
|
||||
applySidebarOverride();
|
||||
updateSidebarTabsVisibility();
|
||||
});
|
||||
|
||||
sidebarTopObserver.observe(target, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
}
|
||||
|
||||
function isSidebarOnLeft() {
|
||||
const sidebar = document.querySelector('.comfyui-sidebar, .comfy-sidebar, .sidebar, [class*="sidebar-nav"], [class*="sidebar"]');
|
||||
if (!sidebar) return false;
|
||||
@@ -371,7 +393,7 @@ function setupCanvasMenuPopoverRelocator() {
|
||||
}
|
||||
|
||||
function updateTopMetrics() {
|
||||
const bar = document.querySelector('.actionbar-buttons, [class*="actionbar-buttons"]') || findTopbarContainer();
|
||||
const bar = document.querySelector('.actionbar-container, .actionbar-buttons, [class*="actionbar-buttons"]') || findTopbarContainer();
|
||||
const tabsEl = document.querySelector('.workflow-tabs-container');
|
||||
const topbar = tabsEl?.closest('header, .topbar, [class*="topbar"]') || tabsEl;
|
||||
|
||||
@@ -491,7 +513,13 @@ function updateSidebarTabsVisibility() {
|
||||
}
|
||||
});
|
||||
|
||||
const hideStockHistory = app.ui?.settings?.getSettingValue("Comfy Sidebar.Hide Junk.Override Stock Job History Tab") ?? false;
|
||||
const hideStockHistory = (
|
||||
app.extensionManager?.setting?.get?.(SettingIds.OVERRIDE_STOCK_HISTORY) ??
|
||||
app.ui?.settings?.getSettingValue?.(SettingIds.OVERRIDE_STOCK_HISTORY) ??
|
||||
app.ui?.settings?.getSettingValue?.("Comfy Sidebar.Hide Junk.Override Stock Job History Tab") ??
|
||||
app.ui?.settings?.getSettingValue?.("Comfy Sidebar.Override Stock History") ??
|
||||
false
|
||||
);
|
||||
const historyTarget = sidebar.querySelector('[data-testid="queue-tab-button"], [data-testid="job-history-tab-button"], [class*="lucide--history"]');
|
||||
if (historyTarget) {
|
||||
const historyBtn = historyTarget.closest('.comfyui-sidebar-tab, button, [role="tab"], li, a, .comfyui-sidebar-item') || historyTarget;
|
||||
@@ -775,6 +803,10 @@ export function syncClassicLayout() {
|
||||
syncPropertiesButton(isClassicLayoutEnabled);
|
||||
syncActiveQueueIndicator(isClassicLayoutEnabled);
|
||||
updateSidebarTabsVisibility();
|
||||
applySidebarOverride();
|
||||
if (!sidebarTopObserver) {
|
||||
setupSidebarTopObserver();
|
||||
}
|
||||
syncRuntimePreviewButton();
|
||||
|
||||
} catch (err) {
|
||||
@@ -792,6 +824,7 @@ export function syncClassicLayout() {
|
||||
export function setupPropertiesPanelToggleFix() {
|
||||
setupCanvasMenuTooltipRelocator();
|
||||
setupCanvasMenuPopoverRelocator();
|
||||
setupSidebarTopObserver();
|
||||
|
||||
if (!document.getElementById("comfy-sidebar-layout-fix-styles")) {
|
||||
const style = document.createElement("style");
|
||||
@@ -1083,6 +1116,10 @@ export function destroyLayoutFix() {
|
||||
domObserver.disconnect();
|
||||
domObserver = null;
|
||||
}
|
||||
if (sidebarTopObserver) {
|
||||
sidebarTopObserver.disconnect();
|
||||
sidebarTopObserver = null;
|
||||
}
|
||||
if (actionbarResizeObserver) {
|
||||
actionbarResizeObserver.disconnect();
|
||||
actionbarResizeObserver = null;
|
||||
|
||||
+10
-2
@@ -3,7 +3,7 @@ import { SettingIds } from "./core/constants.js";
|
||||
import { injectStyles } from "./utils/styles.js";
|
||||
import { setupDragAndDrop } from "./utils/dragdrop.js";
|
||||
import { renumberNodesTopologically, setManualNodeId } from "./utils/nodeRenumber.js";
|
||||
import { findOurSidebarButton } from "./comfy/adapter.js";
|
||||
import { findOurSidebarButton, applySidebarOverride } from "./comfy/adapter.js";
|
||||
import { syncAllNodeBadges, setupVueNodeObserver, toggleIgnoreActiveNode } from "./comfy/nodes.js";
|
||||
import { applyClassicLayout, setupPropertiesPanelToggleFix, syncClassicLayout, syncStockHistoryAndProgressSettings, destroyLayoutFix } from "./comfy/layout.js";
|
||||
import { initSessionAndHistory, syncQueue } from "./queue/queueService.js";
|
||||
@@ -75,7 +75,11 @@ function registerSettings() {
|
||||
if (isInitialized && app.ui?.settings) {
|
||||
syncStockHistoryAndProgressSettings(value);
|
||||
}
|
||||
setTimeout(() => { syncClassicLayout(); }, 0);
|
||||
applySidebarOverride();
|
||||
setTimeout(() => {
|
||||
applySidebarOverride();
|
||||
syncClassicLayout();
|
||||
}, 50);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -450,6 +454,10 @@ app.registerExtension({
|
||||
type: "custom",
|
||||
render: (el) => { el.appendChild(sidebarContainer); }
|
||||
});
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
applySidebarOverride();
|
||||
});
|
||||
},
|
||||
|
||||
destroy() {
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
[project]
|
||||
name = "comfy-sidebar"
|
||||
description = "A compact and powerful layout overhaul for ComfyUI that makes generation results easier to browse, preview, compare, and manage."
|
||||
version = "1.7.3"
|
||||
version = "1.7.4"
|
||||
license = { file = "LICENSE" }
|
||||
dependencies = [
|
||||
"send2trash>=1.8.0",
|
||||
|
||||
Reference in New Issue
Block a user