diff --git a/index.ts b/index.ts index 125e659..85f582d 100644 --- a/index.ts +++ b/index.ts @@ -12,6 +12,8 @@ for (const line of lines.slice(1)) { } } +const MOTD = process.env.MOTD || "50;"; + export let displaySockets: ServerWebSocket[] = []; export async function broadcastDisplayUpdate() { @@ -111,7 +113,7 @@ Bun.serve({ if(!displaySockets.includes(ws)) { displaySockets.push(ws); console.log("Added display socket. Total:", displaySockets.length); - ws.send(JSON.stringify({ type: "display", tickets: await getDisplayTickets() })); + ws.send(JSON.stringify({ type: "display", tickets: await getDisplayTickets(), motd: MOTD })); } } }, // a message is received diff --git a/web/src/routes/display/+page.svelte b/web/src/routes/display/+page.svelte index 7c571c5..f4695c2 100644 --- a/web/src/routes/display/+page.svelte +++ b/web/src/routes/display/+page.svelte @@ -24,6 +24,12 @@ withSound = location.search.includes("sound=true"); eventTarget.addEventListener("display", (e) => { const detail = (e as CustomEvent).detail; + if(detail.motd) { + const [speed, ...text] = detail.motd.split(" "); + marqueeText = text.join(" "); + marqueeSpeed = parseInt(speed); + updateMarqueeSpeed(); + } const _newCalls = detail.tickets.filter( (call: CallEntry) => !calls.find((c) => c.num === call.num) ); @@ -48,9 +54,22 @@ ); }); + function updateMarqueeSpeed() { + requestAnimationFrame(() => { + const marqueeContent = document.querySelectorAll(".marquee-content") as NodeListOf; + const speed = marqueeSpeed; // px per second + const width = marqueeContent[0].offsetWidth; + marqueeContent[0].style.animationDuration = `${width / speed}s`; + marqueeContent[1].style.animationDuration = `${width / speed}s`; + }); + } + const ENTRIES: Record = { A: 1, B: 2, C: 1, D: 2, E: 1 }; const ENTRIES_PER_TABLE = 10; + + let marqueeSpeed = 50; + let marqueeText = $state(""); {#if newCalls.length > 0} @@ -84,6 +103,10 @@ {/if} +
+
{marqueeText}
+
{marqueeText}
+
@@ -136,7 +159,7 @@