139 lines
4.7 KiB
JavaScript
139 lines
4.7 KiB
JavaScript
// app.js (оркестратор)
|
||
import { fetchHealth, fetchHistory } from "./data.js";
|
||
import { state, smooth, addSignals, resetBufferTracking } from "./state.js";
|
||
import { initDOM, setStatus, setMeta, setBars, setSignal, DOM } from "./ui.js";
|
||
import { initAccordion } from "./accordion.js";
|
||
import { drawChart } from "./chart.js";
|
||
import { initResize } from "./layout.js";
|
||
import { initCamera } from "./camera.js";
|
||
let lastChart = 0;
|
||
let connectionLost = false;
|
||
let consecutiveErrors = 0;
|
||
const MAX_ERRORS = 3;
|
||
let pollTimer = null;
|
||
// ================= INIT =================
|
||
window.addEventListener("DOMContentLoaded", () => {
|
||
initDOM();
|
||
initAccordion();
|
||
initResize();
|
||
initCamera();
|
||
});
|
||
document.addEventListener("keydown", (e) => {
|
||
const leftPanel = document.getElementById("leftPanel");
|
||
const rightPanel = document.getElementById("rightPanel");
|
||
switch (e.key.toLowerCase()) {
|
||
case 'c':
|
||
const camBtn = document.getElementById('camToggle');
|
||
if (camBtn)
|
||
camBtn.click();
|
||
break;
|
||
case 'f':
|
||
if (leftPanel) {
|
||
leftPanel.style.width = "100%";
|
||
if (rightPanel)
|
||
rightPanel.style.display = "none";
|
||
}
|
||
break;
|
||
case 'escape':
|
||
if (rightPanel)
|
||
rightPanel.style.display = "flex";
|
||
if (leftPanel && rightPanel) {
|
||
const total = window.innerWidth;
|
||
const leftWidth = total * 0.6;
|
||
leftPanel.style.flex = `0 0 ${leftWidth}px`;
|
||
rightPanel.style.flex = `0 0 ${total - leftWidth}px`;
|
||
}
|
||
break;
|
||
}
|
||
});
|
||
// ================= UPDATE =================
|
||
async function update() {
|
||
try {
|
||
const [health, history] = await Promise.all([
|
||
fetchHealth(),
|
||
fetchHistory()
|
||
]);
|
||
consecutiveErrors = 0;
|
||
if (connectionLost) {
|
||
console.log("[app] Соединение восстановлено");
|
||
}
|
||
const isOnline = health.pipe_alive && health.has_data;
|
||
if (isOnline) {
|
||
setStatus("На связи");
|
||
connectionLost = false;
|
||
}
|
||
else {
|
||
setStatus("Нет связи", true);
|
||
if (!connectionLost)
|
||
resetBufferTracking();
|
||
connectionLost = true;
|
||
}
|
||
const arr = Array.isArray(history.bytes) ? history.bytes : [];
|
||
const raw = arr[arr.length - 1] ?? 0;
|
||
if (arr.length > 0 && isOnline) {
|
||
const bufferSize = health.stats?.filled ?? 0;
|
||
addSignals(arr, bufferSize);
|
||
}
|
||
const value = raw & 0x3F;
|
||
const level = (raw >> 6) & 0x3;
|
||
const percent = (value / 63) * 100;
|
||
if (isOnline) {
|
||
setBars(smooth(percent));
|
||
setSignal(level);
|
||
}
|
||
else {
|
||
setBars(0, true);
|
||
setSignal(0, true);
|
||
}
|
||
if (DOM.lastByte) {
|
||
DOM.lastByte.textContent = isOnline ? value.toString() : "--";
|
||
}
|
||
const uptime = Math.round(health.uptime_sec || 0);
|
||
const filled = health.stats?.filled ?? 0;
|
||
const Bps = Math.round(health.stats?.bytes_per_sec ?? 0);
|
||
setMeta(`Работа: ${uptime}s | Буфер: ${filled} | Приём: ${Bps} B/s`);
|
||
if (DOM.history) {
|
||
DOM.history.innerHTML = arr
|
||
.map((b, i) => `[${i}] ${(b & 0xFF).toString(2).padStart(8, "0")} = ${b & 0xFF}`)
|
||
.join("<br>");
|
||
}
|
||
const now = performance.now();
|
||
if (now - lastChart > 100 && DOM.canvas) {
|
||
drawChart(DOM.canvas, state.signalHistory);
|
||
lastChart = now;
|
||
}
|
||
}
|
||
catch (e) {
|
||
consecutiveErrors++;
|
||
if (consecutiveErrors === 1)
|
||
console.warn("[app] Сервер недоступен, ждём...");
|
||
setStatus("СЕРВЕР НЕДОСТУПЕН", true);
|
||
setBars(0, true);
|
||
setSignal(0, true);
|
||
resetBufferTracking();
|
||
if (DOM.lastByte)
|
||
DOM.lastByte.textContent = "--";
|
||
if (consecutiveErrors >= MAX_ERRORS && pollTimer) {
|
||
clearInterval(pollTimer);
|
||
pollTimer = window.setInterval(update, 2000);
|
||
console.log("[app] Замедлили опрос до 2с");
|
||
}
|
||
}
|
||
}
|
||
function startPolling() {
|
||
if (pollTimer)
|
||
clearInterval(pollTimer);
|
||
if (consecutiveErrors > 0)
|
||
update();
|
||
pollTimer = window.setInterval(update, 500);
|
||
}
|
||
window.addEventListener("focus", () => {
|
||
if (consecutiveErrors >= MAX_ERRORS) {
|
||
console.log("[app] Окно в фокусе, ускоряем опрос");
|
||
consecutiveErrors = 0;
|
||
startPolling();
|
||
}
|
||
});
|
||
startPolling();
|
||
update();
|