обнова

This commit is contained in:
2026-09-24 17:16:49 +03:00
parent 258f0991ff
commit e262ce2684
5 changed files with 930 additions and 23 deletions

View File

@@ -123,6 +123,23 @@
return result;
}
async function connectAgentToCurrentMatch(deviceId) {
const token = currentSessionToken();
const gameId = currentGameId();
if (!token) throw new Error("Сначала откройте матч в основной панели");
if (!gameId) throw new Error("Сначала выберите матч");
const result = await api(`/api/hockey/agents/devices/${encodeURIComponent(deviceId)}/select-session`, {
method: "POST",
body: JSON.stringify({
session_token: token,
apply_mapping: false,
make_primary: false,
}),
});
refreshMappingInBackground(deviceId, result?.assignment || null);
return result;
}
function setMessage(text, error = false) {
state.message = text || "";
state.messageError = error;
@@ -150,6 +167,7 @@
else document.body.appendChild(root);
root.querySelector("[data-agent-toggle]")?.addEventListener("click", () => {
state.panelOpen = !state.panelOpen;
if (state.panelOpen) window.dispatchEvent(new CustomEvent("hockey:agent-open"));
render();
});
root.addEventListener("click", onClick);
@@ -175,26 +193,51 @@
render();
try {
if (action === "pair") {
const hadPrimary = Boolean(selectedDevice()?.device_id && currentGameId());
const paired = await api(`/api/hockey/agents/devices/${encodeURIComponent(deviceId)}/pair`, {
method: "POST",
body: JSON.stringify({ make_active: true }),
});
mergeDevicePayload(paired);
render();
await bindSelectedDevice(deviceId);
scheduleFastRefresh();
setMessage("Agent прикреплён и выбран для этой панели");
if (hadPrimary) {
await connectAgentToCurrentMatch(deviceId);
scheduleFastRefresh();
setMessage("Agent прикреплён и подключён к текущему матчу; основной Agent не изменён");
} else {
await bindSelectedDevice(deviceId);
scheduleFastRefresh();
setMessage("Agent прикреплён и выбран для этой панели");
}
} else if (action === "activate") {
const hadPrimary = Boolean(selectedDevice()?.device_id && currentGameId());
const activated = await api(`/api/hockey/agents/devices/${encodeURIComponent(deviceId)}/activate`, { method: "POST" });
mergeDevicePayload(activated);
render();
await bindSelectedDevice(deviceId);
scheduleFastRefresh();
setMessage("Agent включён и выбран для этой панели");
if (hadPrimary) {
await connectAgentToCurrentMatch(deviceId);
scheduleFastRefresh();
setMessage("Agent включён и подключён к текущему матчу; основной Agent не изменён");
} else {
await bindSelectedDevice(deviceId);
scheduleFastRefresh();
setMessage("Agent включён и выбран для этой панели");
}
} else if (action === "select") {
await bindSelectedDevice(deviceId);
scheduleFastRefresh();
setMessage("Эта панель теперь управляет выбранным Agent");
} else if (action === "assign-match") {
const currentMatch = String(currentGameId() || "").trim();
if (!currentMatch) throw new Error("Сначала выберите матч");
const existing = state.devices.find((item) => item.device_id === deviceId);
if (existing?.current_match_id && existing.current_match_id !== currentMatch) {
const ok = window.confirm(`Agent сейчас подключён к матчу ${existing.current_match_id}.\n\nПодключить его к текущему матчу ${currentMatch}?`);
if (!ok) return;
}
await connectAgentToCurrentMatch(deviceId);
scheduleFastRefresh();
setMessage(`Agent подключён к матчу ${currentMatch} без смены основной панели`);
} else if (action === "deactivate") {
await api(`/api/hockey/agents/devices/${encodeURIComponent(deviceId)}/deactivate`, { method: "POST" });
if (state.selectedDeviceId === deviceId) selectLocalDevice("");
@@ -270,6 +313,7 @@
const free = item.pair_state === "free";
const busy = item.pair_state === "busy";
const currentMatch = String(item.current_match_id || "");
const gameId = currentGameId();
let actions = "";
if (free && online) {
@@ -285,6 +329,12 @@
? '<span class="hockey-agent-badge active">Эта панель</span>'
: `<button type="button" data-agent-action="select" data-device-id="${esc(item.device_id)}">Использовать здесь</button>`)
: ""}
${active && !selectedHere && gameId && currentMatch !== gameId
? `<button class="secondary" type="button" data-agent-action="assign-match" data-device-id="${esc(item.device_id)}">Подключить к матчу</button>`
: ""}
${active && !selectedHere && gameId && currentMatch === gameId
? '<span class="hockey-agent-badge active">Этот матч</span>'
: ""}
${canTest ? `<button class="secondary" type="button" data-agent-action="test-toggle" data-device-id="${esc(item.device_id)}">${state.testOpenDeviceId === item.device_id ? "Скрыть тест" : "Тест SetText"}</button>` : ""}
${active ? `<button class="secondary" type="button" data-agent-action="deactivate" data-device-id="${esc(item.device_id)}">Не получать</button>` : ""}
<button class="danger" type="button" data-agent-action="unpair" data-device-id="${esc(item.device_id)}">Отвязать</button>
@@ -364,7 +414,7 @@
<div class="hockey-agent-current-match">Web матч: <b>${esc(gameId || "не выбран")}</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 может быть несколько. F1, Space, таймеры и другие команды идут только в Agent с меткой «Эта панель».</footer>
<footer>Активных Agent может быть несколько. Несколько Agent могут одновременно работать с одним матчем. «Использовать здесь» меняет основной Agent этой панели, а «Подключить к матчу» подключает дополнительный Agent без переключения управления.</footer>
`;
panel.querySelector("[data-agent-close]")?.addEventListener("click", () => {
state.panelOpen = false;
@@ -378,6 +428,12 @@
getDevices: () => state.devices.slice(),
};
window.addEventListener("hockey:diagnostics-open", () => {
if (!state.panelOpen) return;
state.panelOpen = false;
render();
});
window.addEventListener("hockey:game-selected", () => {
setTimeout(() => load(true), 300);
setTimeout(() => load(true), 1300);