diff --git a/glob/manager_core.py b/glob/manager_core.py index 142a7378..3e4c0a09 100644 --- a/glob/manager_core.py +++ b/glob/manager_core.py @@ -23,7 +23,7 @@ sys.path.append(glob_path) import cm_global from manager_util import PIPFixer, StrictVersion -version = [2, 55, 5] +version = [2, 56] version_str = f"V{version[0]}.{version[1]}" + (f'.{version[2]}' if len(version) > 2 else '') diff --git a/js/cm-api.js b/js/cm-api.js index 95a13cfb..d607c112 100644 --- a/js/cm-api.js +++ b/js/cm-api.js @@ -1,6 +1,6 @@ import { api } from "../../scripts/api.js"; import { app } from "../../scripts/app.js"; -import { sleep } from "./common.js"; +import { sleep, customConfirm } from "./common.js"; async function tryInstallCustomNode(event) { let msg = '-= [ComfyUI Manager] extension installation request =-\n\n'; @@ -22,8 +22,7 @@ async function tryInstallCustomNode(event) { alert(msg); return; } - - let res = confirm(msg); + const res = await customConfirm(msg); if(res) { if(event.detail.target.installed == 'Disabled') { const response = await api.fetchApi(`/customnode/toggle_active`, { diff --git a/js/common.js b/js/common.js index 8847606f..cad23087 100644 --- a/js/common.js +++ b/js/common.js @@ -2,6 +2,98 @@ import { app } from "../../scripts/app.js"; import { api } from "../../scripts/api.js"; import { $el, ComfyDialog } from "../../scripts/ui.js"; + +export function customConfirm(message, confirmMessage, cancelMessage) { + return new Promise((resolve) => { + // transparent bg + const modalOverlay = document.createElement('div'); + modalOverlay.style.position = 'fixed'; + modalOverlay.style.top = 0; + modalOverlay.style.left = 0; + modalOverlay.style.width = '100%'; + modalOverlay.style.height = '100%'; + modalOverlay.style.backgroundColor = 'rgba(0, 0, 0, 0.8)'; + modalOverlay.style.display = 'flex'; + modalOverlay.style.alignItems = 'center'; + modalOverlay.style.justifyContent = 'center'; + modalOverlay.style.zIndex = '1000000'; + + // Modal window container (dark bg) + const modalDialog = document.createElement('div'); + modalDialog.style.backgroundColor = '#333'; + modalDialog.style.padding = '20px'; + modalDialog.style.borderRadius = '4px'; + modalDialog.style.maxWidth = '400px'; + modalDialog.style.width = '80%'; + modalDialog.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.5)'; + modalDialog.style.color = '#fff'; + + // Display message + const modalMessage = document.createElement('p'); + modalMessage.textContent = message; + modalMessage.style.margin = '0'; + modalMessage.style.padding = '0 0 20px'; + modalMessage.style.wordBreak = 'keep-all'; + + // Button container + const modalButtons = document.createElement('div'); + modalButtons.style.display = 'flex'; + modalButtons.style.justifyContent = 'flex-end'; + + // Confirm button (green) + const confirmButton = document.createElement('button'); + if(confirmMessage) + confirmButton.textContent = confirmMessage; + else + confirmButton.textContent = 'Confirm'; + confirmButton.style.marginLeft = '10px'; + confirmButton.style.backgroundColor = '#28a745'; // green + confirmButton.style.color = '#fff'; + confirmButton.style.border = 'none'; + confirmButton.style.padding = '6px 12px'; + confirmButton.style.borderRadius = '4px'; + confirmButton.style.cursor = 'pointer'; + confirmButton.style.fontWeight = 'bold'; + + // Cancel button (red) + const cancelButton = document.createElement('button'); + if(cancelMessage) + cancelButton.textContent = cancelMessage; + else + cancelButton.textContent = 'Cancel'; + + cancelButton.style.marginLeft = '10px'; + cancelButton.style.backgroundColor = '#dc3545'; // red + cancelButton.style.color = '#fff'; + cancelButton.style.border = 'none'; + cancelButton.style.padding = '6px 12px'; + cancelButton.style.borderRadius = '4px'; + cancelButton.style.cursor = 'pointer'; + cancelButton.style.fontWeight = 'bold'; + + const closeModal = () => { + document.body.removeChild(modalOverlay); + }; + + confirmButton.addEventListener('click', () => { + closeModal(); + resolve(true); + }); + + cancelButton.addEventListener('click', () => { + closeModal(); + resolve(false); + }); + + modalButtons.appendChild(confirmButton); + modalButtons.appendChild(cancelButton); + modalDialog.appendChild(modalMessage); + modalDialog.appendChild(modalButtons); + modalOverlay.appendChild(modalDialog); + document.body.appendChild(modalOverlay); + }); +} + export function show_message(msg) { app.ui.dialog.show(msg); app.ui.dialog.element.style.zIndex = 10010; @@ -13,19 +105,19 @@ export async function sleep(ms) { export function rebootAPI() { if ('electronAPI' in window) { - window.electronAPI.restartApp(); - return true; - } - if (confirm("Are you sure you'd like to reboot the server?")) { - try { - api.fetchApi("/manager/reboot"); - } - catch(exception) { - - } - return true; + window.electronAPI.restartApp(); + return true; } + customConfirm("Are you sure you'd like to reboot the server?").then((isConfirmed) => { + if (isConfirmed) { + try { + api.fetchApi("/manager/reboot"); + } + catch(exception) {} + } + }); + return false; } diff --git a/js/components-manager.js b/js/components-manager.js index b2ccf43b..9ac8351b 100644 --- a/js/components-manager.js +++ b/js/components-manager.js @@ -1,6 +1,6 @@ import { app } from "../../scripts/app.js"; import { api } from "../../scripts/api.js" -import { sleep, show_message } from "./common.js"; +import { sleep, show_message, customConfirm } from "./common.js"; import { GroupNodeConfig, GroupNodeHandler } from "../../extensions/core/groupNode.js"; import { ComfyDialog, $el } from "../../scripts/ui.js"; @@ -365,7 +365,7 @@ function checkVersion(name, component) { return msg; } -function handle_import_components(components) { +async function handle_import_components(components) { let msg = 'Components:\n'; let cnt = 0; for(let name in components) { @@ -387,8 +387,9 @@ function handle_import_components(components) { let last_name = null; msg += '\nWill you load components?\n'; - if(confirm(msg)) { - let mode = confirm('\nWill you save components?\n(cancel=load without save)'); + const confirmed = await customConfirm(msg); + if(confirmed) { + const mode = await customConfirm('\nWill you save components?\n(cancel=load without save)'); for(let name in components) { let component = components[name]; @@ -411,7 +412,7 @@ function handle_import_components(components) { } } -function handlePaste(e) { +async function handlePaste(e) { let data = (e.clipboardData || window.clipboardData); const items = data.items; for(const item of items) { @@ -421,7 +422,7 @@ function handlePaste(e) { let json_data = JSON.parse(data); if(json_data.kind == 'ComfyUI Components' && last_paste_timestamp != json_data.timestamp) { last_paste_timestamp = json_data.timestamp; - handle_import_components(json_data.components); + await handle_import_components(json_data.components); // disable paste node localStorage.removeItem("litegrapheditor_clipboard", null); @@ -677,7 +678,7 @@ export class ComponentBuilderDialog extends ComfyDialog { let orig_handleFile = app.handleFile; -function handleFile(file) { +async function handleFile(file) { if (file.name?.endsWith(".json") || file.name?.endsWith(".pack")) { const reader = new FileReader(); reader.onload = async () => { @@ -690,7 +691,7 @@ function handleFile(file) { } if(is_component) { - handle_import_components(jsonContent); + await handle_import_components(jsonContent); } else { orig_handleFile.call(app, file); diff --git a/js/custom-nodes-manager.js b/js/custom-nodes-manager.js index 5c314985..289b9a50 100644 --- a/js/custom-nodes-manager.js +++ b/js/custom-nodes-manager.js @@ -2,7 +2,7 @@ import { app } from "../../scripts/app.js"; import { $el } from "../../scripts/ui.js"; import { manager_instance, rebootAPI, install_via_git_url, - fetchData, md5, icons + fetchData, md5, icons, customConfirm } from "./common.js"; // https://cenfun.github.io/turbogrid/api.html @@ -919,7 +919,9 @@ export class CustomNodesManager { if(mode === "uninstall") { title = title || `${list.length} custom nodes`; - if (!confirm(`Are you sure uninstall ${title}?`)) { + + const confirmed = await customConfirm(`Are you sure uninstall ${title}?`); + if (!confirmed) { return; } } diff --git a/pyproject.toml b/pyproject.toml index 7c646e8f..9ba35de6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui-manager" description = "ComfyUI-Manager provides features to install and manage custom nodes for ComfyUI, as well as various functionalities to assist with ComfyUI." -version = "2.55.5" +version = "2.56" license = { file = "LICENSE.txt" } dependencies = ["GitPython", "PyGithub", "matrix-client==0.4.0", "transformers", "huggingface-hub>0.20", "typer", "rich", "typing-extensions"]