88 lines
2.6 KiB
Dart
88 lines
2.6 KiB
Dart
|
|
import 'dart:convert';
|
||
|
|
|
||
|
|
import 'package:flutter/foundation.dart';
|
||
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
||
|
|
|
||
|
|
import '../../shared/utils/lru_eviction.dart';
|
||
|
|
|
||
|
|
mixin SettingsPersistence {
|
||
|
|
SharedPreferences? _prefs;
|
||
|
|
|
||
|
|
Future<SharedPreferences> getPrefs() async {
|
||
|
|
return _prefs ??= await SharedPreferences.getInstance();
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<bool> persistField(String key, dynamic value) async {
|
||
|
|
try {
|
||
|
|
final p = await getPrefs();
|
||
|
|
if (value == null) return p.remove(key);
|
||
|
|
if (value is bool) return p.setBool(key, value);
|
||
|
|
if (value is int) return p.setInt(key, value);
|
||
|
|
if (value is double) return p.setDouble(key, value);
|
||
|
|
if (value is String) return p.setString(key, value);
|
||
|
|
if (value is List<String>) return p.setStringList(key, value);
|
||
|
|
return false;
|
||
|
|
} catch (e) {
|
||
|
|
debugPrint('[SettingsPersistence] Failed to persist $key: $e');
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<bool> persistFields(Map<String, dynamic> fields) async {
|
||
|
|
try {
|
||
|
|
final p = await getPrefs();
|
||
|
|
final futures = <Future<bool>>[];
|
||
|
|
for (final entry in fields.entries) {
|
||
|
|
final key = entry.key;
|
||
|
|
final value = entry.value;
|
||
|
|
if (value == null) {
|
||
|
|
futures.add(p.remove(key));
|
||
|
|
} else if (value is bool) {
|
||
|
|
futures.add(p.setBool(key, value));
|
||
|
|
} else if (value is int) {
|
||
|
|
futures.add(p.setInt(key, value));
|
||
|
|
} else if (value is double) {
|
||
|
|
futures.add(p.setDouble(key, value));
|
||
|
|
} else if (value is String) {
|
||
|
|
futures.add(p.setString(key, value));
|
||
|
|
} else if (value is List<String>) {
|
||
|
|
futures.add(p.setStringList(key, value));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
await Future.wait(futures);
|
||
|
|
return true;
|
||
|
|
} catch (e) {
|
||
|
|
debugPrint('[SettingsPersistence] Failed to persist fields: $e');
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
Future<void> putRemembered(
|
||
|
|
String prefsKey,
|
||
|
|
String entryKey,
|
||
|
|
Map<String, dynamic> entryJson,
|
||
|
|
int maxEntries,
|
||
|
|
) async {
|
||
|
|
final p = await getPrefs();
|
||
|
|
final raw = p.getString(prefsKey);
|
||
|
|
final map = raw != null
|
||
|
|
? (jsonDecode(raw) as Map<String, dynamic>)
|
||
|
|
: <String, dynamic>{};
|
||
|
|
map[entryKey] = entryJson;
|
||
|
|
evictOldestEntries(map, maxEntries);
|
||
|
|
await p.setString(prefsKey, jsonEncode(map));
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
Future<Map<String, dynamic>?> readRemembered(
|
||
|
|
String prefsKey,
|
||
|
|
String entryKey,
|
||
|
|
) async {
|
||
|
|
final raw = (await getPrefs()).getString(prefsKey);
|
||
|
|
if (raw == null) return null;
|
||
|
|
final entry = (jsonDecode(raw) as Map<String, dynamic>)[entryKey];
|
||
|
|
return entry is Map<String, dynamic> ? entry : null;
|
||
|
|
}
|
||
|
|
}
|