This commit is contained in:
gitea
2026-01-02 19:56:50 +01:00
parent 9f06568eab
commit 68af4bf379
8 changed files with 341 additions and 76 deletions
+34 -16
View File
@@ -14,17 +14,25 @@ class DeckStorage {
static const String _deckIdsKey = 'deck_ids';
bool _initialized = false;
SharedPreferences? _prefs;
final Future<void> _initFuture;
Future<void>? _initFuture;
DeckStorage._internal() : _initFuture = SharedPreferences.getInstance().then((prefs) {
_instance._prefs = prefs;
_instance._initialized = true;
});
DeckStorage._internal();
/// Lazy initialization of SharedPreferences
Future<void> _initSharedPreferences() async {
if (_initFuture == null) {
_initFuture = SharedPreferences.getInstance().then((prefs) {
_instance._prefs = prefs;
_instance._initialized = true;
});
}
await _initFuture;
}
/// Initialize storage with default deck if empty
Future<void> initialize() async {
if (_initialized) return;
await _initFuture;
await _initSharedPreferences();
// Load existing decks
final deckIds = _prefs!.getStringList(_deckIdsKey) ?? [];
@@ -39,7 +47,7 @@ class DeckStorage {
/// Ensure storage is initialized
Future<void> _ensureInitialized() async {
if (!_initialized) {
await _initFuture;
await _initSharedPreferences();
await initialize();
}
}
@@ -75,10 +83,10 @@ class DeckStorage {
'attemptHistory': deck.attemptHistory.map((entry) => {
'timestamp': entry.timestamp,
'totalQuestions': entry.totalQuestions,
'correctAnswers': entry.correctAnswers,
'incorrectAnswers': entry.incorrectAnswers,
'skippedAnswers': entry.skippedAnswers,
'timeSpentSeconds': entry.timeSpentSeconds,
'correctCount': entry.correctCount,
'percentageCorrect': entry.percentageCorrect,
'timeSpent': entry.timeSpent,
'unknownPercentage': entry.unknownPercentage,
}).toList(),
'incompleteAttempt': deck.incompleteAttempt != null ? {
'attemptId': deck.incompleteAttempt!.attemptId,
@@ -145,13 +153,23 @@ class DeckStorage {
final historyJson = json['attemptHistory'] as List<dynamic>? ?? [];
final attemptHistory = historyJson.map((entryJson) {
final entryMap = entryJson as Map<String, dynamic>;
// Support both old and new field names for backward compatibility
final correctCount = entryMap['correctCount'] as int? ??
entryMap['correctAnswers'] as int? ?? 0;
final totalQuestions = entryMap['totalQuestions'] as int? ?? 0;
final timeSpent = entryMap['timeSpent'] as int? ??
(entryMap['timeSpentSeconds'] as int? ?? 0) * 1000; // Convert seconds to milliseconds
// Calculate percentageCorrect if not present
final percentageCorrect = entryMap['percentageCorrect'] as double? ??
(totalQuestions > 0 ? (correctCount / totalQuestions * 100) : 0.0);
final unknownPercentage = entryMap['unknownPercentage'] as double? ?? 0.0;
return AttemptHistoryEntry(
timestamp: entryMap['timestamp'] as int? ?? 0,
totalQuestions: entryMap['totalQuestions'] as int? ?? 0,
correctAnswers: entryMap['correctAnswers'] as int? ?? 0,
incorrectAnswers: entryMap['incorrectAnswers'] as int? ?? 0,
skippedAnswers: entryMap['skippedAnswers'] as int? ?? 0,
timeSpentSeconds: entryMap['timeSpentSeconds'] as int?,
totalQuestions: totalQuestions,
correctCount: correctCount,
percentageCorrect: percentageCorrect,
timeSpent: timeSpent,
unknownPercentage: unknownPercentage,
);
}).toList();