From 82edd86feea59934c44362b72cdbae53e84eb448 Mon Sep 17 00:00:00 2001 From: Youzini-afk <13153778771cx@gmail.com> Date: Wed, 8 Apr 2026 02:17:49 +0800 Subject: [PATCH] Decouple panel bootstrap from host UI helpers --- ui/panel-bridge.js | 12 +++++++++--- ui/panel.js | 26 ++++++++++++++++++++------ 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/ui/panel-bridge.js b/ui/panel-bridge.js index f59b4fd..52bb7b9 100644 --- a/ui/panel-bridge.js +++ b/ui/panel-bridge.js @@ -37,9 +37,14 @@ function injectOptionsMenuEntry(runtime) { 记忆图谱 `).on("click", async () => { - await ensurePanelBridgeReady(runtime); - openPanelController(runtime); - runtime.$("#options").hide(); + try { + await ensurePanelBridgeReady(runtime); + openPanelController(runtime); + runtime.$("#options").hide(); + } catch (error) { + runtime.console.error("[ST-BME] 点击菜单打开面板失败:", error); + globalThis.toastr?.error?.("记忆图谱面板加载失败,请查看控制台报错", "ST-BME"); + } }); const $optionsContent = runtime.$("#options .options-content"); @@ -129,5 +134,6 @@ export async function initializePanelBridgeController(runtime) { "[ST-BME] 操控面板加载失败(核心功能不受影响):", panelError, ); + globalThis.toastr?.error?.("记忆图谱面板预加载失败,可稍后重试点击菜单", "ST-BME"); } } diff --git a/ui/panel.js b/ui/panel.js index e323895..cc63614 100644 --- a/ui/panel.js +++ b/ui/panel.js @@ -1,8 +1,6 @@ // ST-BME: 操控面板交互逻辑 -import { callGenericPopup, POPUP_TYPE } from "../../../../popup.js"; import { getContext } from "../../../../extensions.js"; -import { renderTemplateAsync } from "../../../../templates.js"; import { GraphRenderer } from "./graph-renderer.js"; import { getNodeDisplayName } from "../graph/node-labels.js"; import { @@ -221,6 +219,7 @@ let fetchedMemoryLLMModels = []; let fetchedBackendEmbeddingModels = []; let fetchedDirectEmbeddingModels = []; let viewportSyncBound = false; +let popupRuntimePromise = null; // 由 index.js 注入的引用 let _getGraph = null; @@ -238,15 +237,29 @@ let _updateSettings = null; let _actionHandlers = {}; async function loadLocalTemplate(templateName) { - const templatePath = new URL(`./${templateName}.html`, import.meta.url) - .pathname; - const html = await renderTemplateAsync(templatePath, {}, true, true, true); + const templateUrl = new URL(`./${templateName}.html`, import.meta.url); + const response = await fetch(templateUrl.href, { + cache: "no-store", + }); + if (!response.ok) { + throw new Error( + `Template request failed: ${templateUrl.pathname} (${response.status} ${response.statusText})`, + ); + } + const html = await response.text(); if (typeof html !== "string" || html.trim().length === 0) { - throw new Error(`Template render returned empty content: ${templatePath}`); + throw new Error(`Template returned empty content: ${templateUrl.pathname}`); } return html; } +async function getPopupRuntime() { + if (!popupRuntimePromise) { + popupRuntimePromise = import("../../../../popup.js"); + } + return await popupRuntimePromise; +} + function mountPanelHtml(html) { const markup = String(html || "").trim(); if (!markup) { @@ -4545,6 +4558,7 @@ async function _openRegexReuseInspector(taskType) { try { const snapshot = await _actionHandlers.inspectTaskRegexReuse(taskType); const content = _buildRegexReusePopupContent(snapshot || {}); + const { callGenericPopup, POPUP_TYPE } = await getPopupRuntime(); await callGenericPopup(content, POPUP_TYPE.TEXT, "", { okButton: "关闭", wide: true,