fix(backup): restore download and metadata provider order

Backups now carry both provider priority lists in the extensions section. Restore applies them after reinstalled extensions are enabled, so the saved order replaces the defaults instead of being reset.
This commit is contained in:
zarzet committed 2026-10-01 23:16:21 +07:00
1 parent 50f21d9c82
commit b487154065
3 files changed
+178 -3

No files matched your search

+11 -3
View File
@@ -618,8 +618,9 @@ class ExtensionNotifier extends Notifier<ExtensionState> {
return keys;
}
/// Builds the extensions section of a backup: the store registry URL plus the
/// installed extensions with their id, version, enabled flag and settings.
/// Builds the extensions section of a backup: the store registry URL, the
/// installed extensions with their id, version, enabled flag and settings,
/// and the download and metadata provider priority order.
/// Secret-flagged settings (tokens, API keys) are only included when
/// [includeSecrets] is true.
Future<Map<String, dynamic>> exportBackup({
@@ -674,7 +675,11 @@ class ExtensionNotifier extends Notifier<ExtensionState> {
});
}
return {'registry_url': registryUrl, 'items': items};
return {
'registry_url': registryUrl,
'items': items,
...providerPriorityBackup(),
};
}
/// Restores extensions from a backup section produced by [exportBackup]:
@@ -782,6 +787,9 @@ class ExtensionNotifier extends Notifier<ExtensionState> {
}
await refreshExtensions();
// Reinstalled and re-enabled extensions now exist, so the saved order can
// be applied in full instead of defaults winning.
await restoreProviderPriorityBackup(data);
return ExtensionRestoreResult(
installed: installedCount,
@@ -339,6 +339,31 @@ extension ExtensionNotifierProviderPriority on ExtensionNotifier {
}
}
/// Priority lists for the extensions section of a backup. Empty lists are
/// omitted so restoring them never replaces a device's own order.
Map<String, dynamic> providerPriorityBackup() => {
if (state.providerPriority.isNotEmpty)
_providerPriorityKey: List<String>.from(state.providerPriority),
if (state.metadataProviderPriority.isNotEmpty)
_metadataProviderPriorityKey: List<String>.from(
state.metadataProviderPriority,
),
};
/// Applies backed-up priority lists. Call after restored extensions are
/// installed: the setters drop IDs that are not available yet, and later
/// installs would otherwise be appended after the defaults.
Future<void> restoreProviderPriorityBackup(Map<String, dynamic> data) async {
final download = _backupProviderIds(data[_providerPriorityKey]);
if (download.isNotEmpty) await setProviderPriority(download);
final metadata = _backupProviderIds(data[_metadataProviderPriorityKey]);
if (metadata.isNotEmpty) await setMetadataProviderPriority(metadata);
}
List<String> _backupProviderIds(Object? raw) => raw is List
? _distinctProviderIds(raw.whereType<String>())
: const <String>[];
Future<void> cleanup() async {
if (_cleanupInFlight) return;
_cleanupInFlight = true;