Files

151 lines
4.9 KiB
JavaScript

import { builds, callModes, makeRecipe, toolSteps } from "./model.js";
const buildSelect = document.getElementById("build-select");
const modeSelect = document.getElementById("mode-select");
let currentBuild = "flash";
let currentStep = 0;
let currentPart = "startup";
function renderBuild() {
const selected = builds[currentBuild];
const flow = document.getElementById("build-flow");
flow.replaceChildren();
selected.flow.forEach((label, index) => {
if (index) {
const arrow = document.createElement("b");
arrow.textContent = "→";
arrow.setAttribute("aria-hidden", "true");
flow.append(arrow);
}
const node = document.createElement("span");
node.textContent = label;
flow.append(node);
});
document.getElementById("build-detail").textContent = selected.detail;
document.querySelectorAll("[data-build]").forEach((button) => {
button.setAttribute(
"aria-pressed",
String(button.dataset.build === currentBuild),
);
});
buildSelect.value = currentBuild;
const previousMode = modeSelect.value;
modeSelect.replaceChildren();
for (const key of selected.modes) {
const option = document.createElement("option");
option.value = key;
option.textContent = callModes[key].title;
modeSelect.append(option);
}
modeSelect.value = selected.modes.includes(previousMode)
? previousMode
: selected.modes[0];
renderRecipe();
}
function renderRecipe() {
const mode = callModes[modeSelect.value];
document.getElementById("endpoint-kind").textContent = mode.kind;
document.getElementById("endpoint-value").textContent = mode.endpoint;
document.getElementById("endpoint-detail").textContent = mode.detail;
document.getElementById("recipe-label").textContent =
`${builds[currentBuild].title} · ${mode.title}`;
document.getElementById("call-recipe").textContent = makeRecipe(
currentBuild,
modeSelect.value,
)[currentPart];
document.querySelectorAll("[data-part]").forEach((button) => {
button.setAttribute(
"aria-pressed",
String(button.dataset.part === currentPart),
);
});
document.getElementById("copy-status").textContent = "";
}
function renderStep() {
const selected = toolSteps[currentStep];
document.getElementById("step-number").textContent = String(
currentStep + 1,
).padStart(2, "0");
document.getElementById("step-title").textContent = selected.title;
document.getElementById("step-explanation").textContent =
selected.explanation;
document.getElementById("step-code").textContent = selected.code;
document.getElementById("step-progress").textContent =
`${currentStep + 1} / ${toolSteps.length}`;
document.getElementById("previous-step").disabled = currentStep === 0;
document.getElementById("next-step").disabled =
currentStep === toolSteps.length - 1;
document.querySelectorAll("[data-step]").forEach((button) => {
button.setAttribute(
"aria-pressed",
String(Number(button.dataset.step) === currentStep),
);
});
}
const stepList = document.getElementById("tool-steps");
toolSteps.forEach((step, index) => {
const button = document.createElement("button");
button.type = "button";
button.dataset.step = String(index);
button.textContent = `${index + 1} ${step.title}`;
button.addEventListener("click", () => {
currentStep = index;
renderStep();
});
stepList.append(button);
});
document.querySelectorAll("[data-build]").forEach((button) => {
button.addEventListener("click", () => {
currentBuild = button.dataset.build;
renderBuild();
});
});
buildSelect.addEventListener("change", () => {
currentBuild = buildSelect.value;
renderBuild();
});
modeSelect.addEventListener("change", renderRecipe);
document.querySelectorAll("[data-part]").forEach((button) => {
button.addEventListener("click", () => {
currentPart = button.dataset.part;
renderRecipe();
});
});
document.getElementById("previous-step").addEventListener("click", () => {
currentStep -= 1;
renderStep();
});
document.getElementById("next-step").addEventListener("click", () => {
currentStep += 1;
renderStep();
});
document.getElementById("copy-recipe").addEventListener("click", async () => {
try {
await navigator.clipboard.writeText(
document.getElementById("call-recipe").textContent,
);
document.getElementById("copy-status").textContent = "已复制调用示例。";
} catch {
document.getElementById("copy-status").textContent =
"可以在上方代码中手动选择并复制。";
}
});
const themeButton = document.getElementById("theme-toggle");
themeButton.addEventListener("click", () => {
const theme =
document.documentElement.dataset.theme === "dark" ? "light" : "dark";
document.documentElement.dataset.theme = theme;
themeButton.setAttribute(
"aria-label",
theme === "dark" ? "切换浅色主题" : "切换深色主题",
);
});
renderBuild();
renderStep();