fix bug in app.js

This commit is contained in:
admin committed 2026-09-11 22:21:32 +07:00
1 parent 1620f9b4d9
commit 000d2e818f
1 file changed
+23 -23
+23 -23
View File
@@ -151,21 +151,21 @@ const MAP = {
const $ = (sel) => document.querySelector(sel); const $ = (sel) => document.querySelector(sel);
const $$ = (sel) => document.querySelectorAll(sel); const $$ = (sel) => document.querySelectorAll(sel);
function t(key) { function i18n(key) {
return I18N[State.lang][key] || I18N.en[key] || key; return I18N[State.lang][key] || I18N.en[key] || key;
} }
function applyI18n() { function applyI18n() {
document.documentElement.lang = State.lang; document.documentElement.lang = State.lang;
document.body.dataset.lang = State.lang; document.body.dataset.lang = State.lang;
document.title = t("page_title"); document.title = i18n("page_title");
$$("[data-i18n]").forEach(el => { $$("[data-i18n]").forEach(el => {
const k = el.getAttribute("data-i18n"); const k = el.getAttribute("data-i18n");
el.textContent = t(k); el.textContent = i18n(k);
}); });
$$("[data-i18n-title]").forEach(el => { $$("[data-i18n-title]").forEach(el => {
const k = el.getAttribute("data-i18n-title"); const k = el.getAttribute("data-i18n-title");
el.title = t(k); el.title = i18n(k);
}); });
} }
@@ -384,7 +384,7 @@ function drawZones(zones) {
ctx.save(); ctx.save();
ctx.font = "bold 11px 'Inter', system-ui, sans-serif"; ctx.font = "bold 11px 'Inter', system-ui, sans-serif";
ctx.textAlign = "center"; ctx.textAlign = "center";
const occText = z.occupied ? t("occupied") : t("empty"); const occText = z.occupied ? i18n("occupied") : i18n("empty");
ctx.fillStyle = z.occupied ? "#ffffff" : hexToRgba("#000000", 0.55); ctx.fillStyle = z.occupied ? "#ffffff" : hexToRgba("#000000", 0.55);
const label = `Z${z.id} · ${occText}`; const label = `Z${z.id} · ${occText}`;
const metrics = ctx.measureText(label); const metrics = ctx.measureText(label);
@@ -591,13 +591,13 @@ function refreshPanels() {
row.innerHTML = ` row.innerHTML = `
<div class="target-slot s${idx+1}">T${t.slot}</div> <div class="target-slot s${idx+1}">T${t.slot}</div>
<div class="target-detail"> <div class="target-detail">
<span class="status ${statusKey}">${t(statusKey)}</span> <span class="status ${statusKey}">${i18n(statusKey)}</span>
<div class="target-metrics"> <div class="target-metrics">
<div>${t("x_coord")}: <b>${t.x_mm} mm</b></div> <div>${i18n("x_coord")}: <b>${t.x_mm} mm</b></div>
<div>${t("y_coord")}: <b>${t.y_mm} mm</b></div> <div>${i18n("y_coord")}: <b>${t.y_mm} mm</b></div>
<div>${t("speed")}: <b>${speedTxt} cm/s</b></div> <div>${i18n("speed")}: <b>${speedTxt} cm/s</b></div>
<div>${t("distance")}: <b>${distanceKm} m</b></div> <div>${i18n("distance")}: <b>${distanceKm} m</b></div>
<div style="grid-column: span 2;">${t("angle")}: <b>${angleTxt}</b></div> <div style="grid-column: span 2;">${i18n("angle")}: <b>${angleTxt}</b></div>
</div> </div>
</div>`; </div>`;
tl.appendChild(row); tl.appendChild(row);
@@ -612,10 +612,10 @@ function refreshPanels() {
row.innerHTML = ` row.innerHTML = `
<div class="zone-swatch z${idx+1}"></div> <div class="zone-swatch z${idx+1}"></div>
<div class="zone-info"> <div class="zone-info">
<div class="zone-name">${t("zone_"+(idx+1))} · Z${z.id}</div> <div class="zone-name">${i18n("zone_"+(idx+1))} · Z${z.id}</div>
<div class="zone-coord">[${z.x1}, ${z.y1}] → [${z.x2}, ${z.y2}]</div> <div class="zone-coord">[${z.x1}, ${z.y1}] → [${z.x2}, ${z.y2}]</div>
</div> </div>
<div class="zone-badge ${z.occupied ? "occupied" : "empty"}">${z.occupied ? t("occupied") : t("empty")}</div> <div class="zone-badge ${z.occupied ? "occupied" : "empty"}">${z.occupied ? i18n("occupied") : i18n("empty")}</div>
`; `;
zl.appendChild(row); zl.appendChild(row);
}); });
@@ -629,22 +629,22 @@ function buildEditorInputs() {
const block = document.createElement("div"); const block = document.createElement("div");
block.className = "zone-editor-block"; block.className = "zone-editor-block";
block.innerHTML = ` block.innerHTML = `
<label>${t("zone_"+(idx+1))} — Z${z.id}</label> <label>${i18n("zone_"+(idx+1))} — Z${z.id}</label>
<div class="coord-grid"> <div class="coord-grid">
<div class="coord-field"> <div class="coord-field">
<label>${t("edit_zone_x1")}</label> <label>${i18n("edit_zone_x1")}</label>
<input type="number" data-zone="${idx}" data-field="x1" value="${z.x1}"> <input type="number" data-zone="${idx}" data-field="x1" value="${z.x1}">
</div> </div>
<div class="coord-field"> <div class="coord-field">
<label>${t("edit_zone_y1")}</label> <label>${i18n("edit_zone_y1")}</label>
<input type="number" data-zone="${idx}" data-field="y1" value="${z.y1}"> <input type="number" data-zone="${idx}" data-field="y1" value="${z.y1}">
</div> </div>
<div class="coord-field"> <div class="coord-field">
<label>${t("edit_zone_x2")}</label> <label>${i18n("edit_zone_x2")}</label>
<input type="number" data-zone="${idx}" data-field="x2" value="${z.x2}"> <input type="number" data-zone="${idx}" data-field="x2" value="${z.x2}">
</div> </div>
<div class="coord-field"> <div class="coord-field">
<label>${t("edit_zone_y2")}</label> <label>${i18n("edit_zone_y2")}</label>
<input type="number" data-zone="${idx}" data-field="y2" value="${z.y2}"> <input type="number" data-zone="${idx}" data-field="y2" value="${z.y2}">
</div> </div>
</div>`; </div>`;
@@ -719,7 +719,7 @@ function connectWS() {
console.warn("[Radar] WebSocket closed (code=" + ev.code + " reason=" + ev.reason + ")"); console.warn("[Radar] WebSocket closed (code=" + ev.code + " reason=" + ev.reason + ")");
State.browserWsConnected = false; State.browserWsConnected = false;
updateWsStatus("err"); updateWsStatus("err");
if (wsReconnectTimer == null) toast(t("ws_reconnecting"), "warning"); if (wsReconnectTimer == null) toast(i18n("ws_reconnecting"), "warning");
scheduleReconnect(); scheduleReconnect();
}; };
_activeWs.onerror = (ev) => { _activeWs.onerror = (ev) => {
@@ -741,14 +741,14 @@ function updateWsStatus(kind) {
const dot = chip.querySelector(".status-dot"); const dot = chip.querySelector(".status-dot");
const txt = chip.querySelector("span:last-child"); const txt = chip.querySelector("span:last-child");
dot.className = "status-dot " + (kind === "ok" ? "status-ok" : kind === "err" ? "status-err" : "status-warn"); dot.className = "status-dot " + (kind === "ok" ? "status-ok" : kind === "err" ? "status-err" : "status-warn");
txt.textContent = kind === "ok" ? t("ws_connected") : kind === "err" ? t("ws_disconnected") : t("ws_connecting"); txt.textContent = kind === "ok" ? i18n("ws_connected") : kind === "err" ? i18n("ws_disconnected") : i18n("ws_connecting");
} }
function updateEsp32Status(connected) { function updateEsp32Status(connected) {
const chip = $("#statusEsp32"); const chip = $("#statusEsp32");
const dot = chip.querySelector(".status-dot"); const dot = chip.querySelector(".status-dot");
const txt = chip.querySelector("span:last-child"); const txt = chip.querySelector("span:last-child");
dot.className = "status-dot " + (connected ? "status-ok" : "status-err"); dot.className = "status-dot " + (connected ? "status-ok" : "status-err");
txt.textContent = connected ? t("esp32_connected") : t("esp32_disconnected"); txt.textContent = connected ? i18n("esp32_connected") : i18n("esp32_disconnected");
} }
/* Called on every broadcast frame from backend */ /* Called on every broadcast frame from backend */
@@ -851,11 +851,11 @@ function initUI() {
body: JSON.stringify(payload), body: JSON.stringify(payload),
}); });
if (!res.ok) throw new Error("HTTP " + res.status); if (!res.ok) throw new Error("HTTP " + res.status);
toast(t("zone_saved"), "success"); toast(i18n("zone_saved"), "success");
$("#zoneEditor").hidden = true; $("#zoneEditor").hidden = true;
} catch (err) { } catch (err) {
console.error(err); console.error(err);
toast(t("zone_save_error") + ": " + err.message, "error"); toast(i18n("zone_save_error") + ": " + err.message, "error");
} }
}); });