Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 66a9e59db6 | |||
| ab069f2ec3 | |||
| cb664e4505 |
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "shelem",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.4",
|
||||
"description": "Shelem card game — multiplayer",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -1700,11 +1700,40 @@ async function validateAuth() {
|
||||
updateAuthBar();
|
||||
}
|
||||
|
||||
// Show the running app version in the lobby footer (served from /api/config).
|
||||
// Tapping it force-updates: clears the service-worker caches and reloads, so a
|
||||
// phone stuck on stale cached assets can pull the latest build.
|
||||
async function loadAppVersion() {
|
||||
try {
|
||||
const d = await fetch('/api/config').then(r => r.json());
|
||||
if (d.version) $('app-version').textContent = `v${d.version} · tap to update`;
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
|
||||
async function forceUpdate() {
|
||||
const el = $('app-version');
|
||||
if (el) el.textContent = 'Updating…';
|
||||
try {
|
||||
if ('serviceWorker' in navigator) {
|
||||
const regs = await navigator.serviceWorker.getRegistrations();
|
||||
await Promise.all(regs.map(r => r.unregister()));
|
||||
}
|
||||
if (window.caches) {
|
||||
const keys = await caches.keys();
|
||||
await Promise.all(keys.map(k => caches.delete(k)));
|
||||
}
|
||||
} catch { /* ignore */ }
|
||||
// SW gone and caches cleared — a plain reload now refetches everything fresh
|
||||
location.reload();
|
||||
}
|
||||
|
||||
// ─── Boot ─────────────────────────────────────────────────────
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
initLobby();
|
||||
wireGameEvents();
|
||||
applyBarBottom();
|
||||
loadAppVersion();
|
||||
$('app-version').addEventListener('click', forceUpdate);
|
||||
|
||||
// Drop any stale/corrupted auth token before we use it to connect
|
||||
await validateAuth();
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
|
||||
<p id="lobby-error" class="error-msg"></p>
|
||||
</div>
|
||||
<div id="app-version" class="app-version"></div>
|
||||
</div>
|
||||
|
||||
<!-- ══════════════ WAITING ROOM ══════════════ -->
|
||||
|
||||
+16
-2
@@ -1033,6 +1033,20 @@ input:focus { border-color: var(--gold); }
|
||||
.lb-table td { border-bottom: 1px solid rgba(255,255,255,.05); }
|
||||
.lb-table tr:hover td { background: rgba(255,255,255,.04); }
|
||||
|
||||
/* ── App version footer ───── */
|
||||
.app-version {
|
||||
text-align: center;
|
||||
margin-top: 14px;
|
||||
font-size: .72rem;
|
||||
color: rgba(255,255,255,.35);
|
||||
letter-spacing: .5px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
.app-version:hover { color: rgba(255,255,255,.6); text-decoration: underline; }
|
||||
.app-version:active { color: var(--gold); }
|
||||
|
||||
/* ── Round-by-round breakdown ───── */
|
||||
.round-breakdown-wrap { margin: 6px 0 2px; }
|
||||
.rb-scroll { max-height: 42vh; overflow-y: auto; -webkit-overflow-scrolling: touch; }
|
||||
@@ -1269,8 +1283,8 @@ input:focus { border-color: var(--gold); }
|
||||
box-shadow: 0 6px 28px rgba(0,0,0,.8);
|
||||
max-height: 55vh;
|
||||
}
|
||||
/* Shrink bid history on mobile so it doesn't swallow the screen */
|
||||
.bid-history { max-height: 110px; }
|
||||
/* Always 4 players, so show all four bids without an inner scroll */
|
||||
.bid-history { max-height: none; }
|
||||
.bid-box h3 { font-size: .95rem; margin-bottom: 0; }
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
'use strict';
|
||||
const CACHE_NAME = 'shelem-v2';
|
||||
const CACHE_NAME = 'shelem-v3';
|
||||
|
||||
// ── Generate all 55 card paths ──────────────────────────────────
|
||||
const SUITS = ['CLUB', 'DIAMOND', 'HEART', 'SPADE'];
|
||||
|
||||
@@ -132,8 +132,10 @@ app.use(express.static(path.join(__dirname, 'public'), {
|
||||
}));
|
||||
|
||||
// ─── Auth API ─────────────────────────────────────────────────
|
||||
const APP_VERSION = require('./package.json').version;
|
||||
|
||||
app.get('/api/config', (_req, res) => {
|
||||
res.json({ signupsOpen: config.signupsOpen });
|
||||
res.json({ signupsOpen: config.signupsOpen, version: APP_VERSION });
|
||||
});
|
||||
|
||||
// Validate the stored auth token; the client uses this at startup to detect a
|
||||
|
||||
Reference in New Issue
Block a user