feat: motd
This commit is contained in:
4
index.ts
4
index.ts
@@ -12,6 +12,8 @@ for (const line of lines.slice(1)) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MOTD = process.env.MOTD || "50;";
|
||||||
|
|
||||||
export let displaySockets: ServerWebSocket<unknown>[] = [];
|
export let displaySockets: ServerWebSocket<unknown>[] = [];
|
||||||
|
|
||||||
export async function broadcastDisplayUpdate() {
|
export async function broadcastDisplayUpdate() {
|
||||||
@@ -111,7 +113,7 @@ Bun.serve({
|
|||||||
if(!displaySockets.includes(ws)) {
|
if(!displaySockets.includes(ws)) {
|
||||||
displaySockets.push(ws);
|
displaySockets.push(ws);
|
||||||
console.log("Added display socket. Total:", displaySockets.length);
|
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
|
}, // a message is received
|
||||||
|
|||||||
@@ -24,6 +24,12 @@
|
|||||||
withSound = location.search.includes("sound=true");
|
withSound = location.search.includes("sound=true");
|
||||||
eventTarget.addEventListener("display", (e) => {
|
eventTarget.addEventListener("display", (e) => {
|
||||||
const detail = (e as CustomEvent).detail;
|
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(
|
const _newCalls = detail.tickets.filter(
|
||||||
(call: CallEntry) => !calls.find((c) => c.num === call.num)
|
(call: CallEntry) => !calls.find((c) => c.num === call.num)
|
||||||
);
|
);
|
||||||
@@ -48,9 +54,22 @@
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function updateMarqueeSpeed() {
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
const marqueeContent = document.querySelectorAll(".marquee-content") as NodeListOf<HTMLElement>;
|
||||||
|
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<string, number> = { A: 1, B: 2, C: 1, D: 2, E: 1 };
|
const ENTRIES: Record<string, number> = { A: 1, B: 2, C: 1, D: 2, E: 1 };
|
||||||
|
|
||||||
const ENTRIES_PER_TABLE = 10;
|
const ENTRIES_PER_TABLE = 10;
|
||||||
|
|
||||||
|
let marqueeSpeed = 50;
|
||||||
|
let marqueeText = $state("");
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if newCalls.length > 0}
|
{#if newCalls.length > 0}
|
||||||
@@ -84,6 +103,10 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
<div class="marquee">
|
||||||
|
<div class="marquee-content">{marqueeText}</div>
|
||||||
|
<div class="marquee-content">{marqueeText}</div>
|
||||||
|
</div>
|
||||||
<div class="p-4 flex justify-around gap-4 text-5xl">
|
<div class="p-4 flex justify-around gap-4 text-5xl">
|
||||||
<!-- <h1 class="text-6xl font-bold">Aufruf</h1> -->
|
<!-- <h1 class="text-6xl font-bold">Aufruf</h1> -->
|
||||||
<table class="self-start">
|
<table class="self-start">
|
||||||
@@ -136,7 +159,7 @@
|
|||||||
</table>
|
</table>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="fixed h-full w-1 top-0 left-1/2 -translate-x-1/2 {wsState.closed
|
class="fixed h-full w-1 top-15 left-1/2 -translate-x-1/2 {wsState.closed
|
||||||
? 'bg-red-800'
|
? 'bg-red-800'
|
||||||
: !wsState.connected
|
: !wsState.connected
|
||||||
? 'bg-amber-800'
|
? 'bg-amber-800'
|
||||||
@@ -239,4 +262,28 @@
|
|||||||
background-color: var(--accent);
|
background-color: var(--accent);
|
||||||
border: 2px solid var(--background);
|
border: 2px solid var(--background);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.marquee {
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100vw;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: 2.5rem;
|
||||||
|
gap: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.marquee-content {
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-name: marquee;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes marquee {
|
||||||
|
from {
|
||||||
|
transform: translateX(0%);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user