diff --git a/tests/test_build77_penalty_overlay_auto_in.py b/tests/test_build77_penalty_overlay_auto_in.py new file mode 100644 index 0000000..a71cd17 --- /dev/null +++ b/tests/test_build77_penalty_overlay_auto_in.py @@ -0,0 +1,24 @@ +from pathlib import Path + +APP_JS = (Path(__file__).resolve().parents[1] / "ui_builder" / "static" / "app.js").read_text(encoding="utf-8") + + +def test_ready_penalty_opens_target_when_scoreboard_is_live(): + start = APP_JS.index("async function rebalanceVmixPenaltyTargets") + end = APP_JS.index("function finishActionMatchesSource", start) + snippet = APP_JS[start:end] + assert "if (hockeyScoreboardIsLive())" in snippet + assert 'commands.push({ Function: `OverlayInput${overlay}In`, Input: target.input });' in snippet + + +def test_penalty_overlay_auto_in_does_not_retrigger_visible_target(): + start = APP_JS.index("async function rebalanceVmixPenaltyTargets") + end = APP_JS.index("function finishActionMatchesSource", start) + snippet = APP_JS[start:end] + assert "const targetWasVisible = Boolean(previous?.input)" in snippet + assert "if (!targetWasVisible)" in snippet + + +def test_existing_team_state_sync_logic_is_untouched(): + assert 'for (const key of ["home_delayed_penalty", "home_empty_net", "away_delayed_penalty", "away_empty_net"])' in APP_JS + assert "async function hockeySyncTeamStateOverlays" in APP_JS diff --git a/ui_builder/static/app.js b/ui_builder/static/app.js index 5135f98..f012fac 100644 --- a/ui_builder/static/app.js +++ b/ui_builder/static/app.js @@ -4539,6 +4539,24 @@ function startCustomTooltips() { commands.push({ Function: "SetText", Input: target.input, SelectedName: target.selected_name, Value: value }); if (mirror) mirror.lastValue = value; } + + // If the scoreboard is already on air and this penalty target was not + // previously assigned, bring the penalty plate on air immediately. + // Previously the text was updated here, but OverlayIn happened only + // when the whole scoreboard shortcut was executed again. + if (hockeyScoreboardIsLive()) { + const overlay = ["1", "2", "3", "4"].includes(String(target.overlay || "")) ? String(target.overlay) : "2"; + const targetWasVisible = 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"].includes(String(previous.overlay || "")) ? String(previous.overlay) : overlay; + commands.push({ Function: `OverlayInput${previousOverlay}Out`, Input: previous.input }); + } + commands.push({ Function: `OverlayInput${overlay}In`, Input: target.input }); + } + } } else { if (previous && hideUnused && target.auto_hide_on_finish !== false && target.input) { const overlay = ["1", "2", "3", "4"].includes(String(target.overlay || "")) ? String(target.overlay) : "2";