Files
matrix-screen-controller/核桃派软件源代码/app/static/board-startup-model.js
T

59 lines
2.3 KiB
JavaScript

export const BOARD_SESSION_KEY = "matrix-board-session-v1";
function validContext(context) {
return context === null || (
context && ["template", "animation"].includes(context.type)
&& ["id", "name", "revision", "baseline"].every((key) => typeof context[key] === "string" && context[key])
&& typeof context.readOnly === "boolean"
&& (context.type !== "animation" || context.readOnly)
);
}
export function readBoardSession(storage, draft, bootId) {
const raw = storage?.getItem(BOARD_SESSION_KEY);
if (!raw) return { bootId: null, context: null };
try {
const value = JSON.parse(raw);
if (value.version !== 1 || typeof value.bootId !== "string" || !validContext(value.context)) {
throw new Error("invalid session");
}
return {
bootId: value.bootId,
context: value.bootId === bootId && value.draft === draft ? value.context : null,
};
} catch {
throw new Error("画板保存绑定损坏或来自未来版本;原值已保留,请另存当前内容后处理浏览器存储。");
}
}
export function writeBoardSession(storage, bootId, draft, context) {
storage.setItem(BOARD_SESSION_KEY, JSON.stringify({ version: 1, bootId, draft, context }));
}
// Resolve only editable static defaults and the read-only demo animation.
// Ordinary animations retain their existing explicit frame editing workflow.
export async function loadDefaultBoard(apiJson) {
const reference = await apiJson("/api/display/default-content");
if (reference.type === "template") {
return { ...await apiJson(`/api/templates/${reference.id}`), type: "template" };
}
if (reference.type !== "animation" || !reference.is_demo) return null;
const animation = await apiJson(`/api/animations/${reference.id}/frames`);
const first = animation.frames[0];
if (!first) throw new Error("默认演示动图没有帧");
const frame = await apiJson(`/api/animations/${reference.id}/frames/${first.id}`);
return { ...animation, type: "animation", read_only: true, scene: frame.scene };
}
export async function initializeDefaultBoard({ canLoad, load, apply, retain }) {
if (!canLoad()) return false;
const content = await load();
if (!canLoad()) {
retain();
return false;
}
if (content) apply(content);
else retain();
return Boolean(content);
}