Files
yovision/prototypes/sense/sense.js
T

123 lines
5.3 KiB
JavaScript

(function () {
"use strict";
const qs = (selector, root = document) => root.querySelector(selector);
const qsa = (selector, root = document) => [...root.querySelectorAll(selector)];
const toastRegion = qs("[data-toast-region]");
const announce = (message) => {
if (!toastRegion) return;
const item = document.createElement("div");
item.className = "toast";
item.setAttribute("role", "status");
item.textContent = message;
toastRegion.appendChild(item);
window.setTimeout(() => item.remove(), 3600);
};
qsa(".choice-card input").forEach((input) => {
input.addEventListener("change", () => {
qsa(`input[name="${input.name}"]`).forEach((peer) => peer.closest(".choice-card")?.classList.toggle("selected", peer.checked));
if (input.name === "discover-method") {
const manual = input.value === "manual";
qs("[data-auto-choice]").hidden = manual;
qs("[data-manual-choice]").hidden = !manual;
}
});
});
const wizard = qs("#add-camera");
if (wizard) {
let step = 0;
let connectionPassed = false;
const panels = qsa("[data-wizard-panel]", wizard);
const progress = qsa(".wizard-progress li", wizard);
const back = qs("[data-wizard-back]", wizard);
const next = qs("[data-wizard-next]", wizard);
const stepLabel = qs("[data-wizard-step-label]", wizard);
const connectionStatus = qs("[data-connection-status]", wizard);
const render = () => {
panels.forEach((panel, index) => {
panel.hidden = index !== step;
panel.classList.toggle("active", index === step);
});
progress.forEach((item, index) => item.classList.toggle("active", index <= step));
stepLabel.textContent = `第 ${step + 1} 步,共 ${panels.length} 步`;
back.disabled = step === 0;
next.textContent = step === panels.length - 1 ? "完成" : "下一步";
next.disabled = step === 3 && !connectionPassed;
qs("input, button, h3[tabindex]", panels[step])?.focus({ preventScroll: true });
};
qsa("[data-open-modal='add-camera']").forEach((trigger) => trigger.addEventListener("click", () => {
step = trigger.textContent.includes("继续") ? 2 : 0;
connectionPassed = false;
connectionStatus.className = "test-status";
connectionStatus.innerHTML = "<strong>尚未测试</strong><span>点击“测试连接”继续。</span>";
render();
}));
back.addEventListener("click", () => { if (step > 0) { step -= 1; render(); } });
next.addEventListener("click", () => {
if (step < panels.length - 1) { step += 1; render(); return; }
qs("[data-close-modal]", wizard)?.click();
announce("教学楼西门 01 已添加,可立即查看实时画面");
});
qs("[data-test-connection]", wizard)?.addEventListener("click", (event) => {
const button = event.currentTarget;
button.disabled = true;
button.textContent = "正在测试…";
connectionStatus.className = "test-status testing";
connectionStatus.innerHTML = "<strong>正在检查账号和画面</strong><span>通常几秒内完成。</span>";
window.setTimeout(() => {
connectionPassed = true;
connectionStatus.className = "test-status success";
connectionStatus.innerHTML = "<strong>连接成功</strong><span>画面正常,已自动选择高清(推荐)。</span>";
button.disabled = false;
button.textContent = "重新测试";
render();
}, 520);
});
qs("[data-simulate-failure]", wizard)?.addEventListener("click", () => {
connectionPassed = false;
connectionStatus.className = "test-status error";
connectionStatus.innerHTML = "<strong>账号验证失败</strong><span>请返回上一步检查用户名和密码,然后重新测试。</span>";
next.disabled = true;
announce("连接失败:请检查账号密码后重试");
});
}
const recovery = qs("#recover-camera");
if (recovery) {
const password = qs("#recover-password", recovery);
const error = qs("[data-recovery-error]", recovery);
const status = qs("[data-recovery-status]", recovery);
const save = qs("[data-recovery-save]", recovery);
qs("[data-recovery-test]", recovery)?.addEventListener("click", (event) => {
const testButton = event.currentTarget;
if (!password.value.trim()) {
error.hidden = false;
password.setAttribute("aria-invalid", "true");
password.focus();
return;
}
error.hidden = true;
password.removeAttribute("aria-invalid");
testButton.disabled = true;
testButton.textContent = "正在测试…";
status.className = "test-status testing";
status.innerHTML = "<strong>正在重新连接</strong><span>正在检查账号和实时画面。</span>";
window.setTimeout(() => {
status.className = "test-status success";
status.innerHTML = "<strong>连接成功</strong><span>实时画面已恢复,可以安全保存。</span>";
testButton.disabled = false;
testButton.textContent = "重新测试";
save.disabled = false;
}, 520);
});
save.addEventListener("click", () => {
qs("[data-close-modal]", recovery)?.click();
announce("宿舍东门 02 的账号已更新,实时画面恢复正常");
});
}
})();