- Removed the omitProviderInModelName key from PreferenceKeys and its associated logic throughout the codebase. - Updated SettingsService and AppSettings to eliminate references to the omitted provider functionality. - Cleaned up related localization strings in multiple languages to reflect the removal of this feature. - Enhanced code clarity and maintainability by streamlining settings management.
211 lines
6.3 KiB
Dart
211 lines
6.3 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
import '../utils/debug_logger.dart';
|
|
import 'hive_boxes.dart';
|
|
import 'persistence_keys.dart';
|
|
|
|
/// Handles one-time migration from SharedPreferences to Hive-backed storage.
|
|
class PersistenceMigrator {
|
|
PersistenceMigrator({required HiveBoxes hiveBoxes}) : _boxes = hiveBoxes;
|
|
|
|
static const int _targetVersion = 1;
|
|
|
|
final HiveBoxes _boxes;
|
|
|
|
Future<void> migrateIfNeeded() async {
|
|
final currentVersion =
|
|
_boxes.metadata.get(HiveStoreKeys.migrationVersion) as int?;
|
|
if (currentVersion != null && currentVersion >= _targetVersion) {
|
|
return;
|
|
}
|
|
|
|
DebugLogger.log(
|
|
'Starting SharedPreferences → Hive migration',
|
|
scope: 'persistence/migration',
|
|
);
|
|
|
|
try {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
await _migratePreferences(prefs);
|
|
await _migrateCaches(prefs);
|
|
await _migrateAttachmentQueue(prefs);
|
|
await _migrateTaskQueue(prefs);
|
|
|
|
await _boxes.metadata.put(HiveStoreKeys.migrationVersion, _targetVersion);
|
|
|
|
await _cleanupLegacyKeys(prefs);
|
|
DebugLogger.log('Migration completed', scope: 'persistence/migration');
|
|
} catch (error, stack) {
|
|
DebugLogger.error(
|
|
'Migration failed',
|
|
scope: 'persistence/migration',
|
|
error: error,
|
|
stackTrace: stack,
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> _migratePreferences(SharedPreferences prefs) async {
|
|
final updates = <String, Object?>{};
|
|
|
|
void copyBool(String key) {
|
|
final value = prefs.getBool(key);
|
|
if (value != null) updates[key] = value;
|
|
}
|
|
|
|
void copyDouble(String key) {
|
|
final value = prefs.getDouble(key);
|
|
if (value != null) updates[key] = value;
|
|
}
|
|
|
|
void copyString(String key) {
|
|
final value = prefs.getString(key);
|
|
if (value != null && value.isNotEmpty) updates[key] = value;
|
|
}
|
|
|
|
void copyStringList(String key) {
|
|
final value = prefs.getStringList(key);
|
|
if (value != null && value.isNotEmpty) {
|
|
updates[key] = List<String>.from(value);
|
|
}
|
|
}
|
|
|
|
copyBool(PreferenceKeys.reduceMotion);
|
|
copyDouble(PreferenceKeys.animationSpeed);
|
|
copyBool(PreferenceKeys.hapticFeedback);
|
|
copyBool(PreferenceKeys.highContrast);
|
|
copyBool(PreferenceKeys.largeText);
|
|
copyBool(PreferenceKeys.darkMode);
|
|
copyString(PreferenceKeys.defaultModel);
|
|
copyString(PreferenceKeys.voiceLocaleId);
|
|
copyBool(PreferenceKeys.voiceHoldToTalk);
|
|
copyBool(PreferenceKeys.voiceAutoSendFinal);
|
|
copyString(PreferenceKeys.socketTransportMode);
|
|
copyStringList(PreferenceKeys.quickPills);
|
|
copyBool(PreferenceKeys.sendOnEnterKey);
|
|
copyBool(PreferenceKeys.rememberCredentials);
|
|
copyString(PreferenceKeys.activeServerId);
|
|
copyString(PreferenceKeys.themeMode);
|
|
copyString(PreferenceKeys.themePalette);
|
|
copyString(PreferenceKeys.localeCode);
|
|
copyBool(PreferenceKeys.onboardingSeen);
|
|
copyBool(PreferenceKeys.reviewerMode);
|
|
|
|
if (updates.isNotEmpty) {
|
|
await _boxes.preferences.putAll(updates);
|
|
}
|
|
}
|
|
|
|
Future<void> _migrateCaches(SharedPreferences prefs) async {
|
|
final jsonString = prefs.getString(HiveStoreKeys.localConversations);
|
|
if (jsonString == null || jsonString.isEmpty) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
final decoded = jsonDecode(jsonString);
|
|
if (decoded is List) {
|
|
final list = decoded
|
|
.map((entry) => Map<String, dynamic>.from(entry as Map))
|
|
.toList(growable: false);
|
|
await _boxes.caches.put(HiveStoreKeys.localConversations, list);
|
|
}
|
|
} catch (error, stack) {
|
|
DebugLogger.error(
|
|
'Failed to migrate local conversations',
|
|
scope: 'persistence/migration',
|
|
error: error,
|
|
stackTrace: stack,
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> _migrateAttachmentQueue(SharedPreferences prefs) async {
|
|
final jsonString = prefs.getString(
|
|
LegacyPreferenceKeys.attachmentUploadQueue,
|
|
);
|
|
if (jsonString == null || jsonString.isEmpty) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
final decoded = jsonDecode(jsonString);
|
|
if (decoded is List) {
|
|
final list = decoded
|
|
.map((entry) => Map<String, dynamic>.from(entry as Map))
|
|
.toList(growable: false);
|
|
await _boxes.attachmentQueue.put(
|
|
HiveStoreKeys.attachmentQueueEntries,
|
|
list,
|
|
);
|
|
}
|
|
} catch (error, stack) {
|
|
DebugLogger.error(
|
|
'Failed to migrate attachment queue',
|
|
scope: 'persistence/migration',
|
|
error: error,
|
|
stackTrace: stack,
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> _migrateTaskQueue(SharedPreferences prefs) async {
|
|
final jsonString = prefs.getString(LegacyPreferenceKeys.taskQueue);
|
|
if (jsonString == null || jsonString.isEmpty) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
final decoded = jsonDecode(jsonString);
|
|
if (decoded is List) {
|
|
final list = decoded
|
|
.map((entry) => Map<String, dynamic>.from(entry as Map))
|
|
.toList(growable: false);
|
|
await _boxes.caches.put(HiveStoreKeys.taskQueue, list);
|
|
}
|
|
} catch (error, stack) {
|
|
DebugLogger.error(
|
|
'Failed to migrate outbound task queue',
|
|
scope: 'persistence/migration',
|
|
error: error,
|
|
stackTrace: stack,
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> _cleanupLegacyKeys(SharedPreferences prefs) async {
|
|
final keysToRemove = <String>[
|
|
PreferenceKeys.reduceMotion,
|
|
PreferenceKeys.animationSpeed,
|
|
PreferenceKeys.hapticFeedback,
|
|
PreferenceKeys.highContrast,
|
|
PreferenceKeys.largeText,
|
|
PreferenceKeys.darkMode,
|
|
PreferenceKeys.defaultModel,
|
|
PreferenceKeys.voiceLocaleId,
|
|
PreferenceKeys.voiceHoldToTalk,
|
|
PreferenceKeys.voiceAutoSendFinal,
|
|
PreferenceKeys.socketTransportMode,
|
|
PreferenceKeys.quickPills,
|
|
PreferenceKeys.sendOnEnterKey,
|
|
PreferenceKeys.rememberCredentials,
|
|
PreferenceKeys.activeServerId,
|
|
PreferenceKeys.themeMode,
|
|
PreferenceKeys.themePalette,
|
|
PreferenceKeys.localeCode,
|
|
PreferenceKeys.onboardingSeen,
|
|
PreferenceKeys.reviewerMode,
|
|
HiveStoreKeys.localConversations,
|
|
HiveStoreKeys.attachmentQueueEntries,
|
|
LegacyPreferenceKeys.attachmentUploadQueue,
|
|
LegacyPreferenceKeys.taskQueue,
|
|
];
|
|
|
|
for (final key in keysToRemove) {
|
|
await prefs.remove(key);
|
|
}
|
|
}
|
|
}
|