392 lines
9.2 KiB
JavaScript
392 lines
9.2 KiB
JavaScript
/**
|
|
* ComfyUI Queue Manager Extension
|
|
* Registers the Queue Manager with ComfyUI's extension system
|
|
*/
|
|
|
|
import { app } from "/scripts/app.js";
|
|
import { api } from "/scripts/api.js";
|
|
|
|
// Extension name
|
|
const EXTENSION_NAME = "QueueManager";
|
|
|
|
// Queue Manager state
|
|
let queueManagerState = {
|
|
window: null,
|
|
tab: null,
|
|
isOpen: false,
|
|
menuButton: null,
|
|
};
|
|
|
|
/**
|
|
* Queue Manager ComfyUI Extension
|
|
*/
|
|
app.registerExtension({
|
|
name: EXTENSION_NAME,
|
|
|
|
async init(app) {
|
|
console.log(`[${EXTENSION_NAME}] Initializing extension`);
|
|
|
|
// Initialize queue manager integration
|
|
this.initializeQueueManager();
|
|
},
|
|
|
|
async setup(app) {
|
|
console.log(`[${EXTENSION_NAME}] Setting up extension`);
|
|
|
|
// Add menu integration
|
|
this.addMenuIntegration();
|
|
|
|
// Set up keyboard shortcuts
|
|
this.setupKeyboardShortcuts();
|
|
},
|
|
|
|
async beforeRegisterNodeDef(nodeType, nodeData, app) {
|
|
// Hook into Queue Manager node registration
|
|
if (nodeData.name === "QueueManagerNode") {
|
|
console.log(`[${EXTENSION_NAME}] Queue Manager node detected`);
|
|
|
|
// Add custom functionality to the node if needed
|
|
const onNodeCreated = nodeType.prototype.onNodeCreated;
|
|
nodeType.prototype.onNodeCreated = function () {
|
|
if (onNodeCreated) {
|
|
onNodeCreated.apply(this, arguments);
|
|
}
|
|
|
|
// Add queue manager specific functionality
|
|
this.addWidget("button", "Open Queue Manager", null, () => {
|
|
openQueueManager();
|
|
});
|
|
};
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Initialize Queue Manager integration
|
|
*/
|
|
initializeQueueManager() {
|
|
// Check if Queue Manager API is available
|
|
this.checkQueueManagerAPI();
|
|
|
|
// Set up event listeners
|
|
this.setupEventListeners();
|
|
},
|
|
|
|
/**
|
|
* Add menu integration to ComfyUI
|
|
*/
|
|
addMenuIntegration() {
|
|
try {
|
|
// Wait for ComfyUI menu to be ready
|
|
const addMenuButton = () => {
|
|
const menuContainer = this.findMenuContainer();
|
|
if (menuContainer) {
|
|
this.createMenuButton(menuContainer);
|
|
} else {
|
|
// Retry after a short delay
|
|
setTimeout(addMenuButton, 500);
|
|
}
|
|
};
|
|
|
|
// Add menu button when DOM is ready
|
|
if (document.readyState === "loading") {
|
|
document.addEventListener("DOMContentLoaded", addMenuButton);
|
|
} else {
|
|
addMenuButton();
|
|
}
|
|
} catch (error) {
|
|
console.error(
|
|
`[${EXTENSION_NAME}] Failed to add menu integration:`,
|
|
error,
|
|
);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Find ComfyUI's menu container
|
|
*/
|
|
findMenuContainer() {
|
|
// Try multiple selectors to find the menu
|
|
const selectors = [
|
|
".comfy-menu",
|
|
"#comfy-menu",
|
|
".menu",
|
|
".comfy-menu-btns",
|
|
".comfyui-menu",
|
|
];
|
|
|
|
for (const selector of selectors) {
|
|
const container = document.querySelector(selector);
|
|
if (container) {
|
|
return container;
|
|
}
|
|
}
|
|
|
|
// Try to find by looking for existing menu buttons
|
|
const existingButtons = document.querySelectorAll("button");
|
|
for (const button of existingButtons) {
|
|
if (
|
|
button.textContent.includes("Queue") ||
|
|
button.textContent.includes("Settings") ||
|
|
button.className.includes("comfy")
|
|
) {
|
|
return button.parentElement;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
},
|
|
|
|
/**
|
|
* Create the Queue Manager menu button
|
|
*/
|
|
createMenuButton(container) {
|
|
if (queueManagerState.menuButton) {
|
|
return; // Already created
|
|
}
|
|
|
|
const button = document.createElement("button");
|
|
button.textContent = "📋 Queue Manager";
|
|
button.title = "Open Queue Manager";
|
|
button.className = "comfy-menu-btns queue-manager-btn";
|
|
|
|
// Style the button to match ComfyUI's theme
|
|
button.style.cssText = `
|
|
background: var(--comfy-menu-bg, #333);
|
|
color: var(--comfy-menu-text, #fff);
|
|
border: 1px solid var(--comfy-menu-border, #555);
|
|
padding: 4px 8px;
|
|
margin: 2px;
|
|
cursor: pointer;
|
|
border-radius: 3px;
|
|
font-size: 12px;
|
|
transition: background-color 0.2s;
|
|
`;
|
|
|
|
// Add hover effects
|
|
button.addEventListener("mouseenter", () => {
|
|
button.style.backgroundColor = "var(--comfy-menu-hover-bg, #555)";
|
|
});
|
|
|
|
button.addEventListener("mouseleave", () => {
|
|
button.style.backgroundColor = "var(--comfy-menu-bg, #333)";
|
|
});
|
|
|
|
// Add click handler
|
|
button.addEventListener("click", (e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
openQueueManager();
|
|
});
|
|
|
|
// Insert button into menu
|
|
container.appendChild(button);
|
|
queueManagerState.menuButton = button;
|
|
|
|
console.log(`[${EXTENSION_NAME}] Menu button added successfully`);
|
|
},
|
|
|
|
/**
|
|
* Set up keyboard shortcuts
|
|
*/
|
|
setupKeyboardShortcuts() {
|
|
document.addEventListener("keydown", (e) => {
|
|
// Ctrl+Shift+Q to open Queue Manager
|
|
if (e.ctrlKey && e.shiftKey && e.key === "Q") {
|
|
e.preventDefault();
|
|
openQueueManager();
|
|
}
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Set up event listeners
|
|
*/
|
|
setupEventListeners() {
|
|
// Listen for window close events
|
|
window.addEventListener("beforeunload", () => {
|
|
if (queueManagerState.window && !queueManagerState.window.closed) {
|
|
queueManagerState.window.close();
|
|
}
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Check if Queue Manager API is available
|
|
*/
|
|
async checkQueueManagerAPI() {
|
|
try {
|
|
const response = await fetch("/queue/status");
|
|
if (response.ok) {
|
|
console.log(`[${EXTENSION_NAME}] Queue Manager API is available`);
|
|
return true;
|
|
}
|
|
} catch (error) {
|
|
console.warn(
|
|
`[${EXTENSION_NAME}] Queue Manager API not available:`,
|
|
error,
|
|
);
|
|
}
|
|
return false;
|
|
},
|
|
});
|
|
|
|
/**
|
|
* Open the Queue Manager interface
|
|
*/
|
|
function openQueueManager() {
|
|
try {
|
|
// Check if already open
|
|
if (queueManagerState.window && !queueManagerState.window.closed) {
|
|
queueManagerState.window.focus();
|
|
return;
|
|
}
|
|
|
|
// Determine the best way to open
|
|
if (canOpenPopup()) {
|
|
openAsPopup();
|
|
} else {
|
|
openAsTab();
|
|
}
|
|
} catch (error) {
|
|
console.error(`[${EXTENSION_NAME}] Failed to open Queue Manager:`, error);
|
|
showNotification("Failed to open Queue Manager", "error");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if popup windows can be opened
|
|
*/
|
|
function canOpenPopup() {
|
|
try {
|
|
const test = window.open("", "_blank", "width=1,height=1");
|
|
if (test) {
|
|
test.close();
|
|
return true;
|
|
}
|
|
} catch (error) {
|
|
// Popup blocked
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Open Queue Manager as popup window
|
|
*/
|
|
function openAsPopup() {
|
|
const features = [
|
|
"width=1200",
|
|
"height=800",
|
|
"left=100",
|
|
"top=100",
|
|
"resizable=yes",
|
|
"scrollbars=yes",
|
|
"status=no",
|
|
"menubar=no",
|
|
"toolbar=no",
|
|
].join(",");
|
|
|
|
const url = getQueueManagerUrl();
|
|
queueManagerState.window = window.open(url, "QueueManager", features);
|
|
|
|
if (queueManagerState.window) {
|
|
queueManagerState.window.focus();
|
|
queueManagerState.isOpen = true;
|
|
|
|
// Handle window close
|
|
const checkClosed = setInterval(() => {
|
|
if (queueManagerState.window.closed) {
|
|
queueManagerState.isOpen = false;
|
|
queueManagerState.window = null;
|
|
clearInterval(checkClosed);
|
|
}
|
|
}, 1000);
|
|
|
|
console.log(`[${EXTENSION_NAME}] Opened as popup window`);
|
|
} else {
|
|
openAsTab();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Open Queue Manager as new tab
|
|
*/
|
|
function openAsTab() {
|
|
const url = getQueueManagerUrl();
|
|
queueManagerState.tab = window.open(url, "_blank");
|
|
|
|
if (queueManagerState.tab) {
|
|
queueManagerState.tab.focus();
|
|
queueManagerState.isOpen = true;
|
|
console.log(`[${EXTENSION_NAME}] Opened as new tab`);
|
|
} else {
|
|
showNotification(
|
|
"Failed to open Queue Manager. Please check popup blocker settings.",
|
|
"error",
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the Queue Manager URL
|
|
*/
|
|
function getQueueManagerUrl() {
|
|
const baseUrl = window.location.origin;
|
|
return `${baseUrl}/extensions/comfyui-queue-manager/index.html`;
|
|
}
|
|
|
|
/**
|
|
* Show notification to user
|
|
*/
|
|
function showNotification(message, type = "info") {
|
|
const notification = document.createElement("div");
|
|
notification.className = `queue-manager-notification ${type}`;
|
|
notification.textContent = message;
|
|
|
|
const colors = {
|
|
info: "#2196F3",
|
|
success: "#4CAF50",
|
|
warning: "#FF9800",
|
|
error: "#f44336",
|
|
};
|
|
|
|
notification.style.cssText = `
|
|
position: fixed;
|
|
top: 20px;
|
|
right: 20px;
|
|
background: ${colors[type] || colors.info};
|
|
color: white;
|
|
padding: 12px 20px;
|
|
border-radius: 4px;
|
|
z-index: 10000;
|
|
font-size: 14px;
|
|
box-shadow: 0 2px 10px rgba(0,0,0,0.3);
|
|
max-width: 300px;
|
|
word-wrap: break-word;
|
|
`;
|
|
|
|
document.body.appendChild(notification);
|
|
|
|
// Auto-remove after 5 seconds
|
|
setTimeout(() => {
|
|
if (document.body.contains(notification)) {
|
|
document.body.removeChild(notification);
|
|
}
|
|
}, 5000);
|
|
|
|
// Click to dismiss
|
|
notification.addEventListener("click", () => {
|
|
if (document.body.contains(notification)) {
|
|
document.body.removeChild(notification);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Export for external access
|
|
window.QueueManagerExtension = {
|
|
openQueueManager,
|
|
getState: () => queueManagerState,
|
|
showNotification,
|
|
};
|
|
|
|
console.log(`[${EXTENSION_NAME}] Extension loaded successfully`);
|