Stage 17 (contour round 2): Grafana Live/reload, rate-limit, iOS reconnect, hint/plaque/make-move UX

- Grafana: disable Live (GF_LIVE_MAX_CONNECTIONS=0) so its WebSocket no longer trips caddy Basic-Auth and re-prompts; admin console gains a Grafana nav link
- deploy: force-recreate config-only services so reseeded Grafana dashboards / Caddyfile are actually picked up (the move-duration panel was invisible because the bind-mount went stale)
- rate-limit: raise per-user budget 120/40 -> 300/80; UI skips reloading on the echo of the player's own move (fewer requests, no double-load)
- iOS/Telegram reconnect: suppress the connection banner while backgrounded and for a short grace after resume; reconnect silently; wire visibilitychange + pageshow/pagehide + Telegram activated/deactivated (Bot API 8.0)
- hint button disabled when 0 hints remain; nudge button shows a disabled state on your own turn
- players plaque: invert so the active seat pops (accent chip, raised) and others recede
- make-move UX: a direct  commit button (no hold/popover); the Shuffle tab becomes ↩️ Reset while tiles are pending
This commit is contained in:
Ilia Denisov
2026-06-06 12:33:52 +02:00
parent 09fec2b83c
commit c94cd3c3bf
10 changed files with 110 additions and 48 deletions
+10
View File
@@ -12,6 +12,7 @@ interface TelegramWebApp {
colorScheme?: 'light' | 'dark';
ready?: () => void;
expand?: () => void;
onEvent?: (event: string, handler: () => void) => void;
}
function webApp(): TelegramWebApp | undefined {
@@ -49,6 +50,15 @@ export function telegramLaunch(): TelegramLaunch {
return { initData: w.initData, startParam, theme: w.themeParams };
}
/**
* telegramOnEvent subscribes to a Telegram WebApp lifecycle event (e.g. 'activated' /
* 'deactivated', added in Bot API 8.0). It is a no-op outside Telegram or on a client
* that predates the event, so callers can register defensively.
*/
export function telegramOnEvent(event: string, handler: () => void): void {
webApp()?.onEvent?.(event, handler);
}
/**
* telegramColorScheme returns Telegram's active colour scheme ('light' | 'dark'),
* or undefined outside Telegram. Inside the Mini App this — not the OS