fix(metadata): support extension custom search

This commit is contained in:
zarzet
2026-07-30 15:36:31 +07:00
parent d85c8f6a17
commit 3e41aa0eee
6 changed files with 102 additions and 54 deletions
+31
View File
@@ -361,6 +361,20 @@ class SearchFilter {
}
}
String canonicalExtensionSearchFilterId(String value) {
final normalized = value.trim().toLowerCase().replaceAll(
RegExp(r'[^a-z0-9]+'),
'',
);
return switch (normalized) {
'track' || 'tracks' || 'song' || 'songs' || 'music' => 'track',
'artist' || 'artists' => 'artist',
'album' || 'albums' => 'album',
'playlist' || 'playlists' => 'playlist',
_ => normalized,
};
}
class SearchBehavior {
final bool enabled;
final String? placeholder;
@@ -399,6 +413,23 @@ class SearchBehavior {
);
}
String? filterIdForKind(String kind) {
final canonicalKind = canonicalExtensionSearchFilterId(kind);
for (final filter in filters) {
if (canonicalExtensionSearchFilterId(filter.id) == canonicalKind ||
(filter.label != null &&
canonicalExtensionSearchFilterId(filter.label!) ==
canonicalKind) ||
(filter.icon != null &&
canonicalExtensionSearchFilterId(filter.icon!) ==
canonicalKind)) {
final id = filter.id.trim();
if (id.isNotEmpty) return id;
}
}
return null;
}
(double, double) getThumbnailSize({double defaultSize = 56}) {
if (thumbnailWidth != null && thumbnailHeight != null) {
return (thumbnailWidth!.toDouble(), thumbnailHeight!.toDouble());
+3 -24
View File
@@ -183,32 +183,11 @@ class HomeSearchProviderPolicy {
return null;
}
return filters
.where(
(candidate) =>
canonicalFilterId(candidate.id) == canonicalFilter ||
(candidate.label != null &&
canonicalFilterId(candidate.label!) == canonicalFilter) ||
(candidate.icon != null &&
canonicalFilterId(candidate.icon!) == canonicalFilter),
)
.firstOrNull
?.id;
return extension?.searchBehavior?.filterIdForKind(canonicalFilter);
}
static String canonicalFilterId(String value) {
final normalized = value.trim().toLowerCase().replaceAll(
RegExp(r'[^a-z0-9]+'),
'',
);
return switch (normalized) {
'track' || 'tracks' || 'song' || 'songs' || 'music' => 'track',
'artist' || 'artists' => 'artist',
'album' || 'albums' => 'album',
'playlist' || 'playlists' => 'playlist',
_ => normalized,
};
}
static String canonicalFilterId(String value) =>
canonicalExtensionSearchFilterId(value);
static String? preferredFilter(
String preferredSearchTab,
+38 -21
View File
@@ -870,16 +870,17 @@ class _EditMetadataSheetState extends State<_EditMetadataSheet> {
context,
listen: false,
).read(extensionProvider);
final selectedProviderId =
configuredProviderId != null &&
extensionState.extensions.any(
(extension) =>
extension.id == configuredProviderId &&
extension.enabled &&
extension.hasMetadataProvider,
)
? configuredProviderId
: null;
final selectedProvider = configuredProviderId == null
? null
: extensionState.extensions
.where(
(extension) =>
extension.id == configuredProviderId &&
extension.enabled &&
extension.hasMetadataProvider,
)
.firstOrNull;
final selectedProviderId = selectedProvider?.id;
final usesAutomaticProvider =
selectedProviderId == null || selectedProviderId.isEmpty;
final shouldFetchLyrics = _autoFillFields.contains('lyrics');
@@ -920,16 +921,31 @@ class _EditMetadataSheetState extends State<_EditMetadataSheet> {
if (needsTrackLookup && best == null) {
final query = queryParts.join(' ');
final results = usesAutomaticProvider
? await PlatformBridge.searchTracksWithMetadataProviders(
query,
limit: 5,
)
: await PlatformBridge.searchTracksWithMetadataProvider(
selectedProviderId,
query,
limit: 5,
);
final List<Map<String, dynamic>> results;
if (usesAutomaticProvider) {
results = await PlatformBridge.searchTracksWithMetadataProviders(
query,
limit: 5,
);
} else if (selectedProvider!.hasCustomSearch) {
final trackFilter = selectedProvider.searchBehavior?.filterIdForKind(
'track',
);
results = await PlatformBridge.customSearchWithExtension(
selectedProvider.id,
query,
options: {
'limit': 5,
if (trackFilter != null) 'filter': trackFilter,
},
);
} else {
results = await PlatformBridge.searchTracksWithMetadataProvider(
selectedProvider!.id,
query,
limit: 5,
);
}
if (!mounted) return;
@@ -1186,7 +1202,8 @@ class _EditMetadataSheetState extends State<_EditMetadataSheet> {
coverUrl: coverUrl?.isNotEmpty == true ? coverUrl : null,
);
});
} catch (e) {
} catch (e, stackTrace) {
_log.e('Metadata auto-fill failed: $e', e, stackTrace);
if (mounted) {
_showSheetSnackBar(
context.l10n.snackbarError(context.friendlyError(e)),