агент ёбанный

This commit is contained in:
2026-09-24 17:38:59 +03:00
parent 87bd314526
commit 70fce14772
5 changed files with 194 additions and 80 deletions

View File

@@ -29,15 +29,29 @@
.replaceAll("'", "'");
async function api(path, options = {}) {
const response = await fetch(path, {
cache: "no-store",
credentials: "same-origin",
...options,
headers: {
const controller = new AbortController();
const timeoutMs = Number(options.timeoutMs || 5000);
const timer = setTimeout(() => controller.abort(), timeoutMs);
const fetchOptions = { ...options };
delete fetchOptions.timeoutMs;
if (!fetchOptions.signal) fetchOptions.signal = controller.signal;
let response;
try {
response = await fetch(path, {
cache: "no-store",
credentials: "same-origin",
...fetchOptions,
headers: {
...(options.body ? { "Content-Type": "application/json" } : {}),
...(options.headers || {}),
},
});
...(options.headers || {}),
},
});
} catch (error) {
if (error?.name === "AbortError") throw new Error(`Запрос ${path} превысил ${timeoutMs / 1000} с`);
throw error;
} finally {
clearTimeout(timer);
}
let payload = {};
try { payload = await response.json(); } catch (_) {}
if (!response.ok) {
@@ -279,7 +293,7 @@
async function load(force = false) {
if (state.loading && !force) return;
try {
const payload = await api("/api/hockey/agents/devices");
const payload = await api("/api/hockey/agents/devices", { timeoutMs: 3500 });
state.devices = Array.isArray(payload.devices) ? payload.devices : [];
state.activeDeviceId = String(payload.active_device_id || "");
state.activeDeviceIds = Array.isArray(payload.active_device_ids)
@@ -300,7 +314,10 @@
const editingTest = Boolean(state.root?.querySelector("[data-agent-test-form]")?.contains(document.activeElement));
if (!editingTest) render();
} catch (error) {
if (!String(error.message || "").includes("401")) console.warn("Could not load vMix agents", error);
if (!String(error.message || "").includes("401")) {
console.warn("Could not load vMix agents", error);
if (state.panelOpen) setMessage(error.message || "Не удалось получить список Agent", true);
}
}
}
@@ -409,9 +426,12 @@
panel.innerHTML = `
<header>
<div><small>VMIX BRIDGE</small><strong>Устройства</strong></div>
<button type="button" class="icon" data-agent-close aria-label="Закрыть">×</button>
<div class="hockey-agent-header-actions">
<button type="button" class="secondary" data-agent-refresh>Обновить</button>
<button type="button" class="icon" data-agent-close aria-label="Закрыть">×</button>
</div>
</header>
<div class="hockey-agent-current-match">Web матч: <b>${esc(gameId || "не выбран")}</b></div>
<div class="hockey-agent-current-match">Web матч: <b>${esc(gameId || "не выбран")}</b> · найдено: <b>${state.devices.length}</b></div>
${state.message ? `<div class="hockey-agent-notice ${state.messageError ? "error" : ""}">${esc(state.message)}</div>` : ""}
<div class="hockey-agent-list">${cards}</div>
<footer>Активных Agent может быть несколько. Несколько Agent могут одновременно работать с одним матчем. «Использовать здесь» меняет основной Agent этой панели, а «Подключить к матчу» подключает дополнительный Agent без переключения управления.</footer>
@@ -420,6 +440,16 @@
state.panelOpen = false;
render();
});
panel.querySelector("[data-agent-refresh]")?.addEventListener("click", async () => {
const button = panel.querySelector("[data-agent-refresh]");
if (button) button.disabled = true;
try {
await load(true);
setMessage("Список Agent обновлён");
} finally {
if (button) button.disabled = false;
}
});
}
window.HockeyAgentRuntime = {