Seat a player when the dealer names one, and stop hiding the bar on a full table
The first thing anybody does with this tool is seat the table, and it didn't work. Measured on a fresh table: click a seat, type a name, repeat six times — six names on the felt, six seats still not in the hand, and no action bar at all. No "post blinds and deal", no explanation, nothing to press. Six people at the table and a blank screen with no way forward. Three things were wrong and each hid the next. Naming a chair and dealing that chair in were separate acts. Putting a name on an empty chair is somebody sitting down, so it now deals them in. Only a chair that was empty — no name and nobody in it: renaming someone who is sitting out is a correction, not an arrival, and dealing them back in over a typo would be the tool overruling the dealer. The action bar hid itself whenever no seat was live, which was written for an empty felt and caught a named one too. A table with names on it is not an empty table; it's a table the dealer needs to be told something about. And the seat editor never redrew the bar. It refreshes narrowly on purpose — a full render on every keystroke would take the name field out from under the dealer mid-word — but the bar answers "is there a table here at all", and seating somebody is exactly what changes that answer. Even ticking "In hand" by hand left the bar hidden until something else happened to redraw. Verified the fix keeps focus and the caret where they were, typing a character at a time. For the states that can still reach it — a table where everyone was sat out, a save from before naming seated people — the prompt names them and offers "Deal in all 6" rather than a hunt through six seat editors. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgb
This commit is contained in:
@@ -79,8 +79,14 @@ const ActionBar = {
|
||||
// Anything to act on? A hand with nobody dealt in doesn't get a bar — and that
|
||||
// still holds during setup, because a seated player is a live seat whether or not
|
||||
// the betting has been opened. An empty table stays uncluttered.
|
||||
//
|
||||
// A *named* table is not an empty one, though, and that was the hole: name six
|
||||
// people without dealing any of them in and the bar hid itself, leaving a screen
|
||||
// with six players on it, no way forward and nothing saying why. Anyone with a
|
||||
// name on the felt is somebody the dealer has to be told about.
|
||||
isRunning() {
|
||||
return Betting.liveSeats(this.state).length > 0;
|
||||
return Betting.liveSeats(this.state).length > 0 ||
|
||||
this.state.seats.some(p => (p.name || "").trim());
|
||||
},
|
||||
|
||||
render() {
|
||||
@@ -598,6 +604,36 @@ const ActionBar = {
|
||||
}
|
||||
line.classList.add("dealPromptBlocked");
|
||||
wrap.appendChild(line);
|
||||
|
||||
// Named seats that aren't in the hand. Naming a chair now seats whoever is
|
||||
// in it, so reaching this takes something else — a table where everyone was
|
||||
// sat out, or a save from before that was true — but the way out of it
|
||||
// should still be one tap rather than a hunt through six seat editors.
|
||||
const benched = this.state.seats
|
||||
.map((player, index) => ({ player, index }))
|
||||
.filter(({ player }) => (player.name || "").trim() && !player.inHand)
|
||||
.map(({ index }) => index);
|
||||
|
||||
if (benched.length > 0) {
|
||||
const aside = document.createElement("p");
|
||||
aside.className = "dealPromptLine dealPromptAside dealPromptDebt";
|
||||
const text = document.createElement("span");
|
||||
text.textContent = benched.length === 1
|
||||
? `${listNames(benched)} is sitting out.`
|
||||
: `${listNames(benched)} are sitting out.`;
|
||||
aside.appendChild(text);
|
||||
aside.appendChild(this.button(
|
||||
benched.length === 1 ? "Deal them in" : `Deal in all ${benched.length}`,
|
||||
"dealPromptDebtBtn",
|
||||
() => this.commit("dealing everybody in", () => {
|
||||
benched.forEach(index => {
|
||||
this.state.seats[index].inHand = true;
|
||||
this.state.seats[index].folded = false;
|
||||
});
|
||||
})
|
||||
));
|
||||
wrap.appendChild(aside);
|
||||
}
|
||||
return wrap;
|
||||
}
|
||||
|
||||
|
||||
@@ -524,13 +524,41 @@ const Render = {
|
||||
this.updatePotBadge();
|
||||
this.renderSeatTotal(form, player);
|
||||
this.refreshPuck(index);
|
||||
// The editor deliberately refreshes narrowly rather than redrawing everything —
|
||||
// a full render on every keystroke would take the name field out from under the
|
||||
// dealer mid-word. But the action bar answers "is there a table here at all",
|
||||
// and seating somebody is exactly what changes that answer. Without this it
|
||||
// stayed hidden until something else happened to redraw: two players seated, a
|
||||
// dealable hand, and a blank bar until the page was reloaded.
|
||||
//
|
||||
// Safe to do on every keystroke: the bar is small, it's rebuilt on every action
|
||||
// anyway, and nothing inside it can hold focus while the sidebar has it.
|
||||
if (typeof ActionBar !== "undefined" && ActionBar.state) ActionBar.render();
|
||||
},
|
||||
|
||||
wireSeatFields(form, player, index) {
|
||||
const nameInput = form.querySelector(".seatNameInput");
|
||||
nameInput.value = player.name;
|
||||
nameInput.addEventListener("input", () => {
|
||||
// Putting a name on an empty chair is somebody sitting down, so they get
|
||||
// dealt in. It used to be two separate acts, and the second one was easy to
|
||||
// miss: a dealer setting up typed six names, got six seats that still
|
||||
// weren't in the hand, and the action bar hid itself because by its reckoning
|
||||
// nobody was playing. Six people at the table and a blank screen.
|
||||
//
|
||||
// Only for a chair that was empty — no name and not dealt in. Renaming
|
||||
// somebody who is sitting out is a correction, not an arrival, and dealing
|
||||
// them back in over a typo would be the tool overruling the dealer.
|
||||
const wasEmpty = !player.name.trim() && !player.inHand;
|
||||
player.name = nameInput.value;
|
||||
if (wasEmpty && player.name.trim()) {
|
||||
player.inHand = true;
|
||||
player.folded = false;
|
||||
const inHandBox = form.querySelector(".inHandCheckbox");
|
||||
if (inHandBox) inHandBox.checked = true;
|
||||
const foldBox = form.querySelector(".foldCheckbox");
|
||||
if (foldBox) { foldBox.checked = false; foldBox.disabled = false; }
|
||||
}
|
||||
document.getElementById("seatEditorTitle").textContent = this.puckLabel(player, index);
|
||||
this.commitSeatChange(form, player, index);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user