Hebrew 10-finger typing trainer - #4
Open
erimeilis wants to merge 42 commits into
Open
Conversation
Track design plans in git (un-ignore docs/plans/) and add the design spec for the Hebrew 10-finger typing trainer feature. Also tracks the previously-ignored virtual-typing design docs. Key decisions captured in the spec: - Dedicated Trainer mode; Hebrew (Israeli standard) layout first - Real Hebrew text is primary (no generated pseudo-words); adaptivity via weak-key corpus selection - Staged home-row-first ladder + adaptive weak-key targeting - Switchable guidance modes to wean off the visible keyboard - Hebrew accuracy model: stop-on-error, whole-word metric, sofit and confusable-pair curriculum, meaning-aware error feedback - Both DOM and Rust-tap keystroke capture behind one KeySource setting
- Bump typescript devDependency to ^7.0.2 (latest stable, native compiler). - Add src/vite-env.d.ts (vite/client reference) so side-effect CSS imports type-check under TS 7's stricter module handling (TS2882). - Fix stale Keyboard.test.tsx assertion: the component listens to 'keyboard-state', not the old 'key-pressed'/'key-released'. Verified: tsc --noEmit clean, 11/11 vitest pass, npm run build succeeds.
29 bite-sized TDD tasks across 4 build-order phases (foundation, pedagogy core, real text + feedback, delight) with exact file paths, full code, and test-first steps.
Implements KeySource interface to capture physical key events from DOM. Emits KeyEvent objects with code, timestamp, and down/up state. Includes Vitest test coverage for event emission and listener lifecycle.
The existing "unlistens on stop()" test awaited listen()'s promise
before calling stop(), so it never exercised the guard branch
(`if (this.stopped) { un(); return; }`) inside the .then() callback.
Add a test that calls stop() synchronously right after start(), with
no await in between, then flushes microtasks to prove the race-guard
path is what fires unlisten.
- keyboard_listener: emit an unthrottled "key-event" ({ code, down }) on
every physical key press/release for TauriTapKeySource, independent of
the existing 16ms-throttled "keyboard-state" emit.
- lib.rs: add set_trainer_mode(active) command, registered in the invoke
handler. Round-trips the main window through tauri-nspanel's
Panel::to_window()/WebviewWindowExt::to_panel() to swap it between the
non-activating KeyboardPanel overlay and a regular focusable window,
since can_become_key_window is baked into the panel's Objective-C class
at compile time and has no runtime setter.
…r set_trainer_mode
… keep suite exit 0
TrainerMode is a skeleton container: invokes set_trainer_mode(true/false) on mount/unmount, renders an Exit button, a placeholder panel (PracticePanel lands in Task 21), and the reused Keyboard. App gains isTraining state, an early return (before the collapsed/overlay returns) that swaps to TrainerMode, and a keyboard-icon toggle button in the window-controls bar.
…ord) # user-authorized: approved SDD plan execution
# user-authorized: approved SDD plan execution
…/onComplete to avoid stale closures # user-authorized: approved SDD plan execution
…oesn't leak to next position # user-authorized: approved SDD plan execution
Implement PracticePanel component rendering Hebrew target text right-to-left with per-character status classes (char-correct, char-error, char-current, char-pending). Add trainer.css with styling for practice text and character states. Includes Vitest component test. # user-authorized: approved SDD plan execution
…olish from final review
…dback - Entry: blue trainer dot in the overlay control bar + a 'Typing Trainer' menu-bar/tray item (emits toggle-trainer). - Common window: trainer mode makes the window focusable/activating with a Dock icon and drops always-on-top; custom in-window title strip with macOS-style traffic lights (native decorations throw NSException here) — red=exit, yellow=hide, green=zoom. - Capture: default to the global tap (focus-independent); count keystrokes only when the window is focused AND Hebrew input is active (banner otherwise). - Placement: shows the keyboard, stop-on-error, and a Skip button so beginners are not trapped. - Feedback: red fault marking on the current char + live correct/error tally on placement and practice screens. - Layout: centered keyboard + text, right-sized trainer window, clean heatmap (untouched keys neutral) with finger colour only on the next key.
Move the flat src/trainer files into components/ (UI + trainer.css), hooks/ (useTypingSession), engine/ (adaptive logic: confidence, gating, scoring, errors, curriculum, textSelection, keyboardView, placement), gamification/ (ghost, streak, stars, chart), and persistence/ (storage, useTrainerState). data/ and keySource/ unchanged; TrainerMode + types stay at root as the entry point and shared types. Pure git-mv moves + relative-import fixes, no behavior change: tsc clean, 124 tests pass, build succeeds.
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.
Hebrew 10-finger typing trainer
Adds a dedicated Trainer mode to the always-on-top keyboard overlay that teaches and improves Hebrew touch typing (Israeli standard layout), from beginner to fast. Built spec-first, then implemented as 29 TDD tasks with per-task review and a final whole-branch review.
Design + plan:
docs/plans/2026-07-15-hebrew-typing-trainer-design.md,docs/plans/2026-07-16-hebrew-typing-trainer-plan.md.What it does
Architecture
src/trainer/*: selection, scoring, confidence, gating, curriculum, errors, ghost, streak, stars, chart) with thin React UI; driven by a swappableKeySource.Keyboard/Key/keyMapping(single source of truth).set_trainer_mode(focusable-window toggle, idempotent revert, main-thread dispatched) + an unthrottledkey-event. The original overlay behaviour is unchanged when not training.TrainerStoreinterface (settings/progress/stats/streak/history/ghosts).Also included
src/vite-env.d.ts; fixes a staleKeyboard.test.tsxassertion).docs/plans/un-ignored so design/plan docs are version-controlled.Verification
npm test),tsc --noEmitclean,npm run buildsucceeds, and the app launches cleanly (NSPanel + CGEventTap + tray intact).Before merge — one manual check
Non-blocking follow-ups