Repository navigation
feat(ui): steady death screen and retry-key lockout after a test ends - #42
Merged
Merged
Conversation
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
thokr-web | 09b8b10 | Oct 29 2026, 10:51 PM |
This was referenced Oct 29, 2026
Merged
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.
Intent
Follow-up to the death mode (
-d) merged in #28. Today, when a death-mode run ends on a mistake, the screen switches to a death screen with a centred skull, an "expected X, pressed Y" line, the prompt with the word died on, and progress stats.The ask: the lines being typed should not move at all from the test screen to the death screen - the jumping lines are unnecessary. Also remove the expected vs pressed line. The skull stays where it is now.
Later ask on the same PR: after any test end (natural finish or death), ignore the r and n keys for about 500ms - drop those keys, do not buffer them; esc and quit stay immediate; render the r/n hints dimmed until they go live, then normal. Remove the (esc)ape hint text everywhere it shows; esc keeps working. The browser demo gets the same behaviour, with the rule in the shared core so terminal and web cannot drift (time supplied by the caller, since wasm has no Instant::now).
Later ask on the same PR: replace the skull with a settled death look: typed text normal colour, the fatal (next expected) character drawn as a red block, the untyped remainder dimmed further than usual, and the stats line (e.g. '23 words, 95 chars, 6.1s') in red. No skull, no word 'died' anywhere. Prompt lines stay exactly where they are, the 500ms r/n lockout and dimmed hints stay.
Newest ask on the same PR: drop the initial red flash; keep only the settled look. On death go straight to the settled state. Remove the flash timing code and its tests from the shared core and the web engine (no dead code). Keep everything else.
What Changed
PromptLayout. The skull and the "expected X, pressed Y" line are gone. Typed text shows in normal colour, the fatal character is a red reversed block, the untyped rest is dimmed dark gray, and the progress stats line is red.Thokrecordsended_atandrestart_keys_live_atdropsr/n/Left/Right for 500ms (END_LOCKOUT). Dropped keys are not buffered. Esc and Ctrl-C still quit at once. The(r)etry / (n)ewlegend renders dimmed until the keys go live, andnext_tickwakes once more to redraw it.write/on_tick/next_tick/ui::drawnow take the time from the caller.(esc)apehint is removed from the terminal and web legends. The web engine uses the same core lockout rule and clock-passing calls. Newmain.rstests cover the lockout, and the snapshots are updated.Risk Assessment
✅ Low: The newest commit only removes the death-flash timing (DEATH_FLASH, death_flashing_at, the flash branch in next_tick and render_death, and its tests), so death goes straight to the settled look; the lockout, the dimmed hints and the prompt placement are unchanged, and no flash code is left in the core, the UI or the web engine.
Testing
I built thokr with a nix-provided cargo and drove it in a pseudo-terminal sized 80x24, rendering the screen with pyte (dim tracked). In death mode the three prompt rows had the same text on the same rows in the last test frame and in the death frame. The ~40ms death frame already had its settled look: a red block on the expected char, typed text in the normal colour, the rest gray and dim, and the stats line in red. It matched the ~250ms frame cell for cell, so there is no flash. There was no skull, no "died" and no "expected/pressed" line. The only hint was "(r)etry / (n)ew", in italic, dimmed until 500ms and normal at ~700ms. r and n pressed inside the lockout changed nothing, and r afterwards restarted the test. Esc during the lockout exited at once. A natural finish showed the same lockout and hint dimming. I also built the web engine to wasm, ran the snapshot test (pass), and drove the built page in Chrome: arrow keys right after a finish were dropped, and at ~700ms one restarted the test. PNG screenshots, a transcript and the browser result JSON are in the evidence directory. I removed the transient web/node_modules, web/wasm and web/dist, and the worktree is clean.
Evidence: Browser lockout timing result
Evidence: Terminal transcript with per-check results
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
✅ **Review** - passed
✅ No issues found.
✅ **Test** - passed
✅ No issues found.
cargo build(debug thokr binary, nix-provided cargo 1.99, target dir in /tmp)pty + pyte driver/tmp/nm-drive/scen.py: ranthokr -d -p <long prompt>at 80x24. Typed 100 correct chars, then a wrong key. Captured the frame before the fatal key and the death frames at ~40ms, ~250ms, ~300ms (after r/n) and ~700ms. Compared the row text and the cell styles (fg, dim, reverse, italic)pty driver:thokr -d -p 'the quick brown fox', died, then pressed esc ~30ms later. The process exited within 400mspty driver:thokr -p abnatural finish. Pressed n/r at once (ignored, hints dim), checked hints normal at ~700ms, pressed n after the lockout (new test)built the web engine for wasm32-wasip1 (rustup toolchain in /tmp) and rannpm run build:app, thennode --test test/snapshots.test.mjs(engine and chart.ts against the ui.rs insta snapshots: 10/10 pass)chrome-devtools-axi against the built page served locally: typed the hero prompt, then ArrowLeft/ArrowRight ~30ms after the finish (ignored, results stay), then ArrowLeft at ~700ms (restarts the same prompt)cargo test(crate unit tests incl. death, lockout and next_tick tests: 88 pass, 1 ignored)grep -rn flash src web/engine/src web/src(no flash code left, only words in a word list)✅ **Document** - passed
✅ No issues found.
src/ui.rs- Could not runcargo fmt --all -- --checkorcargo clippy --all-features -- -D warnings(the checks in .github/workflows/build.yml) becausecargois not on PATH here, and web/node_modules is missing sonpm run typecheckcould not run either. Formatting and clippy status of src/ui.rs, src/thok.rs, src/main.rs and web/engine/src/lib.rs is unverified locally. CI runs these checks.✅ **Push** - passed
✅ No issues found.