build121 - можно создавать шорткаты без обязательно снятия оверлея
This commit is contained in:
2
app.py
2
app.py
@@ -29,7 +29,7 @@ from ui_builder import install_ui_builder
|
|||||||
from khl_site.khl_data_center import APP as khl_site_app
|
from khl_site.khl_data_center import APP as khl_site_app
|
||||||
|
|
||||||
BASE_DIR = Path(__file__).resolve().parent
|
BASE_DIR = Path(__file__).resolve().parent
|
||||||
BUILD_VERSION = "2026.08.26.7"
|
BUILD_VERSION = "2026.08.26.8"
|
||||||
# compatibility: BUILD_VERSION = "2026.08.26.1"
|
# compatibility: BUILD_VERSION = "2026.08.26.1"
|
||||||
# compatibility: BUILD_VERSION = "2026.08.25.1"
|
# compatibility: BUILD_VERSION = "2026.08.25.1"
|
||||||
# compatibility: BUILD_VERSION = "2026.08.24.15"
|
# compatibility: BUILD_VERSION = "2026.08.24.15"
|
||||||
|
|||||||
@@ -2538,14 +2538,13 @@ function startCustomTooltips() {
|
|||||||
prevent_default: sequence.prevent_default !== false,
|
prevent_default: sequence.prevent_default !== false,
|
||||||
allow_in_inputs: Boolean(sequence.allow_in_inputs),
|
allow_in_inputs: Boolean(sequence.allow_in_inputs),
|
||||||
toggle_all_overlays_on_repeat: Boolean(sequence.toggle_all_overlays_on_repeat),
|
toggle_all_overlays_on_repeat: Boolean(sequence.toggle_all_overlays_on_repeat),
|
||||||
// BUILD117: keep the legacy toggle flag for config compatibility, but let the
|
// BUILD121: overlay repeat-out targets are optional. Generic shortcuts do not
|
||||||
// operator choose exactly which vMix overlay channels are taken OUT on repeat.
|
// necessarily control graphics, so an empty selection is valid and is the default.
|
||||||
// Existing scoreboard configs had no list, so the safe default remains 1/2/3.
|
// Existing saved selections are preserved exactly. The dedicated scoreboard preset
|
||||||
// BUILD118 exposes vMix 29 Overlay channels 1..8 while leaving 4..8 untouched by default.
|
// still explicitly creates O1/O2/O3 because that preset is a graphics shortcut.
|
||||||
repeat_overlay_outs: (() => {
|
repeat_overlay_outs: (() => {
|
||||||
const raw = Array.isArray(sequence.repeat_overlay_outs) ? sequence.repeat_overlay_outs : [1, 2, 3];
|
const raw = Array.isArray(sequence.repeat_overlay_outs) ? sequence.repeat_overlay_outs : [];
|
||||||
const normalized = [...new Set(raw.map((value) => Number(value)).filter((value) => Number.isInteger(value) && value >= 1 && value <= 8))];
|
return [...new Set(raw.map((value) => Number(value)).filter((value) => Number.isInteger(value) && value >= 1 && value <= 8))];
|
||||||
return normalized.length ? normalized : [1, 2, 3];
|
|
||||||
})(),
|
})(),
|
||||||
sync_hockey_team_states: sequence.sync_hockey_team_states === undefined
|
sync_hockey_team_states: sequence.sync_hockey_team_states === undefined
|
||||||
? Boolean(sequence.toggle_all_overlays_on_repeat)
|
? Boolean(sequence.toggle_all_overlays_on_repeat)
|
||||||
@@ -5564,22 +5563,25 @@ function startCustomTooltips() {
|
|||||||
// BUILD118: repeat OUT is configurable across vMix Overlay channels 1..8. Do not use
|
// BUILD118: repeat OUT is configurable across vMix Overlay channels 1..8. Do not use
|
||||||
// OverlayInputAllOff: explicit OverlayInputNOut preserves each configured
|
// OverlayInputAllOff: explicit OverlayInputNOut preserves each configured
|
||||||
// transition-out and avoids touching unrelated channels that are not selected.
|
// transition-out and avoids touching unrelated channels that are not selected.
|
||||||
const repeatOverlayOuts = (Array.isArray(sequence.repeat_overlay_outs) ? sequence.repeat_overlay_outs : [1, 2, 3])
|
const selectedOverlayOuts = (Array.isArray(sequence.repeat_overlay_outs) ? sequence.repeat_overlay_outs : [])
|
||||||
.map((value) => Number(value))
|
.map((value) => Number(value))
|
||||||
.filter((value, index, values) => Number.isInteger(value) && value >= 1 && value <= 8 && values.indexOf(value) === index);
|
.filter((value, index, values) => Number.isInteger(value) && value >= 1 && value <= 8 && values.indexOf(value) === index);
|
||||||
const selectedOverlayOuts = repeatOverlayOuts.length ? repeatOverlayOuts : [1, 2, 3];
|
// Empty is intentionally valid: a shortcut may have no graphics/Overlay action.
|
||||||
await sendRuntimeVmixSequence(
|
// In that case do not swallow the repeat press; execute its normal steps below.
|
||||||
selectedOverlayOuts.map((number) => ({ Function: `OverlayInput${number}Out` })),
|
if (selectedOverlayOuts.length) {
|
||||||
execution,
|
await sendRuntimeVmixSequence(
|
||||||
);
|
selectedOverlayOuts.map((number) => ({ Function: `OverlayInput${number}Out` })),
|
||||||
if (sequence.sync_hockey_team_states) hockeyClearTeamStateOverlayTracking();
|
execution,
|
||||||
state.shortcutSequenceOverlayState.set(sequence.id, false);
|
);
|
||||||
state.quickPanelOnAirSequences.delete(String(sequence.id || ""));
|
if (sequence.sync_hockey_team_states) hockeyClearTeamStateOverlayTracking();
|
||||||
refreshQuickPanelOnAirClasses();
|
state.shortcutSequenceOverlayState.set(sequence.id, false);
|
||||||
window.dispatchEvent(new CustomEvent("ui-builder:shortcut-sequence-finish", { detail: { sequence: clone(sequence), meta: { ...meta, overlay_group_action: "off" } } }));
|
state.quickPanelOnAirSequences.delete(String(sequence.id || ""));
|
||||||
if (meta.source === "quick-panel-button") toast(`Выполнено: ${sequence.name} · кнопка «${meta.button_label || sequence.name}»`);
|
refreshQuickPanelOnAirClasses();
|
||||||
else if (String(meta.source || "").startsWith("keyboard")) toast(`Шорткат выполнен: ${sequence.name}`);
|
window.dispatchEvent(new CustomEvent("ui-builder:shortcut-sequence-finish", { detail: { sequence: clone(sequence), meta: { ...meta, overlay_group_action: "off" } } }));
|
||||||
return true;
|
if (meta.source === "quick-panel-button") toast(`Выполнено: ${sequence.name} · кнопка «${meta.button_label || sequence.name}»`);
|
||||||
|
else if (String(meta.source || "").startsWith("keyboard")) toast(`Шорткат выполнен: ${sequence.name}`);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (sequence.is_scoreboard_sequence) {
|
if (sequence.is_scoreboard_sequence) {
|
||||||
await syncConfiguredScoreboardCountdownsToRuntime();
|
await syncConfiguredScoreboardCountdownsToRuntime();
|
||||||
@@ -14391,7 +14393,7 @@ function renderHockeyPenaltyDashboard(node, component, runtime) {
|
|||||||
<label class="check-inline"><input type="checkbox" data-sequence-overlay-group ${sequence.toggle_all_overlays_on_repeat ? "checked" : ""}> повторное нажатие снимает выбранные Overlay</label>
|
<label class="check-inline"><input type="checkbox" data-sequence-overlay-group ${sequence.toggle_all_overlays_on_repeat ? "checked" : ""}> повторное нажатие снимает выбранные Overlay</label>
|
||||||
<span class="check-inline" data-sequence-overlay-outs-wrap>
|
<span class="check-inline" data-sequence-overlay-outs-wrap>
|
||||||
снять:
|
снять:
|
||||||
${[1, 2, 3, 4, 5, 6, 7, 8].map((number) => `<label class="check-inline"><input type="checkbox" data-sequence-overlay-out="${number}" ${(sequence.repeat_overlay_outs || [1, 2, 3]).includes(number) ? "checked" : ""}> O${number}</label>`).join("")}
|
${[1, 2, 3, 4, 5, 6, 7, 8].map((number) => `<label class="check-inline"><input type="checkbox" data-sequence-overlay-out="${number}" ${(sequence.repeat_overlay_outs || []).includes(number) ? "checked" : ""}> O${number}</label>`).join("")}
|
||||||
</span>
|
</span>
|
||||||
<label class="check-inline"><input type="checkbox" data-sequence-scoreboard ${sequence.is_scoreboard_sequence ? "checked" : ""}> этот сценарий — верхний счёт</label>
|
<label class="check-inline"><input type="checkbox" data-sequence-scoreboard ${sequence.is_scoreboard_sequence ? "checked" : ""}> этот сценарий — верхний счёт</label>
|
||||||
<label class="check-inline"><input type="checkbox" data-sequence-team-states ${sequence.sync_hockey_team_states ? "checked" : ""}> добавлять состояния команд к верхнему счёту</label>
|
<label class="check-inline"><input type="checkbox" data-sequence-team-states ${sequence.sync_hockey_team_states ? "checked" : ""}> добавлять состояния команд к верхнему счёту</label>
|
||||||
@@ -14430,11 +14432,8 @@ function renderHockeyPenaltyDashboard(node, component, runtime) {
|
|||||||
const selected = [...card.querySelectorAll("[data-sequence-overlay-out]:checked")]
|
const selected = [...card.querySelectorAll("[data-sequence-overlay-out]:checked")]
|
||||||
.map((item) => Number(item.dataset.sequenceOverlayOut))
|
.map((item) => Number(item.dataset.sequenceOverlayOut))
|
||||||
.filter((value) => Number.isInteger(value) && value >= 1 && value <= 8);
|
.filter((value) => Number.isInteger(value) && value >= 1 && value <= 8);
|
||||||
if (!selected.length) {
|
// BUILD121: zero selected overlays is valid. Some shortcuts do not put any
|
||||||
event.target.checked = true;
|
// graphics on air, so there is nothing that must be taken OUT on repeat.
|
||||||
toast("Для повторного снятия выберите хотя бы один Overlay");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sequence.repeat_overlay_outs = selected;
|
sequence.repeat_overlay_outs = selected;
|
||||||
}));
|
}));
|
||||||
card.querySelector("[data-sequence-scoreboard]").addEventListener("change", (event) => {
|
card.querySelector("[data-sequence-scoreboard]").addEventListener("change", (event) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user