Files
comfyui_o1key/web/js/hideSidebar.js
T

222 lines
11 KiB
JavaScript

import { app } from "../../../scripts/app.js";
app.registerExtension({
name: "o1key.hideSidebarItems",
async setup() {
const hide = () => {
// 隐藏侧边栏的"说明"、"应用"、"模型"、"节点"、"模板"按钮
const hiddenLabels = ["说明", "帮助", "help", "应用", "apps", "模型", "models", "节点", "nodes", "模板", "templates", "template"];
document.querySelectorAll(".side-bar-button, [class*='sidebar'] button, .p-togglebutton").forEach(btn => {
const label = [
btn.getAttribute("aria-label"),
btn.getAttribute("title"),
btn.getAttribute("data-title"),
btn.getAttribute("data-label"),
btn.textContent,
].filter(Boolean).join(" ").toLowerCase();
if (hiddenLabels.some(k => label.includes(k))) {
btn.style.display = "none";
}
});
// 隐藏左上角下拉菜单中的"帮助"项
document.querySelectorAll(".p-menuitem, .p-menu-item, [class*='menu'] li, [class*='Menu'] li").forEach(item => {
const text = item.textContent || "";
if (text.trim() === "帮助" || text.trim() === "Help") {
item.style.display = "none";
}
});
// 隐藏登录/注册弹框(Google/Github 登录对话框)
document.querySelectorAll("[class*='dialog'], [class*='Dialog'], [class*='modal'], [class*='Modal']").forEach(dialog => {
const text = dialog.textContent || "";
if ((text.includes("Google") || text.includes("Github")) &&
(text.includes("登录") || text.includes("注册"))) {
dialog.style.display = "none";
const mask = dialog.previousElementSibling;
if (mask && mask.className && mask.className.includes("mask")) {
mask.style.display = "none";
}
}
});
// 在右侧内容区隐藏"登录/注册"按钮并注入 API Key
injectApiKeyPanel();
};
async function injectApiKeyPanel() {
// 找到右侧内容区中包含"我的用户设置"的区域
let contentArea = null;
document.querySelectorAll("h1, h2, h3, h4, span, div").forEach(el => {
const t = (el.textContent || "").trim();
if (t === "我的用户设置" || t === "My User Settings") {
contentArea = el.closest("div");
}
});
if (!contentArea) return;
// 隐藏"登录/注册"按钮和"登录您的账户"文字
contentArea.querySelectorAll("button, a, span, p, div").forEach(el => {
const t = (el.textContent || "").trim();
if (t.includes("登录") || t.includes("注册") || t === "Sign In" || t === "Sign Up" || t.includes("登录您的账户") || t.includes("Log in")) {
if (el.tagName === "BUTTON" || el.tagName === "A" || t.includes("登录您的账户")) {
el.style.display = "none";
}
}
});
// 检查是否已注入(DOM 中已存在则跳过)
if (document.querySelector("#o1key-apikey-box")) return;
// 创建 API Key 输入区域
const box = document.createElement("div");
box.id = "o1key-apikey-box";
box.style.cssText = "margin-top:24px;padding:20px;border:1px solid #444;border-radius:8px;background:#1e1e1e;";
box.innerHTML = `
<div style="font-weight:bold;font-size:15px;margin-bottom:6px;color:#eee;">O1Key API 密钥</div>
<div style="font-size:12px;color:#999;margin-bottom:14px;">输入您的 API 密钥,测试通过后方可保存</div>
<div style="display:flex;gap:8px;align-items:center;">
<input id="o1key-apikey-input" type="text" placeholder="请输入 API 密钥"
autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
data-form-type="other" data-lpignore="true" name="o1key-key-field"
style="flex:1;padding:8px 12px;border:1px solid #555;border-radius:4px;background:#111;color:#eee;font-size:13px;" />
<button id="o1key-apikey-test"
style="padding:8px 14px;border:none;border-radius:4px;background:#47a;color:#fff;cursor:pointer;font-size:13px;white-space:nowrap;">测试令牌</button>
<button id="o1key-apikey-save" disabled
style="padding:8px 14px;border:none;border-radius:4px;background:#555;color:#999;cursor:not-allowed;font-size:13px;white-space:nowrap;">保存</button>
<button id="o1key-apikey-clear"
style="padding:8px 14px;border:none;border-radius:4px;background:#a44;color:#fff;cursor:pointer;font-size:13px;white-space:nowrap;">清空密钥</button>
</div>
<div id="o1key-apikey-status" style="margin-top:10px;font-size:12px;color:#999;"></div>
`;
contentArea.appendChild(box);
// 加载当前状态
try {
const resp = await fetch("/o1key/api_key");
const data = await resp.json();
const status = box.querySelector("#o1key-apikey-status");
if (data.has_key) {
status.textContent = "当前密钥: " + data.masked;
status.style.color = "#3b8";
} else {
status.textContent = "尚未配置 API 密钥";
status.style.color = "#a84";
}
} catch (e) {}
const saveBtn = box.querySelector("#o1key-apikey-save");
const testBtn = box.querySelector("#o1key-apikey-test");
let testPassed = false;
// 输入变化时重置测试状态
box.querySelector("#o1key-apikey-input").addEventListener("input", () => {
testPassed = false;
saveBtn.disabled = true;
saveBtn.style.background = "#555";
saveBtn.style.color = "#999";
saveBtn.style.cursor = "not-allowed";
});
// 测试令牌按钮
testBtn.addEventListener("click", async () => {
const input = box.querySelector("#o1key-apikey-input");
const status = box.querySelector("#o1key-apikey-status");
const key = input.value.trim();
if (!key) { status.textContent = "请输入密钥"; status.style.color = "#a44"; return; }
testBtn.disabled = true;
testBtn.textContent = "验证中...";
status.textContent = "正在验证密钥...";
status.style.color = "#999";
try {
const resp = await fetch("/o1key/test_key", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({api_key: key})
});
const data = await resp.json();
if (data.valid) {
testPassed = true;
status.textContent = "验证通过,可以保存";
status.style.color = "#3b8";
saveBtn.disabled = false;
saveBtn.style.background = "#3b8";
saveBtn.style.color = "#fff";
saveBtn.style.cursor = "pointer";
} else {
testPassed = false;
status.textContent = data.error || "验证失败";
status.style.color = "#a44";
}
} catch (e) {
status.textContent = "网络错误";
status.style.color = "#a44";
}
testBtn.disabled = false;
testBtn.textContent = "测试令牌";
});
// 保存按钮(仅测试通过后可用)
saveBtn.addEventListener("click", async () => {
if (!testPassed) return;
const input = box.querySelector("#o1key-apikey-input");
const status = box.querySelector("#o1key-apikey-status");
const key = input.value.trim();
try {
const resp = await fetch("/o1key/api_key", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({api_key: key})
});
const data = await resp.json();
if (data.success) {
status.textContent = "密钥已保存";
status.style.color = "#3b8";
input.value = "";
testPassed = false;
saveBtn.disabled = true;
saveBtn.style.background = "#555";
saveBtn.style.color = "#999";
saveBtn.style.cursor = "not-allowed";
} else {
status.textContent = data.error || "保存失败";
status.style.color = "#a44";
}
} catch (e) {
status.textContent = "网络错误";
status.style.color = "#a44";
}
});
// 清空密钥按钮
const clearBtn = box.querySelector("#o1key-apikey-clear");
clearBtn.addEventListener("click", async () => {
if (!confirm("确定要清空 API 密钥吗?")) return;
const status = box.querySelector("#o1key-apikey-status");
try {
const resp = await fetch("/o1key/api_key", { method: "DELETE" });
const data = await resp.json();
if (data.success) {
status.textContent = "API 密钥已清空";
status.style.color = "#a84";
box.querySelector("#o1key-apikey-input").value = "";
testPassed = false;
saveBtn.disabled = true;
saveBtn.style.background = "#555";
saveBtn.style.color = "#999";
saveBtn.style.cursor = "not-allowed";
} else {
status.textContent = data.error || "清空失败";
status.style.color = "#a44";
}
} catch (e) {
status.textContent = "网络错误";
status.style.color = "#a44";
}
});
}
const observer = new MutationObserver(hide);
observer.observe(document.body, { childList: true, subtree: true });
setTimeout(hide, 1000);
setTimeout(hide, 3000);
},
});