From fdf1af582e270e3071941287e83ad9ad01f9d4e7 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Sun, 8 Mar 2026 23:10:05 -0400 Subject: [PATCH] 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. --- anagrams/anagrams.jsx | 7 +++++++ 1 file changed, 7 insertions(+) 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 => ({ -- 2.45.2