summaryrefslogtreecommitdiffstats
path: root/web/play/src/blackjack.ts
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-11-08 03:32:24 +0100
committersalmonik <salmonik@tuta.io>2026-11-08 03:32:24 +0100
commitfda24c47a8262388ada92722850a362da65aaa6e (patch)
tree13363fa1461ae4e10087acba562a527b8bde4228 /web/play/src/blackjack.ts
parentv5.0.0: protocol v5 and the browser frontend (diff)
downloadzagan-bet-fda24c47a8262388ada92722850a362da65aaa6e.tar.gz
zagan-bet-fda24c47a8262388ada92722850a362da65aaa6e.zip
web: accept the serialized reels array and stop game loops on navigation
The Rust SlotsView serializes reels as an array of chars, so the browser joins it instead of String(array). The crash chart, reel animation and roulette observer now stop when another screen takes over, and a returning crash screen rebuilds its detached canvas. Action buttons ignore a double click before the server view arrives. Also tightens the gateway session registry with a generation token, caps WebSocket messages at 64 KiB, uses the __Host- cookie prefix on HTTPS, and ships the systemd unit.
Diffstat (limited to '')
-rw-r--r--web/play/src/blackjack.ts14
1 files changed, 13 insertions, 1 deletions
diff --git a/web/play/src/blackjack.ts b/web/play/src/blackjack.ts
index 3537f45..49d46fa 100644
--- a/web/play/src/blackjack.ts
+++ b/web/play/src/blackjack.ts
@@ -1,6 +1,14 @@
1import type { View } from "./types"; 1import type { View } from "./types";
2import { cardFace, clear, money, node } from "./dom"; 2import { cardFace, clear, money, node } from "./dom";
3 3
4let lastAction = 0;
5
6function actionAllowed(): boolean {
7 if (Date.now() - lastAction < 400) return false;
8 lastAction = Date.now();
9 return true;
10}
11
4function cardElement(card: string): HTMLElement { 12function cardElement(card: string): HTMLElement {
5 if (card === "?") { 13 if (card === "?") {
6 const back = node("div", "card back"); 14 const back = node("div", "card back");
@@ -124,6 +132,7 @@ export function renderBlackjack(
124 ? node("button", "btn primary", label) 132 ? node("button", "btn primary", label)
125 : node("button", "btn", label); 133 : node("button", "btn", label);
126 button.addEventListener("click", () => { 134 button.addEventListener("click", () => {
135 if (!actionAllowed()) return;
127 if (action === "hit") send("Hit"); 136 if (action === "hit") send("Hit");
128 else if (action === "stand") send("Stand"); 137 else if (action === "stand") send("Stand");
129 else send("Double"); 138 else send("Double");
@@ -133,12 +142,15 @@ export function renderBlackjack(
133 actions.append(actionsRow); 142 actions.append(actionsRow);
134 const forfeit = node("button", "btn danger wide", "Forfeit hand"); 143 const forfeit = node("button", "btn danger wide", "Forfeit hand");
135 forfeit.addEventListener("click", () => { 144 forfeit.addEventListener("click", () => {
145 if (!actionAllowed()) return;
136 if (window.confirm("Forfeit this hand? The reserved bet is lost.")) send("Forfeit"); 146 if (window.confirm("Forfeit this hand? The reserved bet is lost.")) send("Forfeit");
137 }); 147 });
138 actions.append(forfeit); 148 actions.append(forfeit);
139 } else if (canDeal) { 149 } else if (canDeal) {
140 const deal = node("button", "btn primary wide big", "DEAL"); 150 const deal = node("button", "btn primary wide big", "DEAL");
141 deal.addEventListener("click", () => send("Deal")); 151 deal.addEventListener("click", () => {
152 if (actionAllowed()) send("Deal");
153 });
142 actions.append(deal); 154 actions.append(deal);
143 } 155 }
144 156