Skip to content

Commit fff660f

Browse files
authored
Merge pull request #2 from crizmo/dev
v1.1.0 New Features
2 parents 5c5b266 + c60469e commit fff660f

File tree

2 files changed

+75
-2
lines changed

2 files changed

+75
-2
lines changed

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ KAnki is a spaced repetition flashcard application designed specifically for jai
2020
- **Error review mode**: Review cards you answered incorrectly right after completing a session
2121
- **Centralized configuration**: Easy customization through a single configuration file
2222
- **E-ink optimized UI**: Fixed element heights and visibility management to minimize screen refreshes
23+
- **Data persistence**: All study progress and card statistics are automatically saved between sessions
2324

2425
## Technical Limitations
2526

@@ -111,6 +112,20 @@ For languages with different writing systems, use the `reading` property:
111112
{"front": "こんにちは", "reading": "konnichiwa", "back": "Hello", "notes": "Greeting"}
112113
```
113114

115+
## Data Storage
116+
117+
KAnki saves your progress and card statistics using the Kindle's localStorage feature. All your data is stored locally on your device at:
118+
119+
```
120+
/Kindle/.active_content_sandbox/kanki/resource/LocalStorage/file__0.localstorage
121+
```
122+
123+
If you ever want to reset all progress or encounter issues with saved data, you can:
124+
125+
1. Delete this file to completely reset the application data
126+
2. Use the "Reset Progress" button within the app to only reset card progress while keeping your deck intact
127+
3. Use the "Reset All" button to return to the default deck and clear all progress
128+
114129
## Development
115130

116131
### Project Structure

kanki/main.js

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,37 @@ function createDefaultDeck() {
143143
return deck;
144144
}
145145

146+
// Save deck to localStorage
147+
function saveDeck() {
148+
if (deck) {
149+
try {
150+
localStorage.setItem('kanki_deck', JSON.stringify(deck));
151+
log("Deck saved to localStorage");
152+
} catch (e) {
153+
log("Error saving deck: " + e.message);
154+
}
155+
}
156+
}
157+
158+
// Load deck from localStorage or create a new one if none exists
159+
function loadDeck() {
160+
try {
161+
var savedDeck = localStorage.getItem('kanki_deck');
162+
if (savedDeck) {
163+
deck = JSON.parse(savedDeck);
164+
log("Loaded saved deck with " + deck.cards.length + " cards");
165+
return true;
166+
}
167+
} catch (e) {
168+
log("Error loading deck: " + e.message);
169+
}
170+
171+
// If no saved deck or error, create a new one
172+
deck = createDefaultDeck();
173+
log("Created new default deck");
174+
return false;
175+
}
176+
146177
// Update status message for notifications (not confirmations)
147178
function updateStatusMessage(message) {
148179
var statusElement = document.getElementById("statusMessage");
@@ -225,6 +256,8 @@ function calculateNextReview(card, wasCorrect) {
225256
card.nextReview = now + (10 * 60 * 1000); // 10 minutes
226257
}
227258

259+
saveDeck();
260+
228261
return card;
229262
}
230263

@@ -358,6 +391,8 @@ function displayCurrentCard(showAnswer) {
358391
if (!showAnswer) {
359392
card.timesViewed = (card.timesViewed || 0) + 1;
360393
card.lastViewed = new Date().getTime();
394+
// Save view statistics
395+
saveDeck();
361396
}
362397

363398
updateCardStats(card);
@@ -454,6 +489,9 @@ function answerCard(wasCorrect) {
454489

455490
currentCardIndex++;
456491

492+
493+
saveDeck();
494+
457495
// Check if we're done with regular cards and have errors to review
458496
if (!inErrorReviewMode && currentCardIndex % dueCards.length === 0 && incorrectCardsQueue.length > 0) {
459497
showErrorReviewPrompt();
@@ -480,6 +518,8 @@ function handleAnswerWithInterval(difficulty) {
480518

481519
currentCardIndex++;
482520

521+
saveDeck();
522+
483523
// Check if we're done with regular cards and have errors to review
484524
if (currentCardIndex % dueCards.length === 0 && incorrectCardsQueue.length > 0) {
485525
showErrorReviewPrompt();
@@ -505,6 +545,8 @@ function answerErrorCardWithInterval(difficulty) {
505545
// Move to next card
506546
currentCardIndex++;
507547

548+
saveDeck();
549+
508550
if (currentCardIndex >= incorrectCardsQueue.length) {
509551
endErrorReview();
510552
} else {
@@ -518,6 +560,9 @@ function changeLevel(level) {
518560
currentCardIndex = 0; // Reset counter when changing level
519561
updateLevelDisplay();
520562
displayCurrentCard(false);
563+
564+
// Save user preference for level
565+
saveDeck();
521566
}
522567

523568
// Initialize app on page load
@@ -532,8 +577,10 @@ function onPageLoad() {
532577

533578
updateLevelButtons();
534579

535-
deck = createDefaultDeck();
536-
log("Created new default deck");
580+
if (!loadDeck()) {
581+
deck = createDefaultDeck();
582+
log("Created new default deck");
583+
}
537584

538585
updateProgressDisplay();
539586

@@ -616,6 +663,7 @@ function resetProgress() {
616663
inErrorReviewMode = false;
617664

618665
displayCurrentCard(false);
666+
saveDeck();
619667
showToast("Progress has been reset", 2000);
620668
log("Progress reset");
621669
}
@@ -632,6 +680,7 @@ function resetAll() {
632680
isReversedMode = false;
633681

634682
displayCurrentCard(false);
683+
saveDeck();
635684
showToast("All data has been reset", 2000);
636685
log("Complete reset performed");
637686
}
@@ -760,6 +809,7 @@ function endErrorReview() {
760809
currentCardIndex = 0;
761810
displayCurrentCard(false);
762811
}
812+
saveDeck();
763813
}
764814

765815
function handleAnswerCard(wasCorrect) {
@@ -769,6 +819,7 @@ function handleAnswerCard(wasCorrect) {
769819
if (!wasCorrect) {
770820
answerCard(wasCorrect);
771821
}
822+
saveDeck();
772823
}
773824
}
774825

@@ -783,6 +834,7 @@ function toggleStarCurrentCard() {
783834

784835
updateStarButton(card.starred);
785836

837+
saveDeck();
786838
showToast(card.starred ? "Card starred" : "Card unstarred", 1000);
787839
}
788840

@@ -814,6 +866,9 @@ function toggleStarredFilter() {
814866

815867
updateLevelDisplay();
816868
displayCurrentCard(false);
869+
870+
// Save user preference for starred filter
871+
saveDeck();
817872
}
818873

819874
function toggleCardDirection() {
@@ -832,6 +887,9 @@ function toggleCardDirection() {
832887

833888
displayCurrentCard(false);
834889

890+
// Save user preference for card direction
891+
saveDeck();
892+
835893
showToast(isReversedMode ? "Reversed Mode: Native → Target" : "Normal Mode: Target → Native", 2000);
836894
}
837895

0 commit comments

Comments
 (0)