/** Tauchgang - the core drill, and the run that counts for the unlock. * * A line of chunks with a moving cursor, the finger hint above it and the keyboard * below. Everything else in the game is a variation on this; this is the one that is * measured. */ import { useEffect } from "react"; import { currentChar } from "../../lib/engine"; import type { RunResult } from "../../lib/grading"; import type { Progress } from "../../lib/progress"; import { say, spellKey } from "../../lib/speech"; import { useRun } from "../../hooks/useRun"; import { HandHint } from "../HandHint"; import { Keyboard } from "../Keyboard"; import { Target } from "../Target"; interface Props { chunks: readonly string[]; text: string; spaceActive: boolean; activeKeys: readonly string[]; progress: Progress; paused: boolean; onFinished: (result: RunResult) => void; } export function TauchgangRun({ chunks, text, spaceActive, activeKeys, progress, paused, onFinished, }: Props) { const { state, daneben } = useRun({ target: text, sound: progress.settings.sound, paused, onFinished, }); const next = currentChar(state); // Say the first key of a line, and any key she gets stuck on. Not every key: a voice // talking over every keystroke is noise, and it would lag behind a good streak. useEffect(() => { if (state.index === 0 && next) say(spellKey(next), progress.settings.speech); }, [state.index, next, progress.settings.speech]); useEffect(() => { if (daneben && next) say(spellKey(next), progress.settings.speech); }, [daneben, next, progress.settings.speech]); return (