From c45ff4525c0e45e4b8e762b81fd180c53d206d66 Mon Sep 17 00:00:00 2001 From: salmonik Date: Sun, 8 Nov 2026 12:24:25 +0100 Subject: web: match the desktop layout and remove play-money copy The browser now uses the desktop's full-width game split: no extra game header or card frame, a full-height sidebar with a pinned action block, and the same lobby grid, topbar account/balance blocks, and bottom-left notices. Slots uses the desktop symbol colours and gold win border; roulette gets the flat felt, column bets under the dozens, the wheel, circular chips, and a LAST line; blackjack gets a centred dealer/player table and divider; crash gets the chart panel, phase label and empty ready state. Also drops every play-money/real-money disclaimer from the page copy. --- web/play/src/main.ts | 97 +++++++++++++++++++--------------------------------- 1 file changed, 35 insertions(+), 62 deletions(-) (limited to 'web/play/src/main.ts') diff --git a/web/play/src/main.ts b/web/play/src/main.ts index 690d827..2ca4ab5 100644 --- a/web/play/src/main.ts +++ b/web/play/src/main.ts @@ -17,17 +17,18 @@ const accountBalance = byId("account-balance"); const gameGrid = byId("game-grid"); const gameBoard = byId("game-board"); const gameSide = byId("game-side"); -const gameTitle = byId("game-title"); -const gameBadge = byId("game-badge"); -const lobbyAccount = byId("lobby-account"); +const versionPill = byId("version-pill"); +const accountNumber = byId("account-number"); +const lobbyCount = byId("lobby-count"); + const historyBody = byId("history-body"); const authForm = byId("auth-form"); const authUser = byId("auth-user"); const authPass = byId("auth-pass"); const authError = byId("auth-error"); const authSubmit = byId("auth-submit"); -const tabLogin = byId("tab-login"); -const tabRegister = byId("tab-register"); +const authSwitch = byId("auth-switch"); +const authTitle = byId("auth-title"); const reconnectOverlay = byId("reconnect-overlay"); const reconnectMessage = byId("reconnect-message"); const replacedOverlay = byId("replaced-overlay"); @@ -39,6 +40,7 @@ let authMode: "login" | "register" = "login"; let infoFor: string | null = null; let serverOffset = 0; let reconnectAttempts = 0; +let lastScreen: string | null = null; const bets = new Map([ ["slots", 10], ["roulette", 10], @@ -54,10 +56,10 @@ const titles: Record = { }; const descriptions: Record = { - slots: "Five reels, five paylines. Match symbols from the left.", - roulette: "European single-zero wheel with inside and outside bets.", - blackjack: "Six-deck shoe. Blackjack pays 3:2.", - crash: "A rising multiplier. Cash out before it crashes.", + slots: "Spin the reels. Three or more matching symbols from the left win.", + roulette: "Put chips on the table, then spin. Straight numbers pay the most.", + blackjack: "Get closer to 21 than the dealer without going over.", + crash: "Start the round, then cash out before the multiplier crashes.", }; const basePath = location.pathname.includes("/play/") @@ -83,9 +85,13 @@ const gateway = new Gateway(wsUrl, { serverOffset = hello.time - Date.now(); currentUser = hello.user ?? null; if (typeof hello.balance === "number") lastBalance = hello.balance; - gameBadge.textContent = `v${hello.version}`; + versionPill.textContent = `v${hello.version}`; }, onView(next) { + if (next.screen !== lastScreen) { + byId("toasts").replaceChildren(); + lastScreen = next.screen; + } view = next; if (next.screen !== "slots") stopSlotsAnimation(); if (next.screen !== "crash") stopCrashAnimation(); @@ -124,12 +130,12 @@ const gateway = new Gateway(wsUrl, { authUser.focus(); } authSubmit.disabled = false; - authSubmit.textContent = authMode === "login" ? "Log in" : "Create account"; + authSubmit.textContent = authMode === "login" ? "LOG IN" : "CREATE ACCOUNT"; }, onError(text) { toast(text, "bad"); authSubmit.disabled = false; - authSubmit.textContent = authMode === "login" ? "Log in" : "Create account"; + authSubmit.textContent = authMode === "login" ? "LOG IN" : "CREATE ACCOUNT"; }, onReplaced() { replacedOverlay.hidden = false; @@ -166,9 +172,9 @@ function serverNow(): number { function setAuthMode(mode: "login" | "register"): void { authMode = mode; - tabLogin.classList.toggle("active", mode === "login"); - tabRegister.classList.toggle("active", mode === "register"); - authSubmit.textContent = mode === "login" ? "Log in" : "Create account"; + authTitle.textContent = mode === "login" ? "Sign in" : "Create account"; + authSubmit.textContent = mode === "login" ? "LOG IN" : "CREATE ACCOUNT"; + authSwitch.textContent = mode === "login" ? "CREATE ACCOUNT" : "BACK TO SIGN IN"; authPass.autocomplete = mode === "login" ? "current-password" : "new-password"; authError.textContent = ""; } @@ -192,6 +198,7 @@ function render(): void { accountName.textContent = String(user); } else { sessionBar.hidden = true; + accountNumber.textContent = "—"; } setBalance(lastBalance); @@ -219,8 +226,6 @@ function render(): void { case "blackjack": case "crash": show("game"); - gameTitle.textContent = titles[view.screen] ?? view.screen; - gameBadge.textContent = badge(view); if (view.screen === "slots") renderSlots(gameBoard, gameSide, view, send); else if (view.screen === "roulette") renderRoulette(gameBoard, gameSide, view, send); else if (view.screen === "blackjack") renderBlackjack(gameBoard, gameSide, view, send); @@ -231,47 +236,23 @@ function render(): void { } } -function badge(view: View): string { - if (view.screen === "crash") return String(view.status ?? ""); - if (view.screen === "blackjack") return String(view.status ?? ""); - if (view.screen === "slots") return String(view.phase ?? ""); - if (view.screen === "roulette") return String(view.phase ?? ""); - return ""; -} - function renderLobby(lobby: View): void { - lobbyAccount.textContent = lobby.account ? `Account ${lobby.account}` : ""; + accountNumber.textContent = lobby.account ? String(lobby.account) : "—"; + const order = ["slots", "roulette", "blackjack", "crash"]; + const list: [string, string][] = [...(lobby.games ?? [])].sort( + (a, b) => order.indexOf(a[0]) - order.indexOf(b[0]), + ); + lobbyCount.textContent = `${list.length} ${list.length === 1 ? "game" : "games"}`; gameGrid.replaceChildren(); - const list: [string, string][] = lobby.games ?? []; for (const [id, name] of list) { const card = node("article", `game-card ${id}`); card.append(node("h3", undefined, name || titles[id] || id)); card.append(node("p", undefined, descriptions[id] ?? "Play a round.")); - - const row = node("div", "row wrap"); - const label = node("label", "field"); - label.style.flex = "1"; - label.append(node("span", "label", "Bet")); - const input = node("input", "input bet-input") as HTMLInputElement; - input.type = "number"; - input.min = "1"; - input.step = "10"; - input.value = String(bets.get(id) ?? 10); - input.addEventListener("change", () => { - const value = Math.max(1, Math.floor(Number(input.value) || 1)); - input.value = String(value); - bets.set(id, value); - }); - label.append(input); - - const play = node("button", "btn primary", id === "roulette" ? "Open table" : "Play"); + const play = node("button", "btn primary wide", "PLAY"); play.addEventListener("click", () => { - const bet = Math.max(1, Math.floor(Number(input.value) || 1)); - bets.set(id, bet); - send({ Play: { game: id, bet } }); + send({ Play: { game: id, bet: bets.get(id) ?? 10 } }); }); - row.append(label, play); - card.append(row); + card.append(play); gameGrid.append(card); } @@ -280,9 +261,10 @@ function renderLobby(lobby: View): void { } } -// Auth tabs and form ------------------------------------------------------- -tabLogin.addEventListener("click", () => setAuthMode("login")); -tabRegister.addEventListener("click", () => setAuthMode("register")); +// Auth mode and form ------------------------------------------------------- +authSwitch.addEventListener("click", () => + setAuthMode(authMode === "login" ? "register" : "login"), +); authForm.addEventListener("submit", async (event) => { event.preventDefault(); @@ -312,16 +294,7 @@ authForm.addEventListener("submit", async (event) => { // Chrome and navigation ---------------------------------------------------- byId("logout").addEventListener("click", () => send("Logout")); byId("show-history").addEventListener("click", () => send({ History: { limit: 50 } })); -byId("refresh-lobby").addEventListener("click", () => send("Info")); byId("history-back").addEventListener("click", () => send("ShowLobby")); -byId("leave-game").addEventListener("click", () => { - if (!view) return; - const live = - (view.screen === "blackjack" && view.status === "player") || - (view.screen === "crash" && view.status === "running"); - if (live && !window.confirm("Leaving now forfeits the active bet. Continue?")) return; - send("Leave"); -}); byId("reload-replaced").addEventListener("click", () => location.reload()); byId("reload-reconnect").addEventListener("click", () => location.reload()); -- cgit v1.2.3