diff --git a/src/App.jsx b/src/App.jsx index 588178f..87ccfd3 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -184,6 +184,7 @@ export default function App() { const [res, setRes] = useState([]); const [chart, setChart] = useState(false); const [rule, setRule] = useState(false); + const [pickPrep, setPickPrep] = useState(null); const [learnStep, setLearnStep] = useState(0); const [st, setSt] = useState({sc:{},tc:0,ta:0,streak:0,ld:null}); const [access, setAccess] = useState(null); @@ -239,7 +240,7 @@ export default function App() { const lvObj = LEVELS.find(l => l.id === id); if (lvObj?.tab) setTab(lvObj.tab); sessionRef.current = createSession(id); - setLv(id); setRes([]); setInp(''); setRev(false); setQ(sessionRef.current.next()); setScr('practice'); + setLv(id); setRes([]); setInp(''); setRev(false); setPickPrep(null); setQ(sessionRef.current.next()); setScr('practice'); }; const openCheckout = plan => { @@ -257,7 +258,9 @@ export default function App() { const doSubmit = useCallback((overrideInput) => { const userAns = (overrideInput ?? inp).trim(); if (!userAns) { setShake(true); setTimeout(()=>setShake(false),400); return; } - const correct = userAns.toLowerCase() === q.ans.toLowerCase(); + // Two-part answers (contractions) grade against "prep art", not the form. + const target = q.answerKey ?? q.ans; + const correct = userAns.toLowerCase() === target.toLowerCase(); if (overrideInput !== undefined) setInp(overrideInput); // Dismiss mobile keyboard so feedback is visible try { iref.current?.blur(); } catch(e){} @@ -274,7 +277,7 @@ export default function App() { const doNext = useCallback(() => { if (res.length >= ROUND) { setScr('summary'); return; } - setInp(''); setRev(false); setOk(false); + setInp(''); setRev(false); setOk(false); setPickPrep(null); if (!sessionRef.current) sessionRef.current = createSession(lv); setQ(sessionRef.current.next()); }, [res, lv]); @@ -288,6 +291,17 @@ export default function App() { if (chart) { if (e.key === 'Escape') setChart(false); return; } if (scr === 'summary' && e.key === 'Enter') { e.preventDefault(); summaryRef.current?.(); return; } if (scr !== 'practice') return; + if (!rev && q?.type === 'contraction') { + const cloud = pickPrep === null ? q.prepChoices : q.artChoices; + const idx = ['1','2','3','4','5','6'].indexOf(e.key); + if (idx >= 0 && cloud[idx]) { + e.preventDefault(); + if (pickPrep === null) setPickPrep(cloud[idx]); + else submitRef.current(`${pickPrep} ${cloud[idx]}`); + return; + } + if (e.key === 'Backspace' && pickPrep !== null) { e.preventDefault(); setPickPrep(null); return; } + } if (!rev && q?.choices) { const idx = ['1','2','3','4'].indexOf(e.key); if (idx >= 0 && q.choices[idx]) { e.preventDefault(); submitRef.current(q.choices[idx]); return; } @@ -691,18 +705,47 @@ export default function App() { )} - {/* PRACTICE: contractions */} + {/* PRACTICE: contractions — shown fused, taken apart in two taps */} {scr === 'practice' && q?.type === 'contraction' && ( -