Let a dealer take the table off the device it's stuck on #99
Closed
jheaps
wants to merge 1 commits from
feat/casino-holdem-table-file into fix/casino-holdem-touch-targets
pull from: feat/casino-holdem-table-file
merge into: :fix/casino-holdem-touch-targets
:master
:feature/socialism
:polish/holdem-seats-one-size
:fix/holdem-dealer-chip-eats-its-seat
:polish/holdem-game-night-ready
:polish/holdem-round-next
:polish/holdem-seat-collisions
:polish/holdem-offline-and-render
:fix/naming-a-blind-deals-the-hand
:release/casino-holdem-polish
:fix/casino-holdem-phone-look
:fix/casino-holdem-sidebar-crowding
:fix/casino-holdem-contribution-rule
:fix/casino-holdem-one-stack-rule
:fix/casino-holdem-default-stack-buyin
:feat/casino-holdem-waiting-list
:feat/casino-holdem-misdeal
:feat/casino-holdem-cash-out
:feat/casino-holdem-clock
:feat/casino-holdem-rake
:fix/casino-holdem-stadium-ring
:fix/casino-holdem-phone-felt-shape
:fix/casino-holdem-audit-runs-everything
:feat/casino-holdem-straddle
:fix/casino-holdem-landscape-ring
:feat/casino-holdem-table-file
:fix/casino-holdem-touch-targets
:fix/casino-holdem-audit-modal-blindspot
:fix/casino-holdem-quicksplit-chop
:fix/casino-holdem-buildable-bet-sizes
:fix/casino-holdem-pot-sized-raise
:fix/casino-holdem-chips-to-count-out
:fix/casino-holdem-first-buy-in
:fix/casino-holdem-seating-a-table
:fix/casino-holdem-showdown-order
:fix/casino-holdem-hand-log-filter
:fix/casino-holdem-posting-in
:fix/casino-holdem-dead-button
:fix/casino-holdem-discarded-pot
:fix/casino-holdem-honest-tank-clock
:fix/casino-holdem-export-the-notes
:fix/casino-holdem-stacks-in-chips
:fix/casino-holdem-close-audit-blind-spots
:fix/casino-holdem-readable-dim-states
:fix/casino-holdem-drop-broken-watermark
:fix/casino-holdem-two-tabs
:fix/casino-holdem-unreadable-save
:fix/casino-holdem-say-when-not-saving
:fix/casino-holdem-shortcut-discovery
:fix/casino-holdem-rulings-index-compact
:fix/casino-holdem-rulings-index
:fix/casino-holdem-payout-in-chips
:fix/casino-holdem-move-seat-on-touch
:fix/casino-holdem-amount-fields-select
:fix/casino-holdem-touch-targets-by-pointer
:fix/casino-holdem-button-box-model
:fix/casino-holdem-blind-badge-placement
:fix/casino-holdem-buyin-deals-in
:fix/casino-holdem-bet-vs-raise
:fix/casino-holdem-deal-around-broke
:fix/casino-holdem-settle-up
:fix/casino-holdem-allin-and-bar
:fix/casino-holdem-one-dealer-button
:fix/casino-holdem-manual-deal
:fix/casino-holdem-less-guessing
:feature/casino-holdem-seat-editor
:fix/casino-holdem-landscape-table
:feature/casino-holdem-acting-seat
:feature/casino-holdem-raise-guard
:feature/casino-holdem-first-run
:feature/casino-holdem-contrast-audit
:feature/casino-holdem-layout-audit
:feature/casino-holdem-blind-fairness
:feature/casino-holdem-rulings-depth
:feature/casino-holdem-bank-audit
:feature/casino-holdem-fewer-taps
:feature/casino-holdem-render-perf
:feature/casino-holdem-keyboard-focus
:feature/casino-holdem-resilience
:feature/casino-holdem-messy-tables
:feature/casino-holdem-touch-mobile
:chore/casino-holdem-tech-debt
:feature/casino-holdem-dealer-batch
:feature/casino-holdem-seat-count-safety
:feature/casino-holdem-odd-chip
:feature/casino-holdem-button-moves
:feature/casino-holdem-allin-runout
:feature/casino-holdem-heads-up
:feature/casino-holdem-contrast
:feature/casino-holdem-touch-audit
:feature/casino-holdem-wizard-polish
:feature/casino-quicksplit-side-pots
:feature/casino-holdem-rebuys
:feature/casino-holdem-rulings
:feature/casino-holdem-sidebar-polish
:feature/casino-holdem-keyboard
:feature/casino-holdem-action-undo
:feature/casino-holdem-pace
:feature/casino-holdem-side-pot-breakdown
:feature/casino-holdem-gestures
:feature/casino-holdem-card-picker
:feature/casino-holdem-live-betting
:feature/casino-holdem-bet-chips
:feature/casino-holdem-seat-legibility
:feature/casino-holdem-undo-toasts
:feature/casino-holdem-quick-split
:feature/casino-holdem-mobile-table
:feature/casino-holdem-hand-history
:feature/casino-texas-holdem
:feature/casino-holdem-dealer-mode-polish
:feature/fractional-learned-weights
:fix/stockfish-dispose-hang
:fix/blog-cache-staleness
:fix/workflows
:gitea/workflows
:echo-acoustic-ranging
:chess-ui-overhaul
:feature/customChessEngine
:feature/blog
:AddProject
:feature/generalUpdate
:tech-debt/chess-cleanup
:tests/CreatePlaywrightTests
:UpdateParticleSimulatorButton
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The night lives in one browser's localStorage and nowhere else. A dealer whose phone dies, or who wants to carry on from the tablet after the break, loses the stacks, the buy-ins, where the button is and the whole hand log. The CSV export can't bring any of it back — it records what happened, not where the table stands.
What changed
The table can be written to a file and read back, from the Session panel beside the CSV export. Round-tripped through the real UI, a hand in progress comes back mid-hand: blinds posted, the same seat on the clock, the button where it was.
Loading replaces everything, so it asks first and names both sides rather than saying "are you sure":
It runs through the same undoable path as the header buttons, so the toast offers the way back — and the confirm says exactly that rather than overstating it. (My first draft of that sentence claimed it couldn't be undone, which was wrong; the measurement of the toast is what caught it.)
Reading a file goes through exactly the same migration a save from storage does:
load()had that logic inline and it's now a function both call. A second, looser path for imports is how a format grows two meanings of the same field.What it refuses, each with something a dealer can act on, and never a half-loaded table:
The last one matters: loading it would risk reading a field whose meaning has changed, and the dealer would find out from the money. What it accepts anyway: a bare table with no envelope, for somebody who copied the storage value out by hand.
Verification
13 new tests in
tests/holdem/tableFile.test.js— the round trip preserving what a CSV can't carry, standings and the bank check agreeing across it, dealing straight from a loaded table, every refusal, migration of a file missing fields that exist now, and the dated filename. Suite at 400 tests, 0 failures.Playwright MCP end to end: saved a live table mid-hand (
holdem-table-2026-09-02-0106.json), wrecked it to zero players and no history, loaded the file back — names, stacks[200, 200, 339, 198], button on seat 2, table notes,bettingOpen, and the posted blinds[0, 0, 1, 2]all returned exactly. Undo put the wrecked table back. All three refusals checked with real files: correct message each time, no confirm shown, and the table byte-for-byte untouched. Layout audit clean, no console errors.Stacked on
fix/casino-holdem-touch-targets.🤖 Generated with Claude Code
https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgb
Pull request closed