推进 INI 面板 control page controller helper

This commit is contained in:
2026-06-14 23:08:19 +08:00
parent 2844fd25c3
commit 59ffacb64e
7 changed files with 272 additions and 45 deletions

View File

@@ -0,0 +1,80 @@
export function createMachineSessionControlPageController({
panelFrame,
statusNode,
viewNode,
renderControlView,
pollMs = 200,
setIntervalFn = globalThis.setInterval,
} = {}) {
if (!panelFrame) {
throw new Error("A panel iframe is required.");
}
if (!statusNode) {
throw new Error("A control page status node is required.");
}
if (!viewNode) {
throw new Error("A control page view node is required.");
}
if (typeof renderControlView !== "function") {
throw new Error("A control view renderer is required.");
}
let refreshTimer = null;
function getPanelWindow() {
return panelFrame.contentWindow ?? null;
}
function getPanelApi() {
return getPanelWindow()?.linuxCncIniPanelApi ?? null;
}
function getControlView() {
return getPanelApi()?.getMachineSessionControlView?.() ?? null;
}
function render() {
const view = getControlView();
if (!view) {
statusNode.textContent = "waiting for panel";
viewNode.textContent = "";
return null;
}
statusNode.textContent = [
view.status.lastAction ?? "-",
view.status.runStatus ?? "-",
view.status.error ?? "-",
].join(" | ");
return renderControlView(viewNode, view);
}
function startPolling() {
if (!refreshTimer) {
refreshTimer = setIntervalFn(render, pollMs);
}
return refreshTimer;
}
function mount({ panelSrc = "./index.html" } = {}) {
panelFrame.addEventListener("load", () => {
render();
startPolling();
});
panelFrame.src = panelSrc;
render();
startPolling();
return controller;
}
const controller = {
getControlView,
getPanelApi,
getPanelWindow,
mount,
render,
startPolling,
};
return controller;
}

View File

@@ -1,58 +1,25 @@
import {
renderMachineSessionControlView,
} from "./control-view-renderer.js";
import {
createMachineSessionControlPageController,
} from "./control-page-controller.js";
const panelFrameNode = document.getElementById("panel-frame");
const statusNode = document.getElementById("control-page-status");
const viewNode = document.getElementById("control-page-view");
let refreshTimer = null;
function getPanelWindow() {
return panelFrameNode?.contentWindow ?? null;
}
function getPanelApi() {
return getPanelWindow()?.linuxCncIniPanelApi ?? null;
}
function getControlView() {
return getPanelApi()?.getMachineSessionControlView?.() ?? null;
}
function renderControlPage() {
const view = getControlView();
if (!view) {
statusNode.textContent = "waiting for panel";
viewNode.textContent = "";
return null;
}
statusNode.textContent = [
view.status.lastAction ?? "-",
view.status.runStatus ?? "-",
view.status.error ?? "-",
].join(" | ");
return renderMachineSessionControlView(viewNode, view);
}
function startPolling() {
if (!refreshTimer) {
refreshTimer = setInterval(renderControlPage, 200);
}
}
panelFrameNode.addEventListener("load", () => {
renderControlPage();
startPolling();
const controller = createMachineSessionControlPageController({
panelFrame: panelFrameNode,
statusNode,
viewNode,
renderControlView: renderMachineSessionControlView,
});
panelFrameNode.src = "./index.html";
renderControlPage();
startPolling();
controller.mount();
window.linuxCncIniPanelControlPageApi = {
getControlView,
getPanelApi,
renderControlPage,
getControlView: controller.getControlView,
getPanelApi: controller.getPanelApi,
renderControlPage: controller.render,
};