diff --git a/src/routes/(app)/learn/sentence/+page.svelte b/src/routes/(app)/learn/sentence/+page.svelte index 1bb92bb7..242fe6a2 100644 --- a/src/routes/(app)/learn/sentence/+page.svelte +++ b/src/routes/(app)/learn/sentence/+page.svelte @@ -13,21 +13,22 @@ import TrackText from "$lib/charrecorder/TrackText.svelte"; import { browser } from "$app/environment"; - function initialThresholds(): [slow: number, fast: number][] { + function viaLocalStorage(key: string, initial: T) { try { - return JSON.parse(localStorage.getItem("mastery-thresholds") ?? ""); + return JSON.parse(localStorage.getItem(key) ?? ""); } catch { - return [ - [1500, 1050], - [3000, 2500], - [5000, 3500], - [6000, 5000], - ]; + return initial; } } - let masteryThresholds: [slow: number, fast: number][] = - $state(initialThresholds()); + let masteryThresholds: [slow: number, fast: number][] = $state( + viaLocalStorage("mastery-thresholds", [ + [1500, 1050], + [3000, 2500], + [5000, 3500], + [6000, 5000], + ]), + ); let inputSentence = $derived( (browser && $page.url.searchParams.get("sentence")) || "Hello World", @@ -46,6 +47,10 @@ let wpm = $state(0); let chords: InferredChord[] = $state([]); let recorder = $state(new ReplayRecorder()); + let idle = $state(true); + let idleTime = $state(viaLocalStorage("idle-timeout", 100)); + + let idleTimeout: ReturnType | null = null; let cooldown = $state(false); @@ -59,6 +64,10 @@ } }); + $effect(() => { + localStorage.setItem("idle-timeout", idleTime.toString()); + }); + $effect(() => { localStorage.setItem( "mastery-thresholds", @@ -148,7 +157,7 @@ function checkInput() { if (recorder.player.stepper.challenge.length === 0) return; const replay = recorder.finish(false); - const elapsed = replay.finish - replay.start!; + const elapsed = replay.finish - replay.start! - idleTime; if (elapsed < masteryThresholds[level]![0]) { lastWPM = wpm; @@ -157,19 +166,22 @@ wordStats.set(currentWord, prevStats.slice(-10)); } - cooldown = true; - setTimeout(() => { - selectNextWord(); - cooldown = false; - }); + selectNextWord(); } $effect(() => { - if (!cooldown && text && text === currentWord) checkInput(); + if (idle && text && text.trim() === currentWord.trim()) checkInput(); }); function onkey(event: KeyboardEvent) { + if (idleTimeout) { + clearTimeout(idleTimeout); + } + idle = false; recorder.next(event); + idleTimeout = setTimeout(() => { + idle = true; + }, idleTime); } @@ -273,6 +285,7 @@ {#if devTools}
Dev Tools
+ {#each masteryThresholds as _, i} diff --git a/src/routes/(app)/learn/sentence/StatsTable.svelte b/src/routes/(app)/learn/sentence/StatsTable.svelte deleted file mode 100644 index 59d341bd..00000000 --- a/src/routes/(app)/learn/sentence/StatsTable.svelte +++ /dev/null @@ -1,90 +0,0 @@ - - -
-

Stats for Level {level}

- -
- - - - - - - - - - - - - {#each Object.entries(wordStats) as [word, times]} - - - - - - - - - - {/each} - -
WordLast WPMBest WPMAttemptsAverage Time
{word}{getLastWPM(times, word.split(" ").length)}{getBestWPM(times, word.split(" ").length)}{times.length}{calculateAverageTime(times)}
- - -