Commit Graph

31 Commits

Author SHA1 Message Date
Michael Pilosov
98f423b794 feat: set White/Black names in the Save dialog too
Mirrors the Export PGN dialog: Save now has White/Black fields (pre-filled,
placeholders blank) and writes the names back to headers + on-screen info, so a
saved game stores real player names instead of You/Opponent. Shared prefill/
write-back helpers between the two dialogs. Bump cache version.
2026-06-25 22:02:38 +00:00
Michael Pilosov
3974c9faab feat: set White/Black player names when exporting a PGN
Export PGN now opens a dialog with White/Black fields (pre-filled from the game
headers, placeholders treated as blank). Entered names are written back, so they
appear in the exported PGN, update the on-screen 'X vs Y' line, and persist if the
game is saved — instead of always exporting 'You vs Opponent'. Bump cache version.
2026-06-25 21:45:03 +00:00
Michael Pilosov
791cc35962 polish: route PGN-error alerts through the in-app dialog too
Replaces the last native alert() calls (corrupted saved game / unparseable PGN)
and the delete confirm with the same <dialog>-based modalAlert/modalConfirm
helpers, so no flow relies on native popups that the browser may suppress.
Bump cache version.
2026-06-25 21:28:39 +00:00
Michael Pilosov
233ecb97c0 fix: save/delete use in-app dialogs instead of native prompt/confirm
The browser suppresses native confirm()/prompt() when the page isn't the active
tab ('dialog was suppressed because this page is not the active tab'). A
suppressed confirm() returns false, so the overwrite-on-save check silently
cancelled — no dialog, no overwrite. Replaced the prompt+confirm flow with a real
<dialog> save modal (name input + live 'this overwrites' warning, so Save is the
confirmation) and moved delete onto an in-app confirm dialog too. No native
popups in these flows now. Bump cache version.
2026-06-25 21:13:02 +00:00
Michael Pilosov
a2e62f4e5e code -> source code 2026-06-25 20:58:33 +00:00
Michael Pilosov
8acd9ef8d2 fix: saving a game with an existing name overwrites instead of duplicating
saveCurrentGame always pushed a new entry, so re-saving under the same title
produced two dropdown entries. Now it warns + confirms, then replaces the
same-named game (case-insensitive), collapsing any existing duplicates into one.
Bump asset cache version.
2026-06-25 20:54:54 +00:00
Michael Pilosov
cf24009e31 feat: opt-in PWA/offline behind ENABLE_CHESS_PWA flag; add cache-version bump
- sw.js + manifest.json: cache-first service worker for instant repeat-visit
  loads and full offline use. Registered only when window.CHESS_PWA is true.
- Disabled by default: an active SW serves returning visitors from cache, so
  they'd stop hitting the server and disappear from the Fly logs. Enable at
  build time with --build-arg ENABLE_CHESS_PWA=1 (Dockerfile flips the flag);
  ENABLE_CHESS_PWA=1 make dev does the same locally.
- scripts/bump_version.sh + 'make bump': bump the asset cache version across
  index.html (?v=N) and sw.js (CACHE) in sync. Required before deploy so the
  service worker / browser cache pick up changed assets. Bumped v25 -> v26.
- README: document cache versioning + PWA flag.
2026-06-25 20:47:19 +00:00
Michael Pilosov
85640e6f8d ui: drop fork tracking for new games; fix stale fork badge
New games have no reference line to return to, so rewinding to fix a finger-slip
no longer shows a 'forked' badge — corrections just overwrite silently. Loaded
games (built-in / uploaded / saved) keep 'Reset to original', but the badge now
reads 'Modified from original' (no move number), which fixes the stale-fork-point
bug: the indicator stayed pinned to the first divergence and ignored later
rewinds. Resettable correctly across any number of rewinds now.
2026-06-25 20:37:47 +00:00
Michael Pilosov
1d9f9459df ui: default to a new game; clean placeholder game info; status beside info
- Open on a fresh 'You vs Opponent' game instead of the Immortal Game.
- Hide chess.js Seven-Tag-Roster placeholders ("?", "????.??.??") so a new
  game reads just "You vs Opponent" rather than "You vs Opponent — ? — ????.??.??".
- Move the turn/move status onto the same row as the game info (top of the side
  panel) instead of below the move list.
2026-06-25 19:44:35 +00:00
Michael Pilosov
ba1d993676 feat: move engine fully client-side; serve as static; add save/export
Gameplay (legal moves, move application, pressure maps, PGN parsing) now runs
entirely in the browser via a chess.js port of engine.py (static/engine.js +
vendored chess.min.js). The app no longer calls the server during play, so it
stays instant and works even when the backend is scaled to zero or offline.

- engine.js: line-for-line port of engine.py; parity-verified identical output
  (pressure, FEN, status, SAN/UCI) across all 10 built-in games / 829 frames.
- app.js: replace all /api fetches with local engine calls; graceful PGN parse
  errors; asset paths moved to root for static serving.
- Save games to localStorage + load from the game dropdown; export any game as
  a .pgn file. Minimal additive UI in the existing export row.
- games.json generated from games.py (scripts/export_games.py).
- Production Dockerfile -> static-web-server (~9MB image, was ~150MB python).
- make dev -> bun static server; add make games / make parity targets.
- app.py kept as optional fallback (serves static app + /api routes).
- parity/: automated JS-vs-python engine parity test.

git diff stat:

 16 files changed, 722 insertions(+), 128 deletions(-)
2026-06-25 19:41:55 +00:00
Michael Pilosov
94e890f3ca fix: rewinding and replaying a move now overwrites the line instead of appending
doMove only truncated moves/frames on the first divergence (forkPoint===null).
Subsequent rewind+move appended to the end of the line, corrupting the game
state irrecoverably. Always truncate to the current point before pushing.
Drop the dead forkedMoves state.
2026-06-25 19:29:27 +00:00
Michael Pilosov
1d8d8cec14 fix playback buttons: flex-basis 0 for proportional sizing, full width 2026-06-25 19:15:29 +00:00
Michael Pilosov
4ab86fa6a0 refactor: playback buttons full-width with double-triangle ff/rw icons
- btn-prev/next now use |◄ / ►| (single triangle + bar, was btn-start/end)
- btn-start/end now use |◄◄ / ►►| (double triangle + bar)
- playback-buttons row fills full width with flex:1 on all buttons
- outer two buttons (start/end) slightly smaller via flex:0.65 + 13px SVG
2026-06-25 19:08:00 +00:00
Michael Pilosov
1c04782db5 ui: replace emoji playback icons with SVG, restyle pressure controls
- All 5 playback buttons now use inline SVG triangles/bars — no more
  emoji rendering on iOS/Android
- Pause icon in togglePlay() also switches to SVG
- Radio mode toggle becomes a segmented pill control (own row, full width)
- Piece/Board checkboxes each get their own tap-friendly row (min 2.5rem tall)
2026-06-25 19:00:50 +00:00
Michael Pilosov
b2432305b5 installation 2026-04-19 18:13:51 +00:00
Michael Pilosov
f6d1b3a56c Add source link footer pointing to GitHub repo 2026-04-07 12:25:26 -06:00
Michael Pilosov
3bcb823909 Add deploy, logs, status targets to Makefile 2026-04-06 16:20:03 -06:00
Michael Pilosov
feadaf1b3e Cap machines at 1 2026-04-06 16:13:09 -06:00
Michael Pilosov
ffcf9781d5 Add fly.toml, set VM to 256mb 2026-04-06 16:02:49 -06:00
Michael Pilosov
abfd7fedc8 Add Dockerfile and health endpoints 2026-04-06 15:54:20 -06:00
Michael Pilosov
185a08fa8b Rebalance built-in games (max 2 per player) 2026-04-06 15:34:23 -06:00
Michael Pilosov
0f2aa97b01 Update README: all 10 built-in games, src-layout, uv quickstart 2026-04-06 15:34:23 -06:00
Michael Pilosov
46955f0644 Cache built-in game parsing to avoid recomputation per request 2026-04-06 15:34:23 -06:00
Michael Pilosov
0a7cdc0f15 Drop --reload from CLI, bump to 0.1.1 2026-04-05 23:01:14 -06:00
Michael Pilosov
f46f52ce3a publish target 2026-04-05 22:56:03 -06:00
Michael Pilosov
ff29a3cd4e Add CLI args for host, port, workers, and reload 2026-04-05 22:54:20 -06:00
Michael Pilosov
20dca2eefa Restructure as src-layout Python package with bundled static assets 2026-04-05 22:52:45 -06:00
Michael Pilosov
6eb5672351 Add frontend, Makefile, and additional built-in games 2026-04-05 22:51:03 -06:00
Michael Pilosov
937eacc448 entrypoint 2026-04-05 22:47:45 -06:00
Michael Pilosov
0e8886908a uv deps 2026-04-05 22:46:44 -06:00
Michael Pilosov
138122a35b Initial commit: chess pressure visualization app 2026-04-05 22:44:01 -06:00