Restart ComfyUI automatically after plugin updates

This commit is contained in:
Jony
2026-09-24 22:27:38 +08:00
parent 96010c058f
commit 10a8700589
7 changed files with 269 additions and 209 deletions
+20 -78
View File
@@ -1,13 +1,11 @@
import { app } from "../../../scripts/app.js";
import { api } from "../../../scripts/api.js";
import { startComfyUIRestart } from "./o1keyRestart.js";
const BUTTON_ID = "o1key-update-button";
const DETECT_BUTTON_ID = "o1key-detect-button";
const DETECT_NOTICE_ID = "o1key-detect-notice";
const DIALOG_ID = "o1key-update-dialog";
const STYLE_ID = "o1key-update-styles";
let mountObserver = null;
let detectNoticeTimer = null;
const UPDATE_ERRORS = {
local_changes: ["当前安装包含自定义修改,暂时无法自动更新。", "请联系技术支持处理,以免丢失现有内容。"],
@@ -207,26 +205,6 @@ function ensureStyles() {
}
#${DIALOG_ID} button:disabled { cursor: default; opacity: .55; }
#${DIALOG_ID} button:disabled:hover { transform: none; }
#${DETECT_NOTICE_ID} {
position: fixed;
right: 20px;
bottom: 20px;
z-index: 100000;
display: flex;
align-items: center;
gap: 10px;
padding: 12px 16px;
border: 1px solid rgba(96, 165, 250, .45);
border-radius: 9px;
color: var(--p-primary-color, #60a5fa);
background: var(--comfy-menu-bg, #202020);
box-shadow: 0 12px 32px rgba(0, 0, 0, .32);
font-family: inherit;
font-size: 13px;
font-weight: 600;
line-height: 1.4;
}
#${DETECT_NOTICE_ID}[hidden] { display: none; }
@media (max-width: 420px) {
#${DIALOG_ID} .o1key-update-header { padding: 18px; }
#${DIALOG_ID} .o1key-update-body { padding: 18px; }
@@ -328,15 +306,17 @@ function createUpdateDialog() {
function setState(state) {
dialog.dataset.state = state;
const busy = state === "checking" || state === "updating";
const busy = state === "checking" || state === "updating" || state === "restarting";
primary.disabled = busy;
close.disabled = state === "updating";
secondary.disabled = state === "updating";
close.disabled = state === "updating" || state === "restarting";
secondary.disabled = state === "updating" || state === "restarting";
primary.textContent = {
checking: "检查中…",
available: "立即更新",
updating: "更新中…",
restarting: "重启中…",
success: "完成",
restart_failed: "关闭",
}[state] || "重新检查";
secondary.textContent = state === "available" ? "稍后再说" : "关闭";
}
@@ -414,14 +394,19 @@ function createUpdateDialog() {
return;
}
if (result.updated) {
if (!result.requirements_changed) {
setState("restarting");
show("更新完成,正在重启 ComfyUI…", "重启完成后页面会自动刷新,请稍候。", "busy");
try {
await startComfyUIRestart();
} catch {
setState("restart_failed");
show("更新完成,但自动重启失败。", "请点击左侧“重启”按钮;如果问题持续,请联系技术支持。", "error");
}
return;
}
setState("success");
show(
"更新完成。",
result.requirements_changed
? "新版本还需要维护人员完成配置,请联系技术支持后重启 ComfyUI。"
: "请重启 ComfyUI,并刷新页面以使用新版本。",
"success",
);
show("更新完成。", "新版本还需要维护人员完成配置,请联系技术支持后重启 ComfyUI。", "success");
} else {
setState("current");
show("已是最新版本。", "无需更新。", "success");
@@ -433,11 +418,11 @@ function createUpdateDialog() {
}
primary.addEventListener("click", () => {
if (dialog.dataset.state === "available") return startUpdate();
if (dialog.dataset.state === "success") return dialog.close();
if (dialog.dataset.state === "success" || dialog.dataset.state === "restart_failed") return dialog.close();
return checkForUpdate();
});
dialog.addEventListener("cancel", (event) => {
if (dialog.dataset.state === "updating") event.preventDefault();
if (dialog.dataset.state === "updating" || dialog.dataset.state === "restarting") event.preventDefault();
});
dialog.checkForUpdate = checkForUpdate;
@@ -458,29 +443,6 @@ function openUpdateDialog() {
}
}
function showDetectNotice() {
ensureStyles();
let notice = document.querySelector(`#${DETECT_NOTICE_ID}`);
if (!notice) {
notice = document.createElement("div");
notice.id = DETECT_NOTICE_ID;
notice.setAttribute("role", "status");
const icon = document.createElement("span");
icon.className = "pi pi-check-circle";
icon.setAttribute("aria-hidden", "true");
const label = document.createElement("span");
label.textContent = "检测按钮已加载";
notice.append(icon, label);
document.body.appendChild(notice);
}
notice.hidden = false;
if (detectNoticeTimer !== null) window.clearTimeout(detectNoticeTimer);
detectNoticeTimer = window.setTimeout(() => {
notice.hidden = true;
detectNoticeTimer = null;
}, 3000);
}
function mountUpdateButton() {
const tokenButton = document.querySelector("#o1key-token-manager-button");
if (!tokenButton?.parentElement) return false;
@@ -506,26 +468,6 @@ function mountUpdateButton() {
if (tokenButton.nextElementSibling !== updateButton) tokenButton.after(updateButton);
let detectButton = document.querySelector(`#${DETECT_BUTTON_ID}`);
if (!detectButton) {
detectButton = tokenButton.cloneNode(true);
detectButton.id = DETECT_BUTTON_ID;
detectButton.type = "button";
detectButton.classList.remove("side-bar-button-selected", "o1key-token-manager-button", "o1key-restart-button");
detectButton.classList.add("o1key-detect-button");
detectButton.setAttribute("aria-label", "检测");
detectButton.setAttribute("title", "检测按钮");
detectButton.removeAttribute("aria-pressed");
const icon = detectButton.querySelector(".side-bar-button-icon");
if (icon) icon.className = "pi pi-check-circle side-bar-button-icon";
const label = detectButton.querySelector(".side-bar-button-label");
if (label) label.textContent = "检测";
detectButton.addEventListener("click", showDetectNotice);
}
if (updateButton.nextElementSibling !== detectButton) updateButton.after(detectButton);
return true;
}