feat(web-console): rebuild intelligent cockpit sync interface

This commit is contained in:
vee
2026-08-18 13:24:36 +08:00
parent 344f662970
commit 9b24d5c8c9
30 changed files with 4100 additions and 12594 deletions
-104
View File
@@ -557,7 +557,6 @@ async function loadGestureRuntime() {
state.runtime = await response.json();
state.engine = new GestureEngine(state.runtime.safety, executeGestureAction);
renderMappingGrid();
renderGestureDebugOptions();
if (!state.runtime.model_available) throw new Error("内置手势模型不可用,请检查工程资源");
}
@@ -658,99 +657,6 @@ function renderMappingGrid() {
select.innerHTML = Object.entries(ACTIONS).map(([value, item]) => `<option value="${value}">${item.label}</option>`).join("");
}
function renderGestureDebugOptions() {
const select = $("#gestureDebugSelect");
if (!select || !state.runtime) return;
const tokens = [...new Set([
"OPEN_PALM",
"CLOSED_FIST",
...Object.keys(state.runtime.actions || {}),
])];
select.innerHTML = tokens.map((token) => {
const action = mappingForToken(token);
const actionLabel = action ? ACTIONS[action]?.label || action : token === "OPEN_PALM" ? "激活控制" : "停止当前动作";
return `<option value="${token}">${TOKEN_NAMES[token] || token} → ${actionLabel}</option>`;
}).join("");
}
function setGestureDebugOpen(open) {
const panel = $("#gestureDebugPanel");
const button = $("#gestureArmButton");
if (!panel || !button) return;
const allowed = document.body.dataset.demoRole === "admin";
const nextOpen = allowed && open;
panel.hidden = !nextOpen;
button.classList.toggle("active", nextOpen);
button.setAttribute("aria-expanded", String(nextOpen));
}
function toggleGestureDebug() {
const panel = $("#gestureDebugPanel");
setGestureDebugOpen(panel?.hidden ?? true);
}
function syncGestureDebugRole(role = document.body.dataset.demoRole) {
const button = $("#gestureArmButton");
if (!button) return;
const isAdmin = role === "admin";
if (!isAdmin) setGestureDebugOpen(false);
button.disabled = !isAdmin;
button.classList.toggle("v2-decorative-control", !isAdmin);
if (isAdmin) {
button.removeAttribute("aria-hidden");
button.removeAttribute("tabindex");
button.setAttribute("aria-controls", "gestureDebugPanel");
button.setAttribute("aria-expanded", String(!$("#gestureDebugPanel")?.hidden));
button.setAttribute("aria-label", "手势调试");
button.setAttribute("title", "手势调试");
} else {
button.setAttribute("aria-hidden", "true");
button.setAttribute("tabindex", "-1");
button.removeAttribute("aria-controls");
button.removeAttribute("aria-expanded");
button.removeAttribute("aria-label");
button.removeAttribute("title");
}
}
function sendSimulatedGesture() {
if (document.body.dataset.demoRole !== "admin") {
setGestureDebugOpen(false);
notify("仅管理员可发送模拟手势");
return;
}
const token = $("#gestureDebugSelect")?.value;
if (!token || !state.engine) {
notify("手势调试能力尚未就绪");
return;
}
const tokenName = TOKEN_NAMES[token] || token;
$("#gestureDetected").textContent = `模拟 · ${tokenName}`;
if (token === "OPEN_PALM") {
state.engine.setArmed(true);
$("#gestureExpected").textContent = "激活控制";
notify("已发送模拟张掌手势");
return;
}
if (token === "CLOSED_FIST") {
state.engine.stopMotion("管理员模拟握拳 · 已停止当前动作");
$("#gestureExpected").textContent = "停止当前动作";
notify("已发送模拟握拳手势");
return;
}
const action = mappingForToken(token);
if (!action || !ACTIONS[action]) {
$("#gestureExpected").textContent = "未绑定动作";
notify("该模拟手势尚未绑定动作");
return;
}
state.lastRecognizedToken = token;
$("#gestureExpected").textContent = ACTIONS[action].label;
$("#gestureSafetyText").textContent = `管理员模拟手势:${tokenName}`;
executeGestureAction(action);
notify(`已发送模拟手势:${tokenName}`);
}
function updateCustomizeToken() {
const token = state.lastRecognizedToken;
$("#gestureCustomizeToken").textContent = token ? TOKEN_NAMES[token] || token : "请先摆出手势";
@@ -811,27 +717,17 @@ document.addEventListener("DOMContentLoaded", async () => {
$("#gestureCloseButton")?.addEventListener("click", closeDrawer);
$("#gestureBackdrop")?.addEventListener("click", closeDrawer);
$("#gestureStartButton")?.addEventListener("click", toggleCamera);
$("#gestureArmButton")?.addEventListener("click", toggleGestureDebug);
$("#gestureStopButton")?.addEventListener("click", () => state.engine?.setArmed(false));
$("#gestureDebugSend")?.addEventListener("click", sendSimulatedGesture);
$("#gestureCustomizeButton")?.addEventListener("click", toggleCustomize);
$("#gestureBindButton")?.addEventListener("click", bindCurrentGesture);
$("#gestureResetMapping")?.addEventListener("click", resetMapping);
document.addEventListener("keydown", (event) => {
if (event.key !== "Escape") return;
if (!$("#gestureDebugPanel")?.hidden) {
setGestureDebugOpen(false);
return;
}
if ($("#gestureDrawer")?.classList.contains("open")) closeDrawer();
});
window.addEventListener("cognitive-agent:demo-role-change", (event) => {
syncGestureDebugRole(event.detail?.role);
});
document.addEventListener("visibilitychange", () => { if (document.hidden && state.stream) stopCamera(); });
window.addEventListener("beforeunload", stopCamera);
navigator.mediaDevices?.addEventListener?.("devicechange", handleCameraDeviceChange);
syncGestureDebugRole();
let runtimeError = null;
try {
await loadGestureRuntime();