From: Carl Worth Date: Mon, 9 Mar 2026 03:10:05 +0000 (-0400) Subject: anagram: Add a guard against the same letter getting taken twice X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=fdf1af582e270e3071941287e83ad9ad01f9d4e7;p=lmno.games anagram: Add a guard against the same letter getting taken twice This is effectively debouncing taps (or keypresses) of letters being taken from the center of the play field and put into the rack. If the same letter tile is taken multiple times then a player can end up with "ghost" tile in the rack that never goes away but also can't be interacted with. --- diff --git a/anagrams/anagrams.jsx b/anagrams/anagrams.jsx index 4a13e90..dd97423 100644 --- a/anagrams/anagrams.jsx +++ b/anagrams/anagrams.jsx @@ -140,6 +140,7 @@ class Game extends React.Component { dragging_center_tile: null }; this._claim_interval = null; + this._taking_tiles = new Set(); /* tile IDs with in-flight take requests */ } componentDidMount() { @@ -491,6 +492,11 @@ class Game extends React.Component { } async take_center_letter(tile) { + /* Guard against duplicate takes of the same tile (e.g. rapid + * double-tap on mobile before React processes the first setState). */ + if (this._taking_tiles.has(tile.id)) return; + this._taking_tiles.add(tile.id); + /* Optimistically add to rack so letters appear in keystroke * order regardless of HTTP response timing. */ this.setState(prev => ({ @@ -505,6 +511,7 @@ class Game extends React.Component { const response = await fetch_post_json("take-letter", { letter_id: tile.id }); + this._taking_tiles.delete(tile.id); if (!response.ok) { /* Revert: remove from rack and restore to center. */ this.setState(prev => ({