Files
abdullahceylan-ac-comfyui-q…/web/menu_extension.js
T

403 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* ComfyUI Queue Manager Menu Extension
* Integrates the Queue Manager into ComfyUI's menu system
*/
import { app } from "/scripts/app.js";
import { api } from "/scripts/api.js";
// Queue Manager window reference
let queueManagerWindow = null;
let queueManagerTab = null;
/**
* Queue Manager Menu Extension
*/
class QueueManagerMenuExtension {
constructor() {
this.name = "QueueManager.MenuExtension";
this.menuItem = null;
}
/**
* Initialize the menu extension
*/
init() {
// Register menu item when ComfyUI is ready
app.registerExtension({
name: this.name,
async setup() {
// Add menu item to ComfyUI's menu
this.addMenuItem();
},
async beforeRegisterNodeDef(nodeType, nodeData, app) {
// Hook into node registration if needed
if (nodeData.name === "QueueManagerNode") {
// Add any node-specific menu integrations here
console.log("[Queue Manager] Node registered:", nodeData.name);
}
},
});
}
/**
* Add Queue Manager menu item to ComfyUI's menu
*/
addMenuItem() {
try {
// Get ComfyUI's menu container
const menuContainer =
document.querySelector(".comfy-menu") ||
document.querySelector("#comfy-menu") ||
document.querySelector(".menu");
if (!menuContainer) {
console.warn(
"[Queue Manager] Could not find ComfyUI menu container, trying alternative approach",
);
this.addMenuItemAlternative();
return;
}
// Create menu item
const menuItem = document.createElement("button");
menuItem.className = "comfy-menu-btns";
menuItem.textContent = "Queue Manager";
menuItem.title = "Open Queue Manager";
menuItem.style.cssText = `
background: #333;
color: #fff;
border: 1px solid #555;
padding: 4px 8px;
margin: 2px;
cursor: pointer;
border-radius: 3px;
font-size: 12px;
`;
// Add click handler
menuItem.addEventListener("click", () => {
this.openQueueManager();
});
// Add hover effects
menuItem.addEventListener("mouseenter", () => {
menuItem.style.background = "#555";
});
menuItem.addEventListener("mouseleave", () => {
menuItem.style.background = "#333";
});
// Insert menu item
menuContainer.appendChild(menuItem);
this.menuItem = menuItem;
console.log("[Queue Manager] Menu item added successfully");
} catch (error) {
console.error("[Queue Manager] Failed to add menu item:", error);
this.addMenuItemAlternative();
}
}
/**
* Alternative method to add menu item if standard approach fails
*/
addMenuItemAlternative() {
try {
// Create a floating button as fallback
const floatingButton = document.createElement("div");
floatingButton.innerHTML = `
<button id="queue-manager-floating-btn" style="
position: fixed;
top: 10px;
right: 10px;
z-index: 10000;
background: #4CAF50;
color: white;
border: none;
padding: 10px 15px;
border-radius: 5px;
cursor: pointer;
font-size: 12px;
box-shadow: 0 2px 5px rgba(0,0,0,0.3);
transition: background 0.3s;
" title="Open Queue Manager">
📋 Queue
</button>
`;
document.body.appendChild(floatingButton);
const button = document.getElementById("queue-manager-floating-btn");
button.addEventListener("click", () => {
this.openQueueManager();
});
button.addEventListener("mouseenter", () => {
button.style.background = "#45a049";
});
button.addEventListener("mouseleave", () => {
button.style.background = "#4CAF50";
});
this.menuItem = button;
console.log("[Queue Manager] Floating menu button added as fallback");
} catch (error) {
console.error("[Queue Manager] Failed to add fallback menu item:", error);
}
}
/**
* Open the Queue Manager interface
*/
openQueueManager() {
try {
// Check if window is already open
if (queueManagerWindow && !queueManagerWindow.closed) {
queueManagerWindow.focus();
return;
}
// Determine the best way to open the interface
if (this.canUsePopupWindow()) {
this.openAsPopupWindow();
} else {
this.openAsTab();
}
} catch (error) {
console.error("[Queue Manager] Failed to open queue manager:", error);
this.showError("Failed to open Queue Manager");
}
}
/**
* Check if popup windows are allowed
*/
canUsePopupWindow() {
try {
// Test if we can open popup windows
const testWindow = window.open("", "_blank", "width=1,height=1");
if (testWindow) {
testWindow.close();
return true;
}
return false;
} catch (error) {
return false;
}
}
/**
* Open Queue Manager as a popup window
*/
openAsPopupWindow() {
const windowFeatures = [
"width=1200",
"height=800",
"left=100",
"top=100",
"resizable=yes",
"scrollbars=yes",
"status=no",
"menubar=no",
"toolbar=no",
"location=no",
].join(",");
// Get the queue manager URL
const queueManagerUrl = this.getQueueManagerUrl();
queueManagerWindow = window.open(
queueManagerUrl,
"QueueManager",
windowFeatures,
);
if (queueManagerWindow) {
queueManagerWindow.focus();
// Handle window close
queueManagerWindow.addEventListener("beforeunload", () => {
queueManagerWindow = null;
});
console.log("[Queue Manager] Opened as popup window");
} else {
console.warn("[Queue Manager] Popup blocked, falling back to tab");
this.openAsTab();
}
}
/**
* Open Queue Manager as a new tab
*/
openAsTab() {
const queueManagerUrl = this.getQueueManagerUrl();
queueManagerTab = window.open(queueManagerUrl, "_blank");
if (queueManagerTab) {
queueManagerTab.focus();
console.log("[Queue Manager] Opened as new tab");
} else {
console.error("[Queue Manager] Failed to open tab");
this.openAsEmbedded();
}
}
/**
* Open Queue Manager as embedded iframe (fallback)
*/
openAsEmbedded() {
try {
// Create modal overlay
const overlay = document.createElement("div");
overlay.id = "queue-manager-overlay";
overlay.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
z-index: 10000;
display: flex;
justify-content: center;
align-items: center;
`;
// Create iframe container
const container = document.createElement("div");
container.style.cssText = `
width: 90%;
height: 90%;
background: white;
border-radius: 8px;
position: relative;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
`;
// Create close button
const closeButton = document.createElement("button");
closeButton.innerHTML = "×";
closeButton.style.cssText = `
position: absolute;
top: 10px;
right: 15px;
background: none;
border: none;
font-size: 24px;
cursor: pointer;
z-index: 10001;
color: #666;
`;
closeButton.addEventListener("click", () => {
document.body.removeChild(overlay);
});
// Create iframe
const iframe = document.createElement("iframe");
iframe.src = this.getQueueManagerUrl();
iframe.style.cssText = `
width: 100%;
height: 100%;
border: none;
border-radius: 8px;
`;
// Assemble components
container.appendChild(closeButton);
container.appendChild(iframe);
overlay.appendChild(container);
document.body.appendChild(overlay);
// Close on overlay click
overlay.addEventListener("click", (e) => {
if (e.target === overlay) {
document.body.removeChild(overlay);
}
});
console.log("[Queue Manager] Opened as embedded iframe");
} catch (error) {
console.error(
"[Queue Manager] Failed to open embedded interface:",
error,
);
this.showError("Failed to open Queue Manager interface");
}
}
/**
* Get the Queue Manager URL
*/
getQueueManagerUrl() {
// Use the web directory served by ComfyUI
const baseUrl = window.location.origin;
return `${baseUrl}/extensions/comfyui-queue-manager/index.html`;
}
/**
* Show error message
*/
showError(message) {
// Create simple error notification
const notification = document.createElement("div");
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: #f44336;
color: white;
padding: 12px 20px;
border-radius: 4px;
z-index: 10000;
font-size: 14px;
box-shadow: 0 2px 5px rgba(0,0,0,0.3);
`;
notification.textContent = message;
document.body.appendChild(notification);
// Auto-remove after 5 seconds
setTimeout(() => {
if (document.body.contains(notification)) {
document.body.removeChild(notification);
}
}, 5000);
}
/**
* Clean up resources
*/
cleanup() {
if (queueManagerWindow && !queueManagerWindow.closed) {
queueManagerWindow.close();
}
if (this.menuItem && this.menuItem.parentNode) {
this.menuItem.parentNode.removeChild(this.menuItem);
}
}
}
// Initialize the menu extension
const queueManagerMenuExtension = new QueueManagerMenuExtension();
// Auto-initialize when DOM is ready
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", () => {
queueManagerMenuExtension.init();
});
} else {
queueManagerMenuExtension.init();
}
// Export for testing and external access
window.QueueManagerMenuExtension = queueManagerMenuExtension;
export default queueManagerMenuExtension;