Review breakdown: show each deck's own activity total
Follow-up to the smart-review breakdown: "I only have 2 decks" turned out to
be three deck cards (one clipped at the window edge) and 15 + 13 + 6 = 34
due. The line now carries each deck's activity total next to its due count -
"Due by deck: Sky deck - 15 of 15 - Humanismus - 13 of 15 - ... - 6 of 13" -
so the arithmetic is checkable inline without opening a deck.
groupByDeck returns {label, count, total}; new i18n key review.dueOfTotal
(en + cs). review-test pins the format. Version 0.6.9, SW v91.
This commit is contained in:
parent
1e8606a95b
commit
71c56ad06f
7 changed files with 24 additions and 8 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 | number>) => 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(" · ");
|
||||
|
|
|
|||
|
|
@ -846,6 +846,7 @@ const en: Record<string, string> = {
|
|||
"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<string, string> = {
|
|||
"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",
|
||||
|
|
|
|||
|
|
@ -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<string, { label: string; count: number }>();
|
||||
/** `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<string, { label: string; count: number; total: number }>();
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "freezmo",
|
||||
"version": "0.6.8",
|
||||
"version": "0.6.9",
|
||||
"private": true,
|
||||
"license": "GPL-3.0-only",
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -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`;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue