diff --git a/README.md b/README.md index 2a27916..9d2e143 100644 --- a/README.md +++ b/README.md @@ -1492,6 +1492,14 @@ Things I chose while building, with the reasoning: into view as you type. No strings, so no i18n; the additive change sits on top of the merged scene-heat rework unchanged. +100. **The review breakdown carries each deck's own total.** The follow-up to 99: "bro its not + possible, I only have 2 decks" — the screenshot showed three deck cards (one clipped at the + window edge) and a breakdown of 15 + 13 + 6 = 34, so the count was right and the *number of + decks* was the misread. To make that checkable inline, each entry now carries the deck's + activity total next to its due count — "Due by deck: Renesanční… · 15 of 15 · Humanismus… · + 13 of 15 · Renesance… · 6 of 13" — so the arithmetic (34 due out of 43 activities) is + verifiable without opening a single deck. review-test pins the format. + 99. **The smart review names its decks.** "It contains mistakes I either did more than once or from decks that I've removed — there's no way there's 34 to repeat with 2 decks." The count itself was honest: `dueItems`/`mistakeItems` only resolve live (deck, activity) pairs, so a diff --git a/components/LibraryScreen.tsx b/components/LibraryScreen.tsx index a935926..5dae38e 100644 --- a/components/LibraryScreen.tsx +++ b/components/LibraryScreen.tsx @@ -680,13 +680,17 @@ export function LibraryScreen({ initialTab = "decks" }: { initialTab?: "decks" | ); } -/** "Sky deck · 17 · Biology · 14 (+2 more)" — capped so the line stays short. */ +/** "Sky deck · 17 of 17 · Biology · 14 of 15 (+2 more)" — the deck's own + * activity total rides along, so a count that mixes decks can be checked + * against the decks instead of looking impossible. Capped at three decks. */ function deckBreakdown( items: ReviewItem[], t: (key: string, vars?: Record) => string, ): string { const groups = groupByDeck(items); - const shown = groups.slice(0, 3).map((group) => `${group.label} · ${group.count}`); + const shown = groups + .slice(0, 3) + .map((group) => `${group.label} · ${t("review.dueOfTotal", { due: group.count, total: group.total })}`); const rest = groups.length - shown.length; if (rest > 0) shown.push(t("review.moreDecks", { n: rest })); return shown.join(" · "); diff --git a/lib/i18n-dict.ts b/lib/i18n-dict.ts index a236831..6556d83 100644 --- a/lib/i18n-dict.ts +++ b/lib/i18n-dict.ts @@ -846,6 +846,7 @@ const en: Record = { "review.due.few": "{n} due", "review.due.many": "{n} due", "review.dueByDeck": "Due by deck: {list}", + "review.dueOfTotal": "{due} of {total}", "review.mistakesByDeck": "Mistakes by deck: {list}", "review.moreDecks.one": "+{n} more deck", "review.moreDecks.few": "+{n} more decks", @@ -1852,6 +1853,7 @@ const cs: Record = { "review.due.few": "{n} k opakování", "review.due.many": "{n} k opakování", "review.dueByDeck": "K opakování podle sady: {list}", + "review.dueOfTotal": "{due} z {total}", "review.mistakesByDeck": "Chyby podle sady: {list}", "review.moreDecks.one": "+{n} další sada", "review.moreDecks.few": "+{n} další sady", diff --git a/lib/learning.ts b/lib/learning.ts index 21995d3..0ff0ce2 100644 --- a/lib/learning.ts +++ b/lib/learning.ts @@ -77,11 +77,13 @@ export function mistakeCount(answers: AnswerRecord[], deckId?: string): number { * ("34 due" with two decks on screen) is self-explanatory instead of looking * like the same mistake twice or an item from a deck that was deleted. */ -export function groupByDeck(items: ReviewItem[]): { label: string; count: number }[] { - const groups = new Map(); +/** `total` is the deck's activity count, so "34 due" can be checked against + * the decks themselves ("15 of 15 · 13 of 15 · 6 of 13"). */ +export function groupByDeck(items: ReviewItem[]): { label: string; count: number; total: number }[] { + const groups = new Map(); for (const item of items) { const key = item.deck.id; - const group = groups.get(key) ?? { label: item.deck.title, count: 0 }; + const group = groups.get(key) ?? { label: item.deck.title, count: 0, total: item.deck.activities.length }; group.count += 1; groups.set(key, group); } diff --git a/package.json b/package.json index 7cbade6..bc44dd4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "freezmo", - "version": "0.6.8", + "version": "0.6.9", "private": true, "license": "GPL-3.0-only", "scripts": { diff --git a/public/sw.js b/public/sw.js index 36621e1..6d0f021 100644 --- a/public/sw.js +++ b/public/sw.js @@ -9,7 +9,7 @@ * * Bumping CACHE_VERSION is how a new deploy invalidates old assets. */ -const CACHE_VERSION = "freezmo-v90"; +const CACHE_VERSION = "freezmo-v91"; const SHELL_CACHE = `${CACHE_VERSION}-shell`; const ASSET_CACHE = `${CACHE_VERSION}-assets`; diff --git a/tests/review-test.mjs b/tests/review-test.mjs index 3c63728..11e645c 100644 --- a/tests/review-test.mjs +++ b/tests/review-test.mjs @@ -189,7 +189,7 @@ async function makeReviewPage(locale = "en") { ); check( "review: the card breaks the count down by deck", - breakdown === "Due by deck: Sky deck · 2 · Twin deck · 2", + breakdown === "Due by deck: Sky deck · 2 of 2 · Twin deck · 2 of 2", breakdown, );