diff --git a/api/funkwhale_api/music/views.py b/api/funkwhale_api/music/views.py index e99bd496c..fdb93e246 100644 --- a/api/funkwhale_api/music/views.py +++ b/api/funkwhale_api/music/views.py @@ -4,7 +4,6 @@ import urllib from django.conf import settings from django.db import transaction from django.db.models import Count, Prefetch, Sum, F, Q -from django.db.models.functions import Length from django.utils import timezone from rest_framework import mixins @@ -24,6 +23,7 @@ from funkwhale_api.federation import api_serializers as federation_api_serialize from funkwhale_api.federation import decorators as federation_decorators from funkwhale_api.federation import routes from funkwhale_api.tags.models import Tag, TaggedItem +from funkwhale_api.tags.serializers import TagSerializer from funkwhale_api.users.oauth import permissions as oauth_permissions from . import filters, licenses, models, serializers, tasks, utils @@ -476,6 +476,7 @@ class Search(views.APIView): "albums": serializers.AlbumSerializer( self.get_albums(query), many=True ).data, + "tags": TagSerializer(self.get_tags(query), many=True).data, } return Response(results, status=200) @@ -514,15 +515,8 @@ class Search(views.APIView): def get_tags(self, query): search_fields = ["name__unaccent"] query_obj = utils.get_query(query, search_fields) - - # We want the shortest tag first - qs = ( - Tag.objects.all() - .annotate(name_length=Length("name")) - .order_by("name_length") - ) - - return qs.filter(query_obj)[: self.max_results] + qs = Tag.objects.all().filter(query_obj) + return common_utils.order_for_search(qs, "name")[: self.max_results] class LicenseViewSet(viewsets.ReadOnlyModelViewSet): diff --git a/front/src/components/audio/SearchBar.vue b/front/src/components/audio/SearchBar.vue index e0c343fed..d7445d13b 100644 --- a/front/src/components/audio/SearchBar.vue +++ b/front/src/components/audio/SearchBar.vue @@ -32,6 +32,7 @@ export default { let artistLabel = this.$pgettext('*/*/*/Noun', 'Artist') let albumLabel = this.$pgettext('*/*/*', 'Album') let trackLabel = this.$pgettext('*/*/*/Noun', 'Track') + let tagLabel = this.$pgettext('*/*/*/Noun', 'Tag') let self = this var searchQuery; @@ -75,6 +76,9 @@ export default { }, getDescription (r) { return '' + }, + getId (t) { + return t.id } }, { @@ -86,6 +90,9 @@ export default { }, getDescription (r) { return '' + }, + getId (t) { + return t.id } }, { @@ -97,6 +104,23 @@ export default { }, getDescription (r) { return '' + }, + getId (t) { + return t.id + } + }, + { + code: 'tags', + route: 'library.tags.detail', + name: tagLabel, + getTitle (r) { + return r.name + }, + getDescription (r) { + return '' + }, + getId (t) { + return t.name } } ] @@ -106,13 +130,14 @@ export default { results: [] } initialResponse[category.code].forEach(result => { + let id = category.getId(result) results[category.code].results.push({ title: category.getTitle(result), - id: result.id, + id, routerUrl: { name: category.route, params: { - id: result.id + id } }, description: category.getDescription(result)