From e874e372f4478c80307ca8357b72712e659da75d Mon Sep 17 00:00:00 2001
From: Kristians Laukis <7798036+LCrew@users.noreply.github.com>
Date: Wed, 9 Sep 2026 07:52:42 +0300
Subject: [PATCH] feat(huds): pick a broadcast HUD from the library, not a
hardcoded pair
The HUD pickers in the demo player and the stream deck listed a fixed
horizontal/vertical union, because those were the only two things the pod could
load. They were never separate HUDs -- only layouts of the one bundle JTs Hud
Manager ships -- and they are now the two seeded builtin rows in broadcast_huds,
so both pickers list the library instead and send a slug.
The HUD also outgrew its home. It was a two-value setting, which fit beside the
other playback toggles on the demo settings page; it is a library with an upload
and a per-row default now, so it gets a page. demo-settings deliberately stops
writing default_hud_mode as well as reading it -- the api still reads that row
as its fallback, so a page that kept rewriting it would quietly reassert an old
layout every time those settings were saved.
useBroadcastHuds queries with raw gql rather than the generated zeus client:
broadcast_huds is new, and the generated types come from `yarn codegen` against
a running Hasura, so zeus here would mean nobody can build this branch until
someone has migrated an instance. The list is cached at module scope because
three pickers can mount at once and it changes only on an import.
$apollo is reached inline rather than destructured at the top of
+
+
+
+
+
+
= {
- horizontal: "pages.settings.application.demo_settings.hud_mode_horizontal",
- vertical: "pages.settings.application.demo_settings.hud_mode_vertical",
-};
-const hudMode = ref("horizontal");
+// The panel's HUD library. This was a hardcoded horizontal/vertical pair,
+// because those were the only two things the pod could load — they were never
+// separate HUDs, only layouts of the one bundled HUD, and they are now the two
+// seeded builtin rows alongside anything an administrator has imported.
+const { huds: broadcastHuds, fetch: fetchBroadcastHuds } = useBroadcastHuds();
+onMounted(() => {
+ void fetchBroadcastHuds();
+});
+
+const hudLabel = (hud: { name?: string | null; slug: string }) =>
+ hud.name?.trim() || hud.slug;
+
+const hudSlug = ref(
+ useApplicationSettingsStore().defaultBroadcastHud,
+);
const xrayEnabled = ref(false);
const hudVisible = ref(true);
-async function setHudMode(mode: HudMode) {
- // Picking a layout while the overlay is hidden also brings it back
- // — the picker doubles as the visibility control, so selecting a
- // mode is the natural way to leave the "hide" state.
+async function setHud(slug: string) {
+ // Picking a HUD while the overlay is hidden also brings it back — the picker
+ // doubles as the visibility control, so selecting one is the natural way to
+ // leave the "hide" state.
const needsShow = !hudVisible.value;
- if (hudMode.value === mode && !needsShow) return;
- hudMode.value = mode;
+ if (hudSlug.value === slug && !needsShow) return;
+ hudSlug.value = slug;
+ // The action argument is still named `mode` so its signature is unchanged;
+ // it carries a broadcast_huds slug now, which the api resolves into the
+ // hudId + variant the pod needs.
await runMutation("set_hud_mode", () => ({
- setHudMode: [{ match_id: matchId.value, mode }, { success: true }],
+ setHudMode: [{ match_id: matchId.value, mode: slug }, { success: true }],
}));
if (needsShow) await setHudVisible(true);
}
@@ -805,30 +815,32 @@ watch(spectatedSteamId, (sid) => {
{{ $t("stream_deck.scoreboard") }}
-
+