if (is_me && data.timeout_ms > 0) {
this._start_claim_timer(data.timeout_ms, data.warning_ms);
}
+
+ /* If a letter was queued from a keyboard-initiated claim, take it. */
+ if (is_me && this._pending_key) {
+ const pending = this._pending_key;
+ this._pending_key = null;
+ const tile = this.state.center.find(
+ t => t.letter === pending && !this.state.revealing[t.id]
+ );
+ if (tile) {
+ this.take_letter(tile);
+ }
+ }
}
receive_claim_end(data) {
*****************************************************/
on_key_down(e) {
- if (!this.state.claim_active) return;
-
/* Ignore if typing in an input field. */
if (e.target.tagName === "INPUT" || e.target.tagName === "TEXTAREA") return;
+ if (!this.state.joined || this.state.game_over) return;
const key = e.key.toUpperCase();
- if (key === "BACKSPACE" || key === "DELETE") {
- /* Return the last letter from the rack. */
+ /* Vote: Y to accept, N to reject. */
+ if (this.state.vote_pending && !this.state.my_vote) {
+ if (key === "Y") { e.preventDefault(); this.vote(true); return; }
+ if (key === "N") { e.preventDefault(); this.vote(false); return; }
+ }
+
+ /* Spacebar: deal a letter from the bag. */
+ if (e.key === " " && !this.state.claim_player) {
+ e.preventDefault();
+ if (this.state.bag_remaining > 0) {
+ this.deal_letter();
+ }
+ return;
+ }
+
+ /* Escape: cancel claim. */
+ if (key === "ESCAPE" && this.state.claim_active) {
+ e.preventDefault();
+ this.cancel_claim();
+ return;
+ }
+
+ /* Backspace/Delete: return last letter during claim. */
+ if ((key === "BACKSPACE" || key === "DELETE") && this.state.claim_active) {
e.preventDefault();
const rack = this.state.claim_rack;
if (rack.length > 0) {
return;
}
- if (key === "ENTER") {
+ /* Enter: submit word during claim. */
+ if (key === "ENTER" && this.state.claim_active) {
e.preventDefault();
if (this.state.claim_rack.length >= 4) {
this.submit_word();
return;
}
- if (key === "ESCAPE") {
+ /* Everything below requires a letter key. */
+ if (!/^[A-Z]$/.test(key)) return;
+
+ /* If not claiming yet, start a claim and queue the letter. */
+ if (!this.state.claim_active) {
+ if (this.state.claiming || this.state.claim_player) return;
e.preventDefault();
- this.cancel_claim();
+ this._pending_key = key;
+ this.start_claim();
return;
}
- if (!/^[A-Z]$/.test(key)) return;
e.preventDefault();
/* Find a matching letter in the center and claim it. */