From 1c0aedfcad5c032507478033b44a3b278850a374 Mon Sep 17 00:00:00 2001 From: ChristopheCode <135648470+ChristopheCode@users.noreply.github.com> Date: Sun, 21 Jun 2026 19:38:37 +0200 Subject: [PATCH 1/4] Add flashcard progress storage helper --- flashcard-progress.js | 104 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 flashcard-progress.js diff --git a/flashcard-progress.js b/flashcard-progress.js new file mode 100644 index 0000000..b9841b2 --- /dev/null +++ b/flashcard-progress.js @@ -0,0 +1,104 @@ +/* + * Flashcard progress helper. + * Stores local learning progress for irregular verbs without sending data anywhere. + */ +(function () { + const STORAGE_KEY = "casualEnglishFlashcardProgress"; + const REVIEW_DELAYS_DAYS = [0, 1, 3, 7, 14, 30]; + + const readProgress = () => { + try { + const raw = typeof safeGet === "function" + ? safeGet(localStorage, STORAGE_KEY) + : localStorage[STORAGE_KEY]; + const parsed = JSON.parse(raw || "{}"); + + return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {}; + } catch { + return {}; + } + }; + + const writeProgress = progress => { + try { + const value = JSON.stringify(progress); + + if (typeof safeSet === "function") { + safeSet(localStorage, STORAGE_KEY, value); + } else { + localStorage[STORAGE_KEY] = value; + } + } catch {} + }; + + const keyForVerb = verb => [verb.base, verb.past, verb.pp] + .map(value => String(value || "").trim().toLowerCase()) + .join("|"); + + const addDays = (date, days) => { + const nextDate = new Date(date); + nextDate.setDate(nextDate.getDate() + days); + return nextDate; + }; + + const emptyProgress = () => ({ + views: 0, + correct: 0, + wrong: 0, + level: 0, + lastSeen: null, + nextReview: null, + }); + + const recordAnswer = (verb, isCorrect) => { + if (!verb || typeof verb !== "object") return null; + + const progress = readProgress(); + const key = keyForVerb(verb); + const current = { ...emptyProgress(), ...progress[key] }; + const now = new Date(); + + current.views += 1; + current.correct += isCorrect ? 1 : 0; + current.wrong += isCorrect ? 0 : 1; + current.level = isCorrect + ? Math.min(current.level + 1, REVIEW_DELAYS_DAYS.length - 1) + : 0; + current.lastSeen = now.toISOString(); + current.nextReview = addDays(now, REVIEW_DELAYS_DAYS[current.level]).toISOString(); + + progress[key] = current; + writeProgress(progress); + + return current; + }; + + const recordView = verb => { + if (!verb || typeof verb !== "object") return null; + + const progress = readProgress(); + const key = keyForVerb(verb); + const current = { ...emptyProgress(), ...progress[key] }; + + current.views += 1; + current.lastSeen = new Date().toISOString(); + + progress[key] = current; + writeProgress(progress); + + return current; + }; + + const getProgress = verb => { + if (!verb || typeof verb !== "object") return emptyProgress(); + + return { ...emptyProgress(), ...readProgress()[keyForVerb(verb)] }; + }; + + window.FlashcardProgress = { + storageKey: STORAGE_KEY, + getProgress, + recordAnswer, + recordView, + }; +}()); From d9b193f1b4b68ca065fd9628bb62107badac0dee Mon Sep 17 00:00:00 2001 From: ChristopheCode <135648470+ChristopheCode@users.noreply.github.com> Date: Sun, 21 Jun 2026 19:40:31 +0200 Subject: [PATCH 2/4] Load flashcard progress on exercises page --- exercises.html | 1 + 1 file changed, 1 insertion(+) diff --git a/exercises.html b/exercises.html index 2047519..0004241 100644 --- a/exercises.html +++ b/exercises.html @@ -113,6 +113,7 @@