Fix stale tile colors on theme toggle and double-counted stats on repeat Enter - #213
Merged
Conversation
…ing stats Two fixes on top of the animations work (#212): - Scored tiles froze in the previous theme's colors after a dark-mode or colorblind toggle. Cell cached the PaletteColor object it was scored with; ThemedLayout rebuilds the theme in place, so the tile's effect saw a changed prop but early-returned as already revealed. A letter's status is now a palette key (LetterStatus) end to end -- GameGrid computes keys, GameRow compares keys and uses sx theme paths, Cell resolves theme.palette[displayStatus] on every render. SampleGame and LandingLogo pass keys too. The effect also mirrors the prop once revealed, so a dependency change mid-flip reveals immediately instead of never. - A second Enter during the new ~2.5 s game-end delay (or after dismissing the stats dialog, or on a reloaded finished game) re-ran the game-end block, and logGame is additive, so the day's stats were counted twice. The block now only ends the game and logs when this render's gameState is still "inProgress"; later presses just reopen the dialog. Adds a ThemeProvider-swap test and a status-change test for Cell, and a repeat-Enter test for HomePage. Before/after screenshots of the color mismatch live in Claude-notes/images and are referenced from the 09-02 review doc. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JpS4A5zjVECoAQjVfMFazi
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two bugs found while reviewing #212 before deploying it to production. Neither is in production yet; both are on
main.1. Scored tiles froze in the previous theme's colors
Switching dark/light mode (or High Contrast) after scoring a guess left the tiles in the old palette while everything else, including the keyboard keys directly below them, switched.
Before (unfixed
main): dark mode, guessCHAIRscored, then switched to light. The tiles keep the dark palette (near-black R, dark green/yellow); the keys show the light one.Computed colors at that moment:
Ctilergb(83, 141, 78)(dark success)Ckeyrgb(106, 170, 100)(light success)Rtilergb(58, 58, 60)(dark error)Rkeyrgb(120, 124, 126)(light error)After: same steps on this branch. Tiles and keys change together and report identical colors.
Cause.
Cellcached thePaletteColorobject it was scored with indisplayStatusand only refreshed it at the flip midpoint.ThemedLayoutrebuilds the theme in place (useMemo, no remount), so the effect saw a new object as a changedstatusprop but early-returned because the tile was already revealed. Before #212 the tile readstatus.maindirectly, so it always tracked the theme.Fix. A letter's status is now a palette key end to end (
LetterStatus = "success" | "warning" | "error" | "primary", exported fromCell.tsx).GameGridcomputes keys,GameRowcompares keys and uses sx theme paths for the connector color, andCellresolvestheme.palette[displayStatus]on every render.SampleGameandLandingLogopass keys too, and both drop theiruseThemecalls. This was chosen over syncing the cached object on change because it removes the class of bug rather than patching one path, and it matches howKeyboardalready types key statuses.The effect also now mirrors the prop whenever the tile is already revealed. That closes a latent hole where any dependency change mid-flip cancelled the pending reveal timer and left the tile uncolored for good.
2. A repeat Enter during the game-end delay double-counted stats
#212 holds the stats dialog back ~2.5 s behind the flip, wave, and confetti on a game-ending win. During that window the on-screen ENTER key is still clickable, and a second tap (a mobile double-tap, say) re-ran the whole game-end block.
logGameis additive, so the day's stats were counted twice. Previously the dialog's backdrop appeared synchronously and blocked this. The same double-count already happened on any Enter after dismissing the dialog, or after reloading a finished game.Fix. The game-end block only ends the game and logs when this render's
gameStateis still"inProgress". Any later press just reopens the stats dialog.Tests
Cell: renders inside aThemeProvider, swaps in a theme with a differentsuccess.main, asserts the background follows.Cell: a status change on an already-revealed tile updates color and aria text with no flip.HomePage: a repeat Enter after a game-ending win reopens the dialog without changingnumQuestionsAttempted,questionsGuessedIn, or the category stats, both inside the delay window and after dismissing the dialog.npm run lint,npx vitest run(204 passing),npm run buildall pass locally. The review docClaude-notes/code-review-2026-09-02.mdhas both findings with the screenshots.🤖 Generated with Claude Code
https://claude.ai/code/session_01JpS4A5zjVECoAQjVfMFazi