Skipping a card is not a mistake
Scrolling through a deck without answering recorded a 0% attempt and listed every card under "Missed items" with its answer revealed. Only answered cards count now: the score is correct/answered, the attempt stores the answered count, an empty run records nothing, and the cards scrolled past wait under "Not answered (n)" - listed as prompts with "not counted as mistakes" - and "Answer the rest (n)" starts a catch-up run of just those cards (same restart path as retry-missed, so history and the SRS still see the answers). "Aced all" requires nothing left waiting too. phase2 pins the flow: all-skipped records no attempt and no mistake list; one-of-two reads "You got 1 of 1 right" + "Not answered (1)" with attempts:1, bestScore:100; the catch-up run records the remaining answer. Exam mode keeps its own rule: in a timed exam an unanswered question is a miss. Version 0.6.5, SW v87.
This commit is contained in:
parent
855ce82836
commit
98537cee64
7 changed files with 161 additions and 20 deletions
|
|
@ -120,13 +120,14 @@ export function StudyFeed({ deck }: { deck: Deck }) {
|
|||
if (!finished) return;
|
||||
if (!retryMode && !recordedRef.current) {
|
||||
recordedRef.current = true;
|
||||
const answered = Object.values(results);
|
||||
const correct = queue.filter((activity) => !skipped.includes(activity.id) && results[activity.id]?.correct).length;
|
||||
const attempted = Math.max(0, total - skipped.length);
|
||||
const answered = queue.filter((activity) => !skipped.includes(activity.id) && results[activity.id]);
|
||||
const correct = answered.filter((activity) => results[activity.id]?.correct).length;
|
||||
const attempted = answered.length;
|
||||
const score = attempted > 0 ? (correct / attempted) * 100 : 0;
|
||||
// Only a run with at least one answer counts. Without this, the scroll
|
||||
// anchoring shift when a regenerated deck swaps in could fire a bogus
|
||||
// 0% attempt before the feed had snapped back to the first slide.
|
||||
// 0% attempt before the feed had snapped back to the first slide — and
|
||||
// swiping through a deck without answering is a pass, not a zero.
|
||||
if (answered.length > 0) {
|
||||
recordAttempt(currentDeck.id, { scorePercent: score, correct, total: attempted });
|
||||
setCurrentDeck((prev) => ({
|
||||
|
|
@ -212,13 +213,24 @@ export function StudyFeed({ deck }: { deck: Deck }) {
|
|||
goTo(index + 1);
|
||||
}, [timed, remaining, timedActivity, timedAnswered, handleAnswered, goTo, index, t]);
|
||||
|
||||
/** Answered, but landed wrong. */
|
||||
const missed = useMemo(
|
||||
() => queue.filter((activity) => !skipped.includes(activity.id) && !results[activity.id]?.correct),
|
||||
() =>
|
||||
queue.filter(
|
||||
(activity) => !skipped.includes(activity.id) && results[activity.id] && !results[activity.id]?.correct,
|
||||
),
|
||||
[queue, results, skipped],
|
||||
);
|
||||
|
||||
/** What the results screen counts: reported cards were never attempted. */
|
||||
const attemptedTotal = Math.max(0, total - skipped.length);
|
||||
/** Scrolled past without answering — waiting, not wrong. */
|
||||
const unanswered = useMemo(
|
||||
() => queue.filter((activity) => !skipped.includes(activity.id) && !results[activity.id]),
|
||||
[queue, results, skipped],
|
||||
);
|
||||
|
||||
/** What the results screen counts: only cards that were answered (reported
|
||||
* cards were never attempted, skipped ones are not mistakes). */
|
||||
const attemptedTotal = total - skipped.length - unanswered.length;
|
||||
|
||||
const correctCount = useMemo(
|
||||
() => queue.filter((activity) => !skipped.includes(activity.id) && results[activity.id]?.correct).length,
|
||||
|
|
@ -454,9 +466,11 @@ export function StudyFeed({ deck }: { deck: Deck }) {
|
|||
total={attemptedTotal}
|
||||
correct={correctCount}
|
||||
missed={missed}
|
||||
unanswered={unanswered}
|
||||
results={results}
|
||||
retryMode={retryMode}
|
||||
onRetryMissed={() => restart(missed, true)}
|
||||
onStudyUnanswered={() => restart(unanswered, true)}
|
||||
onRestart={() => restart(withoutReported(currentDeck.id, currentDeck.activities), false)}
|
||||
onRegenerate={regenerate}
|
||||
regenerating={regenerating}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue