131 lines
3.9 KiB
TypeScript
131 lines
3.9 KiB
TypeScript
// ui.ts (DOM слой)
|
||
export interface DOMElements {
|
||
serverTime: HTMLElement | null;
|
||
status: HTMLElement | null;
|
||
meta: HTMLElement | null;
|
||
latest: HTMLElement | null;
|
||
lastByte: HTMLElement | null;
|
||
history: HTMLElement | null;
|
||
canvas: HTMLCanvasElement | null;
|
||
bars: NodeListOf<HTMLElement>;
|
||
barFill: HTMLElement | null;
|
||
historyHeader: HTMLElement | null;
|
||
historyBody: HTMLElement | null;
|
||
audioIndicator: HTMLElement | null;
|
||
}
|
||
|
||
export const DOM: DOMElements = {
|
||
serverTime: null,
|
||
status: null,
|
||
meta: null,
|
||
latest: null,
|
||
lastByte: null,
|
||
history: null,
|
||
canvas: null,
|
||
bars: document.querySelectorAll(".sig-bar"),
|
||
barFill: null,
|
||
historyHeader: null,
|
||
historyBody: null,
|
||
audioIndicator: null,
|
||
};
|
||
|
||
export function initDOM(): void {
|
||
DOM.serverTime = document.getElementById("server-time");
|
||
DOM.status = document.getElementById("status");
|
||
DOM.meta = document.getElementById("meta");
|
||
DOM.latest = document.getElementById("latest");
|
||
DOM.lastByte = document.getElementById("last-byte");
|
||
DOM.history = document.getElementById("history");
|
||
DOM.canvas = document.getElementById("signalChart") as HTMLCanvasElement;
|
||
DOM.barFill = document.getElementById("bar1");
|
||
DOM.historyHeader = document.getElementById("history-header");
|
||
DOM.historyBody = document.getElementById("history-body");
|
||
DOM.bars = document.querySelectorAll(".sig-bar");
|
||
DOM.audioIndicator = document.getElementById("audio-indicator");
|
||
}
|
||
|
||
export function setServerTime(v: string): void {
|
||
if (DOM.serverTime) DOM.serverTime.textContent = v;
|
||
}
|
||
|
||
export function setStatus(v: string, isError: boolean = false): void {
|
||
if (!DOM.status) return;
|
||
DOM.status.textContent = v;
|
||
|
||
DOM.status.classList.remove("status-ok", "status-error", "status-lost");
|
||
|
||
if (isError) {
|
||
if (v === "Нет связи") {
|
||
DOM.status.classList.add("status-lost");
|
||
} else {
|
||
DOM.status.classList.add("status-error");
|
||
}
|
||
} else {
|
||
DOM.status.classList.add("status-ok");
|
||
}
|
||
}
|
||
|
||
export function setMeta(v: string): void {
|
||
if (DOM.meta) DOM.meta.textContent = v;
|
||
}
|
||
|
||
export function setBars(p: number, noConnection: boolean = false): void {
|
||
const el = DOM.barFill;
|
||
if (!el) return;
|
||
|
||
if (noConnection) {
|
||
el.style.width = "0%";
|
||
el.classList.add("no-connection");
|
||
} else {
|
||
el.classList.remove("no-connection");
|
||
el.style.width = `${Math.max(0, Math.min(100, p))}%`;
|
||
}
|
||
}
|
||
|
||
export function setSignal(level: number, noConnection: boolean = false): void {
|
||
const bars = DOM.bars;
|
||
if (!bars || bars.length < 3) return;
|
||
|
||
bars.forEach(bar => {
|
||
bar.classList.remove("active-1", "active-2", "active-3", "dim", "no-connection");
|
||
if (noConnection) {
|
||
bar.classList.add("no-connection");
|
||
} else {
|
||
bar.classList.add("dim");
|
||
}
|
||
});
|
||
|
||
if (noConnection) return;
|
||
|
||
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");
|
||
}
|
||
}
|
||
|
||
// ФУНКЦИЮ ДЛЯ ИНДИКАТОРА ЗВУКА
|
||
export function setAudioIndicator(active: boolean, level: number = 0): void {
|
||
const el = DOM.audioIndicator;
|
||
if (!el) return;
|
||
|
||
if (active && level > 0) {
|
||
el.textContent = `🔊 ${level}`;
|
||
el.style.color = '#00ff88';
|
||
el.style.opacity = '1';
|
||
// Анимация пульсации
|
||
el.style.animation = 'pulse 1s ease-in-out infinite';
|
||
} else {
|
||
el.textContent = '🔇';
|
||
el.style.color = '#666';
|
||
el.style.opacity = '0.5';
|
||
el.style.animation = 'none';
|
||
}
|
||
} |