feat(game): finished-game export as a PNG image behind a format chooser #159
Reference in New Issue
Block a user
Delete Branch "feature/game-export-image"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The 📤 export of a finished game now opens a format chooser — Telegram's native popup inside Telegram (image / GCG / cancel), the app's own modal elsewhere — offering the existing GCG file and a new client-rendered PNG of the final position.
The image (
ui/src/lib/gameimage.ts, Canvas 2D, lazy dynamic import, zero new dependencies): always the light palette, classic A..O / 1..15 axes, premium squares as plain fills (no text labels), in-game tile styling, no last-move highlight; per-seat scoresheet with GCG-convention coordinates (across = row-first8G, down = column-firstH8), multi-word plays on a smaller second line, localized pass/exchange/resign/timeout notes, the endgame rack-settlement ± row, 🏆 by the winner, and ahostname · finish datefooter (device locale). Fixed scoresheet typography — a long game stretches the board instead (never below its minimum).Delivery: Web Share (cancelled share = no-op, never a blob fallback) or a desktop download; Android Telegram/VK WebViews and the desktop VK iframe — where a binary PNG has neither Web Share, a working
<a download>, nor a clipboard-text fallback — get a preview modal (data: URL image + long-press/right-click save hint + copy-image whereClipboardItemexists). On-device verification of exactly those webviews is on the contour after merge.Owner signed off the rendered samples (3 iterations: value-digit padding, label-free premiums, multi-word rows).
Tests: vitest (scoresheet/layout/notation/delivery picker) + Playwright e2e (chooser download paths on both engines, native-TG popup → preview modal). Docs baked: FUNCTIONAL(+_ru), UI_DESIGN.