fix: stabilize mobile panel viewport overlay

This commit is contained in:
Youzini-afk
2026-03-28 00:09:18 +08:00
parent 14763f0711
commit a75ff11984
2 changed files with 82 additions and 11 deletions

View File

@@ -140,6 +140,7 @@ let currentTaskProfileRuleId = "";
let fetchedMemoryLLMModels = [];
let fetchedBackendEmbeddingModels = [];
let fetchedDirectEmbeddingModels = [];
let viewportSyncBound = false;
// 由 index.js 注入的引用
let _getGraph = null;
@@ -165,6 +166,71 @@ async function loadLocalTemplate(templateName) {
return html;
}
function mountPanelHtml(html) {
const markup = String(html || "").trim();
if (!markup) {
throw new Error("Panel template markup is empty");
}
if (document.body?.insertAdjacentHTML) {
document.body.insertAdjacentHTML("beforebegin", markup);
return;
}
const template = document.createElement("template");
template.innerHTML = markup;
const fragment = template.content.cloneNode(true);
document.documentElement?.appendChild(fragment);
}
function ensureOverlayMountedAtRoot() {
if (!overlayEl) return;
const root = document.documentElement;
const body = document.body;
if (!root) return;
if (overlayEl.parentElement === root && overlayEl.nextElementSibling === body) {
return;
}
if (body?.parentElement === root) {
root.insertBefore(overlayEl, body);
return;
}
root.appendChild(overlayEl);
}
function syncViewportCssVars() {
const rootStyle = document.documentElement?.style;
if (!rootStyle) return;
const viewport = window.visualViewport;
const width = Math.max(
1,
Math.round(viewport?.width || window.innerWidth || 0),
);
const height = Math.max(
1,
Math.round(viewport?.height || window.innerHeight || 0),
);
rootStyle.setProperty("--bme-viewport-width", `${width}px`);
rootStyle.setProperty("--bme-viewport-height", `${height}px`);
}
function bindViewportSync() {
if (viewportSyncBound) return;
viewportSyncBound = true;
const update = () => syncViewportCssVars();
window.addEventListener("resize", update);
window.addEventListener("orientationchange", update);
window.visualViewport?.addEventListener("resize", update);
window.visualViewport?.addEventListener("scroll", update);
}
/**
* 初始化面板(由 index.js 调用一次)
*/
@@ -200,7 +266,7 @@ export async function initPanel({
if (!overlayEl || !panelEl) {
const html = await loadLocalTemplate("panel");
$("body").append(html);
mountPanelHtml(html);
overlayEl = document.getElementById("st-bme-panel-overlay");
panelEl = document.getElementById("st-bme-panel");
if (!overlayEl || !panelEl) {
@@ -210,6 +276,10 @@ export async function initPanel({
}
}
ensureOverlayMountedAtRoot();
bindViewportSync();
syncViewportCssVars();
_bindTabs();
_bindClose();
_bindResizeHandle();
@@ -410,6 +480,8 @@ export function updateFloatingBallStatus(status = "idle", tooltipText = "") {
*/
export function openPanel() {
if (!overlayEl) return;
ensureOverlayMountedAtRoot();
syncViewportCssVars();
overlayEl.classList.add("active");
_restorePanelSize();
@@ -973,6 +1045,11 @@ function _bindPanelResize() {
function _restorePanelSize() {
if (!panelEl) return;
if (_isMobile()) {
panelEl.style.width = "";
panelEl.style.height = "";
return;
}
try {
const raw = localStorage.getItem(PANEL_SIZE_KEY);
if (!raw) return;