refactor: remove Qobuz from built-in provider registry, add retired provider detection

Empty the builtInProviderRegistry now that all built-in providers are
retired. Introduce isRetiredBuiltInDownloadProvider and
isRetiredBuiltInMetadataProvider to classify deezer/qobuz/tidal/spotify
as retired, replacing ad-hoc string checks. Add Dart-side metadata
provider priority reconciliation that replaces retired providers with
extensions declaring replacesBuiltInProviders. Remove getQobuzMetadata
from native bridges and platform_bridge.dart. Update crowdin.yml with
additional locale mappings.
This commit is contained in:
zarzet
2026-04-18 23:10:00 +07:00
parent 16ce6089fb
commit 8f2ca33e87
8 changed files with 108 additions and 85 deletions
+57 -2
View File
@@ -758,6 +758,7 @@ class ExtensionNotifier extends Notifier<ExtensionState> {
state = state.copyWith(extensions: extensions);
await _reconcileDownloadProviderPriority();
await _reconcileDefaultDownloadService();
await _reconcileMetadataProviderPriority();
_reconcileSearchProvider();
_log.d('Loaded ${extensions.length} extensions');
@@ -866,6 +867,7 @@ class ExtensionNotifier extends Notifier<ExtensionState> {
state = state.copyWith(extensions: extensions);
await _reconcileDownloadProviderPriority();
await _reconcileDefaultDownloadService();
await _reconcileMetadataProviderPriority();
_reconcileSearchProvider();
if (!enabled && ext != null) {
@@ -914,6 +916,28 @@ class ExtensionNotifier extends Notifier<ExtensionState> {
_log.d('Reconciled provider priority after extension update: $sanitized');
}
Future<void> _reconcileMetadataProviderPriority() async {
if (state.metadataProviderPriority.isEmpty) {
return;
}
final replaced = _replaceRetiredBuiltInMetadataProviders(
state.metadataProviderPriority,
);
final sanitized = _sanitizeMetadataProviderPriority(replaced);
if (jsonEncode(sanitized) == jsonEncode(state.metadataProviderPriority)) {
return;
}
final prefs = await SharedPreferences.getInstance();
await prefs.setString(_metadataProviderPriorityKey, jsonEncode(sanitized));
await PlatformBridge.setMetadataProviderPriority(sanitized);
state = state.copyWith(metadataProviderPriority: sanitized);
_log.d(
'Reconciled metadata provider priority after extension update: $sanitized',
);
}
String? _firstEnabledExtensionDownloadProviderId() {
return state.extensions
.where((ext) => ext.enabled && ext.hasDownloadProvider)
@@ -951,6 +975,21 @@ class ExtensionNotifier extends Notifier<ExtensionState> {
.firstOrNull;
}
String? replacedBuiltInMetadataProviderFor(String providerId) {
final normalized = providerId.trim().toLowerCase();
if (normalized.isEmpty) return null;
return state.extensions
.where(
(ext) =>
ext.enabled &&
ext.hasMetadataProvider &&
ext.replacesBuiltInProviders.contains(normalized),
)
.map((ext) => ext.id)
.firstOrNull;
}
bool downloadProviderMatchesBuiltIn(
String providerId,
String builtInProviderId,
@@ -1204,7 +1243,9 @@ class ExtensionNotifier extends Notifier<ExtensionState> {
if (savedJson != null) {
final saved = jsonDecode(savedJson) as List<dynamic>;
priority = _sanitizeMetadataProviderPriority(
saved.map((e) => e as String).toList(),
_replaceRetiredBuiltInMetadataProviders(
saved.map((e) => e as String).toList(),
),
);
_log.d('Loaded metadata provider priority from prefs: $priority');
await prefs.setString(
@@ -1233,7 +1274,9 @@ class ExtensionNotifier extends Notifier<ExtensionState> {
Future<void> setMetadataProviderPriority(List<String> priority) async {
try {
final prefs = await SharedPreferences.getInstance();
final sanitized = _sanitizeMetadataProviderPriority(priority);
final sanitized = _sanitizeMetadataProviderPriority(
_replaceRetiredBuiltInMetadataProviders(priority),
);
await prefs.setString(
_metadataProviderPriorityKey,
jsonEncode(sanitized),
@@ -1294,6 +1337,18 @@ class ExtensionNotifier extends Notifier<ExtensionState> {
];
}
List<String> _replaceRetiredBuiltInMetadataProviders(List<String> input) {
final result = <String>[];
for (final provider in input) {
final replacement = replacedBuiltInMetadataProviderFor(provider);
final resolved = replacement ?? provider;
if (!result.contains(resolved)) {
result.add(resolved);
}
}
return result;
}
List<String> _sanitizeMetadataProviderPriority(List<String> input) {
final allowed = getAllMetadataProviders().toSet();
final preferredOrder = getAllMetadataProviders();
-16
View File
@@ -524,22 +524,6 @@ class PlatformBridge {
return jsonDecode(result as String) as Map<String, dynamic>;
}
static Future<Map<String, dynamic>> getQobuzMetadata(
String resourceType,
String resourceId,
) async {
final result = await _channel.invokeMethod('getQobuzMetadata', {
'resource_type': resourceType,
'resource_id': resourceId,
});
if (result == null) {
throw Exception(
'getQobuzMetadata returned null for $resourceType:$resourceId',
);
}
return jsonDecode(result as String) as Map<String, dynamic>;
}
static Future<Map<String, dynamic>> parseProviderUrl(String url) async {
final result = await _channel.invokeMethod('parseProviderUrl', {
'url': url,