Files
go-service/cmd/server/web/js/app.js
2026-05-07 21:30:48 +03:00

148 lines
4.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ===== SMOOTH STATE =====
let lastValue = 0;
// ===== ACCORDION =====
const historyHeader = document.getElementById("history-header");
const historyBody = document.getElementById("history-body");
let accordionOpen = false;
if (historyBody && historyHeader) {
historyBody.classList.add("collapsed");
historyHeader.addEventListener("click", () => {
accordionOpen = !accordionOpen;
historyHeader.textContent =
(accordionOpen ? "▼" : "▶") + " ПРИНЯТЫЕ ДАННЫЕ";
historyBody.classList.toggle("collapsed", !accordionOpen);
});
}
// ===== PROGRESS =====
function setBar(id, value) {
const el = document.getElementById(id);
if (!el) return;
value = Math.max(0, Math.min(100, value));
el.style.width = value + "%";
}
// ===== SIGNAL =====
function setSignal(level) {
const bars = document.querySelectorAll(".sig-bar");
if (!bars.length) return;
bars.forEach(b => b.classList.remove("active-1", "active-2", "active-3", "dim"));
bars.forEach(b => b.classList.add("dim"));
if (level >= 1) {
bars[0].classList.add("active-1");
bars[0].classList.remove("dim");
}
if (level >= 2) {
bars[1].classList.add("active-2");
bars[1].classList.remove("dim");
}
if (level >= 3) {
bars[2].classList.add("active-3");
bars[2].classList.remove("dim");
}
}
// ===== SMOOTH =====
function smoothBar(target) {
const alpha = 0.2;
lastValue = lastValue + alpha * (target - lastValue);
return lastValue;
}
// ===== MEDIAN =====
function median(values) {
if (!values || values.length === 0) return 0;
const sorted = [...values].sort((a, b) => a - b);
const mid = Math.floor(sorted.length / 2);
return sorted.length % 2
? sorted[mid]
: (sorted[mid - 1] + sorted[mid]) / 2;
}
// ===== UPDATE LOOP =====
async function update() {
try {
const [r1, r2] = await Promise.all([
fetch("/api/health"),
fetch("/api/history")
]);
const h = await r1.json();
const hist = await r2.json();
// ===== STATUS =====
const statusEl = document.getElementById("status");
if (statusEl) statusEl.textContent = h.status || "неизвестно";
const filled = h.stats?.filled ?? 0;
const uptime = Math.round(h.uptime_sec || 0);
const bps = Math.round(h.stats?.bits_per_sec ?? 0);
const Bps = Math.round(h.stats?.bytes_per_sec ?? 0);
const meta = document.getElementById("meta");
if (meta) {
meta.textContent =
`работа: ${uptime}s | буфер: ${filled} | ${bps} bit/s (${Bps} B/s)`;
}
// ===== LATEST =====
const latest = Number(h.latest || 0);
const latestEl = document.getElementById("latest");
if (latestEl) latestEl.textContent = latest;
// optional bits view
if (typeof renderBits === "function") {
renderBits(latest);
}
// ===== HISTORY =====
const arr = Array.isArray(hist.bytes) ? hist.bytes : [];
const historyEl = document.getElementById("history");
if (historyEl) {
historyEl.innerHTML = arr
.map((b, i) =>
`[${i}] ${(Number(b) & 0xFF).toString(2).padStart(8, "0")} = ${Number(b) & 0xFF}`
)
.join("<br>");
}
// ===== SIGNAL PARSING =====
const raw = arr.length ? (arr[arr.length - 1] & 0xFF) : 0;
const barValue = raw & 0x3F; // 063
const signalLevel = (raw >> 6) & 0x3; // 03
const percent = (barValue / 63) * 100;
const smooth = smoothBar(percent);
setBar("bar1", smooth);
setSignal(signalLevel);
const lastByte = document.getElementById("last-byte");
if (lastByte) lastByte.textContent = barValue;
} catch (e) {
console.error("UPDATE ERROR:", e);
const status = document.getElementById("status");
if (status) status.textContent = "СЕРВЕР НЕДОСТУПЕН";
}
}
// ===== START =====
setInterval(update, 500);
update();