diff --git a/README_BUILD188_RU.txt b/README_BUILD188_RU.txt new file mode 100644 index 0000000..22f76bd --- /dev/null +++ b/README_BUILD188_RU.txt @@ -0,0 +1,37 @@ +BUILD188 — 2026.10.02.8 +Возврат прежнего вызова удалений при выданном верхнем счёте + +Установка поверх BUILD187 (2026.10.02.7). +В архиве только два изменённых файла приложения и эта инструкция: + app.py + ui_builder/static/app.js + +1. Остановите сервер. +2. Замените файлы, сохранив пути внутри проекта. +3. Запустите сервер и обновите браузер через Ctrl+F5. +Версия /api/health: 2026.10.02.8. + +Исправление +В BUILD186 проверка занятости Overlay могла блокировать показ нового удаления, +когда верхний счёт уже был выдан. Обычная функция вызова удалений полностью +возвращена к рабочему коду до BUILD186: прежние команды native Countdown и +OverlayInputNIn выполняются по прежним условиям. Правила показа большинства, +настройки Input и события веб-таймеров используются как раньше. + +Узкое исправление снятия Delay Penalty сохранено: если удаление ещё действует, +его плашка сохраняется на общем Input или возвращается на освобождённый Overlay. +При этом работающий таймер не перезапускается, а завершённое удаление не возвращается. + +Изменения вкладки «Буллиты» из BUILD187 сохранены. +Для восстановления обычного вызова удалений дополнительные изменения настроек +шорткатов и сценариев не требуются. + +Проверка после установки +1. Выдать верхний счёт и добавить новое удаление: плашка должна вызываться как раньше. +2. При действующем удалении включить и снять Delay Penalty: плашка удаления/ + большинства должна остаться или вернуться, а таймер продолжить работу. + +При подготовке проверены вызов новых удалений при живом верхнем счёте, +восстановление плашки после DP OFF, общий Input, сохранение native таймеров, +снятие последней карточки и подстановка Value в SelectedName. +Проверки выполнены в браузере с имитацией vMix; реальный vMix не подключался. diff --git a/app.py b/app.py index 6f50dac..325359c 100644 --- a/app.py +++ b/app.py @@ -35,7 +35,7 @@ from khl_site.khl_data_center import APP as khl_site_app, configure_storage, syn from hockey_data.khl_career import KhlCareerService BASE_DIR = Path(__file__).resolve().parent -BUILD_VERSION = "2026.10.02.7" +BUILD_VERSION = "2026.10.02.8" # compatibility: BUILD_VERSION = "2026.09.24.2" # compatibility: BUILD_VERSION = "2026.09.23.8" # compatibility: BUILD_VERSION = "2026.09.23.7" diff --git a/ui_builder/static/app.js b/ui_builder/static/app.js index b456db0..5027695 100644 --- a/ui_builder/static/app.js +++ b/ui_builder/static/app.js @@ -5541,7 +5541,6 @@ function startCustomTooltips() { // Overlay OUT operates on a layer. Do not remove an unrelated title that // has since replaced this penalty Input on that layer. const current = state.vmixOverlayRuntime.get(overlay); - if (hockeyTeamStateOverlayLayerWanted(overlay)) return; if (current && runtimeOverlayInputRefs(current).size && !runtimeOverlayMatchesInput(current, input)) return; const functionName = `OverlayInput${overlay}Out`; if (!outCommands.some((command) => command.Function === functionName)) { @@ -5572,7 +5571,6 @@ function startCustomTooltips() { const eventKey = penaltyMirrorKey(entry.component, entry.event); const sourceSide = String(entry.side || entry.event?.side || entry.event?.player?.side || side); const overlay = ["1", "2", "3", "4", "5", "6", "7", "8"].includes(String(target.overlay || "")) ? String(target.overlay) : "2"; - const reservedForTeamState = hockeyTeamStateOverlayLayerWanted(overlay); const assignmentChanged = !previous || previous.eventKey !== eventKey || String(previous.input || "") !== String(target.input) @@ -5586,7 +5584,7 @@ function startCustomTooltips() { state.vmixPenaltyMirrors.delete(eventKey); state.vmixPenaltyTargetAssignments.set(assignmentKey, { eventKey, input: target.input, selectedName: target.selected_name, overlay, sourceSide, targetSide: side, - mode: "countdown", running: Boolean(entry.event.running), visible: scoreboardLive && !reservedForTeamState, + mode: "countdown", running: Boolean(entry.event.running), visible: scoreboardLive, }); const explicitEdit = editedEventKey === eventKey; const reseed = assignmentChanged || explicitEdit || (force && !editedEventKey && !preservePausedCountdown); @@ -5618,20 +5616,14 @@ function startCustomTooltips() { } } - if (scoreboardLive && !reservedForTeamState) { - const current = state.vmixOverlayRuntime.get(overlay); - const targetWasVisible = !forceOverlay && (current && runtimeOverlayInputRefs(current).size - ? runtimeOverlayMatchesInput(current, target.input) - : previous?.visible === true && Boolean(previous?.input) && String(previous.input) === String(target.input) - && String(previous.overlay || overlay) === overlay); + if (scoreboardLive) { + const targetWasVisible = !forceOverlay && previous?.visible === true && Boolean(previous?.input) + && String(previous.input) === String(target.input) + && String(previous.overlay || overlay) === overlay; if (!targetWasVisible) { if (previous?.input && (String(previous.input) !== String(target.input) || String(previous.overlay || overlay) !== overlay)) { const previousOverlay = ["1", "2", "3", "4", "5", "6", "7", "8"].includes(String(previous.overlay || "")) ? String(previous.overlay) : overlay; - const previousCurrent = state.vmixOverlayRuntime.get(previousOverlay); - if (!hockeyTeamStateOverlayLayerWanted(previousOverlay) && (!previousCurrent || !runtimeOverlayInputRefs(previousCurrent).size - || runtimeOverlayMatchesInput(previousCurrent, previous.input))) { - outCommands.push({ Function: `OverlayInput${previousOverlay}Out`, Input: previous.input }); - } + outCommands.push({ Function: `OverlayInput${previousOverlay}Out`, Input: previous.input }); } inCommands.push({ Function: `OverlayInput${overlay}In`, Input: target.input }); }